diff --git a/.cargo-husky/hooks/pre-commit b/.cargo-husky/hooks/pre-commit new file mode 100755 index 0000000..07815e6 --- /dev/null +++ b/.cargo-husky/hooks/pre-commit @@ -0,0 +1,7 @@ +#!/bin/sh -xe + +cargo clippy --features=community -- -D warnings +cargo clippy --features=enterprise -- -D warnings + +# Check fmt (protip: run 'cargo fmt --all -- --emit files' to apply format locally) +cargo fmt --all -- --check diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..37ff423 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,21 @@ +name: Build + +on: + push + +env: + CARGO_TERM_COLOR: always + LIBCLANG_PATH: /usr/lib/llvm-14/lib/ + +jobs: + build: + runs-on: ubuntu-22.04 + strategy: + matrix: + version: [community, enterprise] + steps: + - name: Install apt-get + run: sudo apt-get install -y clang llvm + - uses: actions/checkout@v3 + - name: Build + run: cargo build --features=${{ matrix.version }} --verbose diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index dfa2aec..1813c3f 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -1,6 +1,7 @@ -on: push name: Clippy check +on: push + env: CARGO_TERM_COLOR: always LIBCLANG_PATH: /usr/lib/llvm-14/lib/ @@ -8,10 +9,14 @@ env: jobs: clippy_check: runs-on: ubuntu-latest + strategy: + matrix: + version: [community, enterprise] steps: - uses: actions/checkout@v1 - run: rustup component add clippy - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Clippy default + name: Clippy + args: --features=${{ matrix.version }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 82c42e0..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Rust - - -on: - push: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - -env: - CARGO_TERM_COLOR: always - LIBCLANG_PATH: /usr/lib/llvm-14/lib/ - -jobs: - build: - runs-on: ubuntu-22.04 - steps: - - name: Install apt-get - run: sudo apt-get install -y clang llvm - - name: List libs - run: ls -l /usr/lib - - name: Install latest nightly - uses: dtolnay/rust-toolchain@v1 - with: - toolchain: nightly - components: rustfmt, clippy - - uses: actions/checkout@v3 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose - - name: Run tests (with address sanitizer) - run: LSAN_OPTIONS=suppressions=san.supp RUSTFLAGS="-Zsanitizer=address" cargo +nightly test --verbose diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..1d952d6 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test + +on: + push + +env: + CARGO_TERM_COLOR: always + LIBCLANG_PATH: /usr/lib/llvm-14/lib/ + +jobs: + test: + runs-on: ubuntu-22.04 + strategy: + matrix: + version: [community, enterprise] + steps: + - name: Install apt-get + run: sudo apt-get install -y clang llvm + - name: Install latest nightly + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: nightly + components: rustfmt, clippy + - uses: actions/checkout@v3 + - name: Run tests + run: cargo test --features=${{ matrix.version }} --verbose + - name: Run tests (with address sanitizer) + run: LSAN_OPTIONS=suppressions=san.supp RUSTFLAGS="-Zsanitizer=address" cargo +nightly test --features=${{ matrix.version }} --verbose diff --git a/Cargo.toml b/Cargo.toml index 4652557..ffcd1cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "couchbase_lite" -version = "3.2.1-0" # The first three numbers correspond to the Couchbase Lite C release, the fourth number corresponds to the Doctolib release +version = "3.2.1-0" edition = "2021" [dependencies] @@ -13,7 +13,7 @@ regex = "1.10.4" [dev-dependencies.cargo-husky] version = "1" default-features = false # Disable features which are enabled by default -features = ["precommit-hook", "run-cargo-clippy", "run-cargo-fmt"] +features = ["user-hooks"] [build-dependencies] bindgen = "0.69.4" @@ -32,5 +32,7 @@ incremental = false # See: https://github.com/johnthagen/min-sized-rust [features] -flaky-test = [] +community = [] +enterprise = [] + unsafe-threads-test = [] diff --git a/Dockerfile b/Dockerfile index 10eddae..0eaa434 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,15 @@ -FROM --platform=amd64 rust AS build -RUN apt-get update -RUN apt-get -y install clang -RUN mkdir /build -WORKDIR /build -ENV LIBCLANG_PATH=/usr/lib/llvm-11/lib/ -ADD Cargo.toml Cargo.toml -ADD build.rs build.rs -ADD libcblite libcblite -ADD src src -RUN cargo c -RUN cargo test -- --test-threads=1 - FROM --platform=amd64 rust AS strip-stage +ARG DIRNAME RUN apt-get update RUN apt-get -y install binutils binutils-aarch64-linux-gnu RUN mkdir /build WORKDIR /build -ADD libcblite libcblite -RUN strip /build/libcblite/lib/x86_64-linux-android/libcblite.so -o /build/libcblite/lib/x86_64-linux-android/libcblite.stripped.so -RUN strip /build/libcblite/lib/i686-linux-android/libcblite.so -o /build/libcblite/lib/i686-linux-android/libcblite.stripped.so -RUN /usr/aarch64-linux-gnu/bin/strip /build/libcblite/lib/aarch64-linux-android/libcblite.so -o /build/libcblite/lib/aarch64-linux-android/libcblite.stripped.so -RUN /usr/aarch64-linux-gnu/bin/strip /build/libcblite/lib/arm-linux-androideabi/libcblite.so -o /build/libcblite/lib/arm-linux-androideabi/libcblite.stripped.so -RUN strip /build/libcblite/lib/x86_64-pc-windows-gnu/cblite.dll -o /build/libcblite/lib/x86_64-pc-windows-gnu/cblite.stripped.dll +ADD ${DIRNAME} ${DIRNAME} +RUN strip /build/${DIRNAME}/lib/x86_64-linux-android/libcblite.so -o /build/${DIRNAME}/lib/x86_64-linux-android/libcblite.stripped.so +RUN strip /build/${DIRNAME}/lib/i686-linux-android/libcblite.so -o /build/${DIRNAME}/lib/i686-linux-android/libcblite.stripped.so +RUN /usr/aarch64-linux-gnu/bin/strip /build/${DIRNAME}/lib/aarch64-linux-android/libcblite.so -o /build/${DIRNAME}/lib/aarch64-linux-android/libcblite.stripped.so +RUN /usr/aarch64-linux-gnu/bin/strip /build/${DIRNAME}/lib/arm-linux-androideabi/libcblite.so -o /build/${DIRNAME}/lib/arm-linux-androideabi/libcblite.stripped.so +RUN strip /build/${DIRNAME}/lib/x86_64-pc-windows-gnu/cblite.dll -o /build/${DIRNAME}/lib/x86_64-pc-windows-gnu/cblite.stripped.dll -FROM scratch AS strip -COPY --from=strip-stage /build/libcblite/ . -COPY --from=strip-stage /build/libcblite/ . +FROM scratch AS strip +COPY --from=strip-stage /build/${DIRNAME}/ . diff --git a/README.md b/README.md index ace9f69..c54013b 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,14 @@ Installation instructions are [here][BINDGEN_INSTALL]. ### 2. Build! +You can use Couchbase Lite C community or entreprise editions: + +```shell +$ cargo build --features=enterprise +``` + ```shell -$ cargo build +$ cargo build --features=community ``` ## Maintaining @@ -68,12 +74,6 @@ $ LEAK_CHECK=y cargo test -- --test-threads 1 $ LSAN_OPTIONS=suppressions=san.supp RUSTFLAGS="-Zsanitizer=address" cargo +nightly test ``` -**To diag flaky test** - -```shell -$ LSAN_OPTIONS=suppressions=san.supp RUSTFLAGS="-Zsanitizer=address" cargo +nightly test --verbose --features=flaky-test flaky -``` - ## Learning [Official Couchbase Lite documentation][CBL_DOCS] diff --git a/build.rs b/build.rs index 8589d48..bb9f050 100644 --- a/build.rs +++ b/build.rs @@ -22,6 +22,11 @@ // - https://rust-lang.github.io/rust-bindgen/tutorial-3.html // - https://doc.rust-lang.org/cargo/reference/build-scripts.html +#[cfg(all(not(feature = "community"), not(feature = "enterprise")))] +compile_error!("You need to have one the following features activated: community, enterprise"); +#[cfg(all(feature = "community", feature = "enterprise"))] +compile_error!("You need to have one the following features activated: community, enterprise"); + extern crate bindgen; extern crate fs_extra; @@ -32,8 +37,15 @@ use std::path::PathBuf; use std::process::Command; use fs_extra::dir; -static CBL_INCLUDE_DIR: &str = "libcblite/include"; -static CBL_LIB_DIR: &str = "libcblite/lib"; +#[cfg(feature = "community")] +static CBL_INCLUDE_DIR: &str = "libcblite_community/include"; +#[cfg(feature = "enterprise")] +static CBL_INCLUDE_DIR: &str = "libcblite_enterprise/include"; + +#[cfg(feature = "community")] +static CBL_LIB_DIR: &str = "libcblite_community/lib"; +#[cfg(feature = "enterprise")] +static CBL_LIB_DIR: &str = "libcblite_enterprise/lib"; fn main() -> Result<(), Box> { generate_bindings()?; diff --git a/c_playground/CMakeLists.txt b/c_playground/CMakeLists.txt index 1c6f9b9..f8e2f30 100644 --- a/c_playground/CMakeLists.txt +++ b/c_playground/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.15) project(c_playground) -include_directories(${CMAKE_SOURCE_DIR}/../libcblite/include) +include_directories(${CMAKE_SOURCE_DIR}/../libcblite_enterprise/include) add_executable(Main main.c) -target_link_libraries(Main PUBLIC ${CMAKE_SOURCE_DIR}/../libcblite/lib/macos/libcblite.3.dylib) +target_link_libraries(Main PUBLIC ${CMAKE_SOURCE_DIR}/../libcblite_enterprise/lib/macos/libcblite.3.dylib) diff --git a/libcblite_community/LICENSE.txt b/libcblite_community/LICENSE.txt new file mode 100644 index 0000000..3d3ecce --- /dev/null +++ b/libcblite_community/LICENSE.txt @@ -0,0 +1,199 @@ +Community Edition License Agreement + +This Couchbase Community Edition License Agreement between you and +Couchbase, Inc. governs your use of the community edition of Couchbase's +software accompanying this agreement, including but not limited to +Couchbase Server Community Edition, Couchbase Sync Gateway Community +Edition and Couchbase Lite Community Edition, and any Couchbase services +or updates for such software, in addition to all versions of Couchbase's +community software described in Section 1 below (together, the "Community +Software"). The software license provided through this agreement excludes +the cross datacenter replication ("XDCR") feature and any other excluded +features as described in Couchbase documentation. + +BY INSTALLING OR OTHERWISE USING THE COMMUNITY SOFTWARE, YOU AGREE TO +THE TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO ANY TERMS OF THIS +AGREEMENT, YOU MUST IMMEDIATELY CEASE USING THE COMMUNITY SOFTWARE AND +UNINSTALL AND DELETE ALL COPIES OF THE COMMUNITY SOFTWARE. + +If you are installing or using the Community Software on behalf of an +organization or are otherwise entering into this agreement on behalf of an +organization, you represent and warrant that you are authorized to enter +into this agreement on behalf of your organization. In consideration +of the rights granted to you in this agreement, you must comply with +all the terms in this agreement. + +1. Application of Agreement. +If you have installed or used any prior version of the community edition +of our software under any other license terms, by installing or using +the version of the Community Software that accompanies this agreement, +you agree that this agreement replaces those other license terms in +their entirety and will also govern your use of all prior versions of +the Community Software. + +2. Term and Termination. +This agreement will continue to apply until (a) you terminate this +agreement at any time by uninstalling and deleting all copies of the +Community Software in your possession or control; or (b) we terminate +this agreement. We may terminate this agreement at any time for any +reason (including but not limited to your breach of this agreement) +in our sole discretion by providing you with notice. If we notify +you of our termination, you must uninstall and delete all copies of +the Community Software in your possession or control. Upon request, +you shall provide written certification that you have uninstalled, +deleted and ceased all usage of the Community Software within five (5) +business days of our request. If you represent an organization, then +such certification must be signed by an authorized representative of +your organization on behalf of your organization. + +3. Modification of Agreement. +We may modify this agreement or replace this agreement with new terms +from time to time with any update or new version of the Community Software +or with notice to you. + +4. License Grant. +The Community Software is licensed, not sold, to you. During the term +of this agreement and subject to your compliance with this agreement, +we grant you a non-exclusive, non-transferable, non-assignable, +non-sublicensable, revocable and personal license to install and use the +Community Software at no charge for your internal business purposes and +to develop or commercialize products that interact with the Community +Software, subject to the restrictions in Section 5 and provided that +you ensure that users of your products also comply with the applicable +restrictions in Section 5. + +5. License Restrictions. +This agreement does not grant any rights to our source code or to any +commercial or enterprise (i.e. non-community) edition of our software or +services, which are subject to separate terms. In addition to the other +restrictions and limitations in this agreement, you must not, and you must +not assist or authorize others to: (a) work around or bypass any technical +limitations, protections, or security measures used for or contained in +the Community Software; (b) decompile, reverse engineer, disassemble, +attempt to derive the source code of, modify, or create derivative works +of the Community Software (except the extent prohibited by applicable +law or to the extent permitted by the licensing terms governing use of +any open source components included with the Community Software); (c) +use the Community Software in any manner that violates applicable law, +including but not limited to transferring the Community Software to any +country or recipient in violation of any sanctions or export control +laws or regulations, or that infringes, misappropriates or otherwise +violates any right of any third party; (d) commercialize (other than as +permitted by Section 4 above) or otherwise distribute, offer, provide, +share, sell, transfer, license or sublicense the Community Software; (e) +make any representations or warranties regarding the Community Software; +(f) use or deploy Couchbase Server Community in clusters comprised of +more than five (5) node instances of Couchbase Server Community running +on a server, including a physical server, server blade, virtual machine, +software container, or cloud server; or (g) use or deploy the Community +Software to support an application or workload also supported by any +commercial or enterprise Couchbase offering (including without limitation +Couchbase Enterprise Edition software or Couchbase Capella). Furthermore, +this agreement does not grant you any rights to the XDCR functionality +provided by Couchbase. + +6. Verification of Use. +We may verify that you are using the Community Software in compliance +with this agreement, including without limitation through technological +features in the Community Software that may transmit to us data relating +to your use of the Community Software. Upon our request, you will +provide us promptly and in any event within five (5) business days with +system-generated information verifying that your use of the Community +Software complies with this agreement. If you are found to be using the +Community Software in breach of this agreement, then without limiting +any other rights or remedies we may have, you must immediately pay us +a license fee for such usage of the Community Software that is equal +to the amount you would have paid if you had licensed the commercial +or enterprise version Couchbase's software. If you do not comply with +this agreement and we do not take immediate action, we reserve and do +not waive the right to take action in the future. + +7. Privacy and Data Security. +Our use of any personal data collected by us under this +agreement is governed by our privacy policy, currently located at: +https://www.couchbase.com/privacy-policy/. Your use of the Community +Software operates as a consent to the practices described in our privacy +policy. + +8. No Support Services. +Because this is the free community edition of our software, all Community +Software is provided "as is" without any services or support. We are +under no obligation to provide or continue to provide the Community +Software (including any update, upgrade or new version) to you. + +9. Disclaimer of Warranties. +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW: (A) USE OF ANY +COMMUNITY SOFTWARE IS AT YOUR SOLE RISK, INCLUDING THE ENTIRE RISK +AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND EFFORT; (B) THE +COMMUNITY SOFTWARE IS LICENSED TO YOU ON AN "AS IS" AND "AS AVAILABLE" +BASIS, WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, AND WE DISCLAIM +ALL WARRANTIES, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT +LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, +FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, QUIET ENJOYMENT, AVAILABILITY +AND NON-INFRINGEMENT; AND (C) WITHOUT LIMITING THE FOREGOING, WE DO NOT +WARRANT THAT THE COMMUNITY SOFTWARE WILL MEET YOUR REQUIREMENTS, THAT ITS +OPERATION WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS WILL BE +CORRECTED. NO INFORMATION OR ADVICE GIVEN BY US WILL CREATE ANY WARRANTY. + +10. LIMITATION OF LIABILITY. +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW: (A) IN NO EVENT WILL WE +BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES +WHATSOEVER, OR DAMAGES FOR LOSS OF PROFITS, LOSS OR CORRUPTION OF DATA, +LOSS OF GOODWILL, BUSINESS INTERRUPTION OR ANY OTHER DAMAGES OR LOSSES, +ARISING OUT OF OR RELATED TO YOUR USE OF OR INABILITY TO USE THE COMMUNITY +SOFTWARE; AND (B) IN NO EVENT WILL OUR TOTAL LIABILITY TO YOU FOR ALL +LOSS, CLAIMS AND DAMAGES EXCEED THE AMOUNT OF FIFTY DOLLARS (USD 50.00). +ALL LIMITATIONS AND EXCLUSIONS OF LIABILITY IN THIS AGREEMENT WILL APPLY +EVEN IF THE ABOVE STATED REMEDIES FAIL OF THEIR ESSENTIAL PURPOSE AND +REGARDLESS OF THE FORM OR SOURCE OF CLAIM OR LOSS, WHETHER THE CLAIM OR +LOSS WAS FORESEEABLE, AND WHETHER WE HAVE BEEN ADVISED OF THE POSSIBILITY +OF THE CLAIM OR LOSS. + +11. Non-Assignment. +You may not assign or otherwise transfer your rights and obligations under +this agreement, in whole or in part, without our written consent, and +any such attempt will be void. We may transfer our rights or obligations +under this agreement to a third party at our sole discretion. + +12. Dispute Resolution. +If you have any concern or dispute, you must first try to resolve the +dispute informally by contacting us. If your dispute is not resolved +within thirty (30) days of submission, any resulting legal actions +must be resolved through final and binding arbitration. If you reside +in the Americas, JAMS will administer the arbitration in Santa Clara +County, California pursuant to its Comprehensive Arbitration Rules +and Procedures. If you reside in Australia, New Zealand, Japan, the +People's Republic of China, Hong Kong S.A.R., Macau S.A.R., Taiwan, +South Korea, India, Sri Lanka, Bangladesh, Nepal, or a member state +of the Association of Southeast Asian Nations, then the Singapore +International Arbitration Centre will administer the arbitration in +Singapore under its Rules of Arbitration, which rules are deemed to be +incorporated by reference in this section. Otherwise, the London Court +of International Arbitration (LCIA) will administer the arbitration in +London under the LCIA Arbitration Rules. You agree to appear in the +identified and applicable forum stated in this paragraph, and to be +bound by the results of the arbitration. There will be one arbitrator +that you and we mutually select. The arbitration will be conducted in +the English language. Judgment upon the award rendered may be entered +and will be enforceable in any court of competent jurisdiction having +jurisdiction over you and us. + +13. No Class Actions; Injunctive Relief; Governing Law; Severability. +You may only resolve disputes with us on an individual basis, and you +may not bring a claim as a plaintiff or a class member in a class, +consolidated, or representative action. Notwithstanding anything else +in this agreement, if you use the Community Software in violation of +this agreement, we are entitled to apply for injunctive remedies (or +an equivalent type of urgent legal relief) in any jurisdiction. This +agreement will be governed by and construed in accordance with the +substantive laws of the State of California. By using the Community +Software you represent that you will comply with, and acknowledge that +the software and any related technology or documentation is subject +to, U.S. sanctions and export control laws and regulations. If any +part of this agreement is held invalid, the remainder of the agreement +will continue in full force and effect. If you have other rights not +described in this agreement, including consumer rights, under the laws +of your state or country, this agreement does not change those other +rights if the laws of your state or country do not permit it to do so. + +Community Edition License Agreement (May 2024) diff --git a/libcblite_community/include/cbl++/Base.hh b/libcblite_community/include/cbl++/Base.hh new file mode 100644 index 0000000..d425f5d --- /dev/null +++ b/libcblite_community/include/cbl++/Base.hh @@ -0,0 +1,173 @@ +// +// Base.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl/CBLBase.h" +#include "fleece/slice.hh" +#include +#include +#include +#include +#include + +#if DEBUG +# include "cbl/CBLLog.h" +#endif + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +static inline bool operator== (const CBLError &e1, const CBLError &e2) { + if (e1.code != 0) + return e1.domain == e2.domain && e1.code == e2.code; + else + return e2.code == 0; +} + +namespace cbl { + + using slice = fleece::slice; + using alloc_slice = fleece::alloc_slice; + + // Artificial base class of the C++ wrapper classes; just manages ref-counting. + class RefCounted { + protected: + RefCounted() noexcept :_ref(nullptr) { } + explicit RefCounted(CBLRefCounted* _cbl_nullable ref) noexcept :_ref(CBL_Retain(ref)) { } + RefCounted(const RefCounted &other) noexcept :_ref(CBL_Retain(other._ref)) { } + RefCounted(RefCounted &&other) noexcept :_ref(other._ref) {other._ref = nullptr;} + ~RefCounted() noexcept {CBL_Release(_ref);} + + RefCounted& operator= (const RefCounted &other) noexcept { + CBL_Retain(other._ref); + CBL_Release(_ref); + _ref = other._ref; + return *this; + } + + RefCounted& operator= (RefCounted &&other) noexcept { + if (other._ref != _ref) { + CBL_Release(_ref); + _ref = other._ref; + other._ref = nullptr; + } + return *this; + } + + void clear() {CBL_Release(_ref); _ref = nullptr;} + bool valid() const {return _ref != nullptr;} \ + explicit operator bool() const {return valid();} \ + + static std::string asString(FLSlice s) {return slice(s).asString();} + static std::string asString(FLSliceResult &&s) {return alloc_slice(s).asString();} + + static void check(bool ok, CBLError &error) { + if (!ok) { +#if DEBUG + alloc_slice message = CBLError_Message(&error); + CBL_Log(kCBLLogDomainDatabase, kCBLLogError, "API returning error %d/%d: %.*s", + error.domain, error.code, (int)message.size, (char*)message.buf); +#endif + throw error; + } + } + + CBLRefCounted* _cbl_nullable _ref; + + friend class Extension; + friend class Transaction; + }; + +// Internal use only: Copy/move ctors and assignment ops that have to be declared in subclasses +#define CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +public: \ + CLASS() noexcept :SUPER() { } \ + CLASS& operator=(std::nullptr_t) {clear(); return *this;} \ + bool valid() const {return RefCounted::valid();} \ + explicit operator bool() const {return valid();} \ + bool operator==(const CLASS &other) const {return _ref == other._ref;} \ + bool operator!=(const CLASS &other) const {return _ref != other._ref;} \ + C_TYPE* _cbl_nullable ref() const {return (C_TYPE*)_ref;}\ +protected: \ + explicit CLASS(C_TYPE* _cbl_nullable ref) :SUPER((CBLRefCounted*)ref) { } + +#define CBL_REFCOUNTED_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +public: \ + CLASS(const CLASS &other) noexcept :SUPER(other) { } \ + CLASS(CLASS &&other) noexcept :SUPER((SUPER&&)other) { } \ + CLASS& operator=(const CLASS &other) noexcept {SUPER::operator=(other); return *this;} \ + CLASS& operator=(CLASS &&other) noexcept {SUPER::operator=((SUPER&&)other); return *this;} + + /** A token representing a registered listener; instances are returned from the various + methods that register listeners, such as \ref Database::addListener. + When this object goes out of scope, the listener will be unregistered. + @note ListenerToken is now allowed to copy. */ + template + class ListenerToken { + public: + using Callback = std::function; + + ListenerToken() =default; + ~ListenerToken() {CBLListener_Remove(_token);} + + ListenerToken(Callback cb) + :_callback(new Callback(cb)) + { } + + ListenerToken(ListenerToken &&other) + :_token(other._token), + _callback(std::move(other._callback)) + {other._token = nullptr;} + + ListenerToken& operator=(ListenerToken &&other) { + CBLListener_Remove(_token); + _token = other._token; + other._token = nullptr; + _callback = std::move(other._callback); + return *this; + } + + /** Unregisters the listener early, before it leaves scope. */ + void remove() { + CBLListener_Remove(_token); + _token = nullptr; + _callback = nullptr; + } + + void* _cbl_nullable context() const {return _callback.get();} + CBLListenerToken* _cbl_nullable token() const {return _token;} + void setToken(CBLListenerToken* token) {assert(!_token); _token = token;} + + static void call(void* _cbl_nullable context, Args... args) { + auto listener = (Callback*)context; + (*listener)(args...); + } + + private: + CBLListenerToken* _cbl_nullable _token {nullptr}; + std::shared_ptr _callback; // Use shared_ptr instead of unique_ptr to allow to move + + ListenerToken(const ListenerToken&) =delete; + ListenerToken& operator=(const ListenerToken &other) =delete; + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/Blob.hh b/libcblite_community/include/cbl++/Blob.hh new file mode 100644 index 0000000..31e94bd --- /dev/null +++ b/libcblite_community/include/cbl++/Blob.hh @@ -0,0 +1,173 @@ +// +// Blob.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Document.hh" +#include "cbl/CBLBlob.h" +#include "fleece/Mutable.hh" +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class BlobReadStream; + class BlobWriteStream; + + /** A reference to a binary data blob associated with a document. + A blob's persistent form is a special dictionary in the document properties. + To work with a blob, you construct a Blob object with that dictionary. */ + class Blob : protected RefCounted { + public: + /** Returns true if a dictionary in a document is a blob reference. + @note This method tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + static bool isBlob(fleece::Dict d) {return FLDict_IsBlob(d);} + + /** Creates a new blob, given its contents as a single block of data. + @note The memory pointed to by `contents` is no longer needed after this call completes + (it will have been written to the database.) + @param contentType The MIME type (optional). + @param contents The data's address and length. */ + Blob(slice contentType, slice contents) { + _ref = (CBLRefCounted*) CBLBlob_CreateWithData(contentType, contents); + } + + /** Creates a new blob from the data written to a \ref CBLBlobWriteStream. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. */ + inline Blob(slice contentType, BlobWriteStream& writer); + + /** Creates a Blob instance on an existing blob reference in a document or query result. + @note If the dict argument is not actually a blob reference, this Blob object will be + invalid; you can check that by calling its `valid` method or testing it with its + `operator bool`. */ + Blob(fleece::Dict d) + :RefCounted((CBLRefCounted*) FLDict_GetBlob(d)) + { } + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t length() const {return CBLBlob_Length(ref());} + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + std::string contentType() const {return asString(CBLBlob_ContentType(ref()));} + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + std::string digest() const {return asString(CBLBlob_Digest(ref()));} + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + fleece::Dict properties() const {return CBLBlob_Properties(ref());} + + // Allows Blob to be assigned to mutable Dict/Array item, e.g. `dict["foo"] = blob` + operator fleece::Dict() const {return properties();} + + /** Reads the blob's content into memory and returns them. */ + alloc_slice loadContent() { + CBLError error; + fleece::alloc_slice content = CBLBlob_Content(ref(), &error); + check(content.buf, error); + return content; + } + + /** Opens a stream for reading a blob's content. */ + inline BlobReadStream* openContentStream(); + + protected: + Blob(CBLRefCounted* r) :RefCounted(r) { } + + CBL_REFCOUNTED_BOILERPLATE(Blob, RefCounted, CBLBlob) + }; + + /** A stream for writing a new blob to the database. */ + class BlobReadStream { + public: + /** Opens a stream for reading a blob's content. */ + BlobReadStream(Blob *blob) { + CBLError error; + _stream = CBLBlob_OpenContentStream(blob->ref(), &error); + if (!_stream) throw error; + } + + ~BlobReadStream() { + CBLBlobReader_Close(_stream); + } + + /** Reads data from a blob. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @return The actual number of bytes read; 0 if at EOF. */ + size_t read(void *dst, size_t maxLength) { + CBLError error; + int bytesRead = CBLBlobReader_Read(_stream, dst, maxLength, &error); + if (bytesRead < 0) + throw error; + return size_t(bytesRead); + } + + private: + CBLBlobReadStream* _cbl_nullable _stream {nullptr}; + }; + + BlobReadStream* Blob::openContentStream() { + return new BlobReadStream(this); + } + + /** A stream for writing a new blob to the database. */ + class BlobWriteStream { + public: + /** Create a stream to write a new blob to the database. */ + BlobWriteStream(Database db) { + CBLError error; + _writer = CBLBlobWriter_Create(db.ref(), &error); + if (!_writer) throw error; + } + + ~BlobWriteStream() { + CBLBlobWriter_Close(_writer); + } + + /** Writes data to a new blob. + @param data The data to write. */ + void write(fleece::slice data) { + write(data.buf, data.size); + } + + /** Writes data to a new blob. + @param src The address of the data to write. + @param length The length of the data to write. */ + void write(const void *src, size_t length) { + CBLError error; + if (!CBLBlobWriter_Write(_writer, src, length, &error)) + throw error; + } + + private: + friend class Blob; + CBLBlobWriteStream* _cbl_nullable _writer {nullptr}; + }; + + inline Blob::Blob(slice contentType, BlobWriteStream& writer) { + _ref = (CBLRefCounted*) CBLBlob_CreateWithStream(contentType, writer._writer); + writer._writer = nullptr; + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/Collection.hh b/libcblite_community/include/cbl++/Collection.hh new file mode 100644 index 0000000..b199bbb --- /dev/null +++ b/libcblite_community/include/cbl++/Collection.hh @@ -0,0 +1,379 @@ +// +// Collection.hh +// +// Copyright (c) 2022 Couchbase, Inc 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 "cbl++/Base.hh" +#include "cbl++/Database.hh" +#include "cbl/CBLCollection.h" +#include "cbl/CBLScope.h" +#include "fleece/Mutable.hh" +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Document; + class MutableDocument; + class CollectionChange; + class DocumentChange; + class QueryIndex; + class VectorIndexConfiguration; + + /** Conflict handler used when saving a document. */ + using CollectionConflictHandler = std::function; + + /** + A Collection class represent a collection which is a container for documents. + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + You may decide to delete the default collection, but noted that the default collection cannot + be re-created. The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. */ + class Collection : private RefCounted { + public: + // Accessors: + + /** The collection's name. */ + std::string name() const {return asString(CBLCollection_Name(ref()));} + + /** The collection's fully qualified name in the '.' format. */ + std::string fullName() const {return asString(CBLCollection_FullName(ref()));} + + /** The scope's name. */ + std::string scopeName() const { + auto scope = CBLCollection_Scope(ref()); + auto scopeName = asString(CBLScope_Name(scope)); + CBLScope_Release(scope); + return scopeName; + } + + /** The collection's database. */ + Database database() const {return Database(CBLCollection_Database(ref()));} + + /** The number of documents in the collection. */ + uint64_t count() const {return CBLCollection_Count(ref());} + + // Documents: + + /** Reads a document from the collection in an immutable form. + @note If you are reading the document in order to make changes to it, call \ref Collection::getMutableDocument() instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline Document getDocument(slice docID) const; + + /** Reads a document from the collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref Collection::getDocument(slice docID).) + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline MutableDocument getMutableDocument(slice docID) const; + + /** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + \ref Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @param doc The mutable document to save. */ + inline void saveDocument(MutableDocument &doc); + + /** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency); + + /** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param doc The mutable document to save. + @param handler The callback to be invoked if there is a conflict. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CollectionConflictHandler handler); + + /** Deletes a document from the collection. Deletions are replicated. + @param doc The document to delete. */ + inline void deleteDocument(Document &doc); + + /** Deletes a document from the collection. Deletions are replicated. + @param doc The document to delete. + @param concurrency Conflict-handling strategy. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool deleteDocument(Document &doc, CBLConcurrencyControl concurrency); + + /** Purges a document from the collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @note If you don't have the document in memory already, \ref purgeDocument(slice docID) is a simpler shortcut. + @param doc The document to purge. */ + inline void purgeDocument(Document &doc); + + /** Purges a document by its ID from the collection. + @param docID The document ID to purge. + @return True if the document was purged, false if it doesn't exist. */ + bool purgeDocument(slice docID) { + CBLError error; + bool purged = CBLCollection_PurgeDocumentByID(ref(), docID, &error); + if (!purged && error.code != 0) + throw error; + return purged; + } + + /** Returns the time, if any, at which a given document in the collection will expire and be purged. + Documents don't normally expire; you have to call \ref Collection::setDocumentExpiration(slice docID, time_t expiration) + to set a document's expiration time. + @param docID The ID of the document. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration */ + time_t getDocumentExpiration(slice docID) const { + CBLError error; + time_t exp = CBLCollection_GetDocumentExpiration(ref(), docID, &error); + check(exp >= 0, error); + return exp; + } + + /** Sets or clears the expiration time of a document in the collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. */ + void setDocumentExpiration(slice docID, time_t expiration) { + CBLError error; + check(CBLCollection_SetDocumentExpiration(ref(), docID, expiration, &error), error); + } + + // Indexes: + + /** Creates a value index in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The value index config. */ + void createValueIndex(slice name, CBLValueIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateValueIndex(ref(), name, config, &error), error); + } + + /** Creates a full-text index in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The full-text index config. */ + void createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateFullTextIndex(ref(), name, config, &error), error); + } + + /** Creates an array index for use with UNNEST queries in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The array index config. */ + void createArrayIndex(slice name, CBLArrayIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateArrayIndex(ref(), name, config, &error), error); + } + +#ifdef COUCHBASE_ENTERPRISE + /** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The vector index config. */ + inline void createVectorIndex(slice name, const VectorIndexConfiguration &config); +#endif + + /** Deletes an index given its name from the collection. */ + void deleteIndex(slice name) { + CBLError error; + check(CBLCollection_DeleteIndex(ref(), name, &error), error); + } + + /** Returns the names of the indexes in the collection, as a Fleece array of strings. */ + fleece::RetainedArray getIndexNames() { + CBLError error; + FLMutableArray flNames = CBLCollection_GetIndexNames(ref(), &error); + check(flNames, error); + fleece::RetainedArray names(flNames); + FLArray_Release(flNames); + return names; + } + + /** Get an index by name. If the index doesn't exist, the NULL QueryIndex object will be returned. */ + inline QueryIndex getIndex(slice name); + + // Listeners: + + /** Collection Change Listener Token */ + using CollectionChangeListener = cbl::ListenerToken; + + /** Registers a collection change listener callback. It will be called after one or more + documents in the collection are changed on disk. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] CollectionChangeListener addChangeListener(CollectionChangeListener::Callback callback) { + auto l = CollectionChangeListener(callback); + l.setToken( CBLCollection_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + /** Document Change Listener Token */ + using CollectionDocumentChangeListener = cbl::ListenerToken; + + /** Registers a document change listener callback. It will be called after a specific document in the collection + is changed on disk. + @param docID The ID of the document to observe. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] CollectionDocumentChangeListener addDocumentChangeListener(slice docID, + CollectionDocumentChangeListener::Callback callback) + { + auto l = CollectionDocumentChangeListener(callback); + l.setToken( CBLCollection_AddDocumentChangeListener(ref(), docID, &_callDocListener, l.context()) ); + return l; + } + + protected: + + static Collection adopt(const CBLCollection* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + Collection col; + col._ref = (CBLRefCounted*)d; + return col; + } + + friend class Database; + friend class Document; + friend class QueryIndex; + + CBL_REFCOUNTED_BOILERPLATE(Collection, RefCounted, CBLCollection); + + private: + + static void _callListener(void* _cbl_nullable context, const CBLCollectionChange* change) { + Collection col = Collection((CBLCollection*)change->collection); + std::vector docIDs((slice*)&change->docIDs[0], (slice*)&change->docIDs[change->numDocs]); + auto ch = std::make_unique(col, docIDs); + CollectionChangeListener::call(context, ch.get()); + } + + static void _callDocListener(void* _cbl_nullable context, const CBLDocumentChange* change) { + Collection col = Collection((CBLCollection*)change->collection); + slice docID = change->docID; + auto ch = std::make_unique(col, docID); + CollectionDocumentChangeListener::call(context, ch.get()); + } + }; + + /** Collection change info notified to the collection change listener's callback. */ + class CollectionChange { + public: + /** The collection. */ + Collection& collection() {return _collection;} + + /** The IDs of the changed documents. */ + std::vector& docIDs() {return _docIDs;} + + /** Internal API. */ + CollectionChange(Collection collection, std::vector docIDs) + :_collection(std::move(collection)) + ,_docIDs(std::move(docIDs)) + { } + + private: + + Collection _collection; + std::vector _docIDs; + }; + + /** Document change info notified to the document change listener's callback. */ + class DocumentChange { + public: + /** The collection. */ + Collection& collection() {return _collection;} + + /** The ID of the changed document. */ + slice& docID() {return _docID;} + + /** Internal API. */ + DocumentChange(Collection collection, slice docID) + :_collection(std::move(collection)) + ,_docID(std::move(docID)) + { } + + private: + + Collection _collection; + slice _docID; + }; + + // Database method bodies: + + inline Collection Database::getCollection(slice collectionName, slice scopeName) const { + CBLError error {}; + return Collection::adopt(CBLDatabase_Collection(ref(), collectionName, scopeName, &error), &error) ; + } + + inline Collection Database::createCollection(slice collectionName, slice scopeName) { + CBLError error {}; + return Collection::adopt(CBLDatabase_CreateCollection(ref(), collectionName, scopeName, &error), &error) ; + } + + inline Collection Database::getDefaultCollection() const { + CBLError error {}; + return Collection::adopt(CBLDatabase_DefaultCollection(ref(), &error), &error) ; + } +} + +/** Hash function for Collection. */ +template<> struct std::hash { + std::size_t operator() (cbl::Collection const& col) const { + auto name = CBLCollection_Name(col.ref()); + auto scope = CBLCollection_Scope(col.ref()); + std::size_t hash = fleece::slice(name).hash() ^ fleece::slice(CBLScope_Name(scope)).hash(); + CBLScope_Release(scope); + return hash; + } +}; + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/CouchbaseLite.hh b/libcblite_community/include/cbl++/CouchbaseLite.hh new file mode 100644 index 0000000..cd1f635 --- /dev/null +++ b/libcblite_community/include/cbl++/CouchbaseLite.hh @@ -0,0 +1,31 @@ +// +// CouchbaseLite.hh +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#pragma once +#include "Blob.hh" +#include "Collection.hh" +#include "Database.hh" +#include "Document.hh" +#include "Prediction.hh" +#include "Query.hh" +#include "QueryIndex.hh" +#include "Replicator.hh" +#include "VectorIndex.hh" diff --git a/libcblite_community/include/cbl++/Database.hh b/libcblite_community/include/cbl++/Database.hh new file mode 100644 index 0000000..ab0b9f2 --- /dev/null +++ b/libcblite_community/include/cbl++/Database.hh @@ -0,0 +1,591 @@ +// +// Database.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Base.hh" +#include "cbl/CBLCollection.h" +#include "cbl/CBLDatabase.h" +#include "cbl/CBLDocument.h" +#include "cbl/CBLQuery.h" +#include "cbl/CBLLog.h" +#include "cbl/CBLScope.h" +#include "fleece/Mutable.hh" +#include +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Collection; + class Document; + class MutableDocument; + class Query; + + /** Conflict handler used when saving a document. */ + using ConflictHandler = std::function; + + +#ifdef COUCHBASE_ENTERPRISE + /** ENTERPRISE EDITION ONLY + + Couchbase Lite Extension. */ + class Extension { + public: + /** Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @note Must be called before opening a database that intends to use the vector search extension. */ + static void enableVectorSearch(slice path) { + CBLError error {}; + RefCounted::check(CBL_EnableVectorSearch(path, &error), error); + } + }; +#endif + + /** Couchbase Lite Database. */ + class Database : private RefCounted { + public: + // Static database-file operations: + + /** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ + static bool exists(slice name, + slice inDirectory) + { + return CBL_DatabaseExists(name, inDirectory); + } + + /** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) */ + static void copyDatabase(slice fromPath, + slice toName) + { + CBLError error; + check( CBL_CopyDatabase(fromPath, toName, + nullptr, &error), error ); + } + + /** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) */ + static void copyDatabase(slice fromPath, + slice toName, + const CBLDatabaseConfiguration& config) + { + CBLError error; + check( CBL_CopyDatabase(fromPath, toName, + &config, &error), error ); + } + + /** Deletes a database file. If the database file is open, an error will be thrown. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ + static void deleteDatabase(slice name, + slice inDirectory) + { + CBLError error; + if (!CBL_DeleteDatabase(name, + inDirectory, + &error) && error.code != 0) + check(false, error); + } + + // Lifecycle: + + /** Opens a database, or creates it if it doesn't exist yet, returning a new \ref Database instance. + It's OK to open the same database file multiple times. Each \ref Database instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) */ + Database(slice name) { + open(name, nullptr); + } + + /** Opens a database, or creates it if it doesn't exist yet, returning a new \ref Database instance. + It's OK to open the same database file multiple times. Each \ref Database instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) */ + Database(slice name, + const CBLDatabaseConfiguration& config) + { + open(name, &config); + } + + /** Closes an open database. */ + void close() { + CBLError error; + check(CBLDatabase_Close(ref(), &error), error); + } + + /** Closes and deletes a database. */ + void deleteDatabase() { + CBLError error; + check(CBLDatabase_Delete(ref(), &error), error); + } + + /** Performs database maintenance. + @param type The database maintenance type. */ + void performMaintenance(CBLMaintenanceType type) { + CBLError error; + check(CBLDatabase_PerformMaintenance(ref(), type, &error), error); + } + + // Accessors: + + /** Returns the database's name. */ + std::string name() const {return asString(CBLDatabase_Name(ref()));} + + /** Returns the database's full filesystem path, or an empty string if the database is closed or deleted. */ + std::string path() const {return asString(CBLDatabase_Path(ref()));} + + /** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use Collection's count() on the default collection instead. */ + uint64_t count() const {return CBLDatabase_Count(ref());} + + /** Returns the database's configuration, as given when it was opened. */ + CBLDatabaseConfiguration config() const {return CBLDatabase_Config(ref());} + + // Collections: + + /** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @return The names of all existing scopes in the database, or throws if an error occurred. */ + fleece::MutableArray getScopeNames() const { + CBLError error {}; + FLMutableArray flNames = CBLDatabase_ScopeNames(ref(), &error); + check(flNames, error); + fleece::MutableArray names(flNames); + FLMutableArray_Release(flNames); + return names; + } + + /** Returns the names of all collections in the scope. + @param scopeName The name of the scope. + @return The names of all collections in the scope, or throws if an error occurred. */ + fleece::MutableArray getCollectionNames(slice scopeName =kCBLDefaultScopeName) const { + CBLError error {}; + FLMutableArray flNames = CBLDatabase_CollectionNames(ref(), scopeName, &error); + check(flNames, error); + fleece::MutableArray names(flNames); + FLMutableArray_Release(flNames); + return names; + } + + /** Returns the existing collection with the given name and scope. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @return A \ref Collection instance, or NULL if the collection doesn't exist, or throws if an error occurred. */ + inline Collection getCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName) const; + + /** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @return A \ref Collection instance, or throws if an error occurred. */ + inline Collection createCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName); + + /** Delete an existing collection. + @note The default collection cannot be deleted. + @param collectionName The name of the collection. + @param scopeName The name of the scope. */ + inline void deleteCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName) { + CBLError error {}; + check(CBLDatabase_DeleteCollection(ref(), collectionName, scopeName, &error), error); + } + + /** Returns the default collection. */ + inline Collection getDefaultCollection() const; + + // Documents: + + /** Reads a document from the default collection in an immutable form. + @note If you are reading the document in order to make changes to it, call \ref Database::getMutableDocument() instead. + @warning Deprecated : Use Collection::getDocument(slice docID) on the default collection instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline Document getDocument(slice docID) const; + + /** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref Database::getDocument(slice docID).) + @warning Deprecated : Use Collection::getMutableDocument(slice docID) on the default collection instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline MutableDocument getMutableDocument(slice docID) const; + + /** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref Database::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + \ref Database::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc) on the default collection instead. + @param doc The mutable document to save. */ + inline void saveDocument(MutableDocument &doc); + + /** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref Database::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + on the default collection instead. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency); + + /** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) + on the default collection instead. + @param doc The mutable document to save. + @param handler The callback to be invoked if there is a conflict. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, ConflictHandler handler); + + /** Deletes a document from the default collection. Deletions are replicated. + @warning Deprecated : Use Collection's deleteDocument(Document& doc) on the default collection instead. + @param doc The document to delete. */ + inline void deleteDocument(Document &doc); + + /** Deletes a document from the default collection. Deletions are replicated. + @warning Deprecated : Use Use Collection::deleteDocument(Document& doc, CBLConcurrencyControl concurrency) + on the default collection instead. + @param doc The document to delete. + @param concurrency Conflict-handling strategy. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool deleteDocument(Document &doc, CBLConcurrencyControl concurrency); + + /** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning Deprecated : Use Collection::purgeDocument(Document& doc) on the default collection instead. + @note If you don't have the document in memory already, \ref purgeDocument(slice docID) is a simpler shortcut. + @param doc The document to purge. */ + inline void purgeDocument(Document &doc); + + /** Purges a document by its ID from the default collection. + @warning Deprecated : Use Collection::purgeDocument(slice docID) on the default collection instead. + @param docID The document ID to purge. + @return True if the document was purged, false if it doesn't exist. */ + bool purgeDocument(slice docID) { + CBLError error; + bool purged = CBLDatabase_PurgeDocumentByID(ref(), docID, &error); + if (!purged && error.code != 0) + throw error; + return purged; + } + + /** Returns the time, if any, at which a given document in the default collection will expire and be purged. + Documents don't normally expire; you have to call \ref Database::setDocumentExpiration(slice docID, time_t expiration) + to set a document's expiration time. + @warning Deprecated : Use Collection::getDocumentExpiration(slice docID) on the default collection instead. + @param docID The ID of the document. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration */ + time_t getDocumentExpiration(slice docID) const { + CBLError error; + time_t exp = CBLDatabase_GetDocumentExpiration(ref(), docID, &error); + check(exp >= 0, error); + return exp; + } + + /** Sets or clears the expiration time of a document in the default collection. + @warning Deprecated : Use Collection::setDocumentExpiration(slice docID, time_t expiration) + on the default collection instead. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. */ + void setDocumentExpiration(slice docID, time_t expiration) { + CBLError error; + check(CBLDatabase_SetDocumentExpiration(ref(), docID, expiration, &error), error); + } + + // Query: + + /** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref Query object around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref Query::setParameters(fleece::Dict parameters) each time you run the query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @return The new query object. */ + inline Query createQuery(CBLQueryLanguage language, slice queryString); + + // Indexes: + + /** Creates a value index in the default collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use Collection::createValueIndex(slice name, CBLValueIndexConfiguration config) + on the default collection instead. + @param name The index name. + @param config The value index config. */ + void createValueIndex(slice name, CBLValueIndexConfiguration config) { + CBLError error; + check(CBLDatabase_CreateValueIndex(ref(), name, config, &error), error); + } + + /** Creates a full-text index in the default collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use Collection::createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) + on the default collection instead. + @param name The index name. + @param config The full-text index config. */ + void createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) { + CBLError error; + check(CBLDatabase_CreateFullTextIndex(ref(), name, config, &error), error); + } + + /** Deletes an index given its name from the default collection. + @warning Deprecated : Use Collection::deleteIndex(slice name) on the default collection instead. */ + void deleteIndex(slice name) { + CBLError error; + check(CBLDatabase_DeleteIndex(ref(), name, &error), error); + } + + /** Returns the names of the indexes in the default collection, as a Fleece array of strings. + @warning Deprecated : Use Collection::getIndexNames() on the default collection instead. */ + fleece::RetainedArray getIndexNames() { + FLArray flNames = CBLDatabase_GetIndexNames(ref()); + fleece::RetainedArray names(flNames); + FLArray_Release(flNames); + return names; + } + + // Listeners: + + /** Database (Default Collection) Change Listener Token */ + using ChangeListener = cbl::ListenerToken&>; + + /** Registers a database change listener callback. It will be called after one or more + documents in the default collection are changed on disk. + @warning Deprecated : Use Collection::addChangeListener(ChangeListener::Callback f) + on the default collection instead. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] ChangeListener addChangeListener(ChangeListener::Callback callback) { + auto l = ChangeListener(callback); + l.setToken( CBLDatabase_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + /** Document (in the Default Collection) Change Listener Token */ + using DocumentChangeListener = cbl::ListenerToken; + + /** Registers a document change listener callback. It will be called after a specific document in the default collection + is changed on disk. + @warning Deprecated : Use Collection::addDocumentChangeListener(slice docID, + DocumentChangeListener::Callback listener) on the default collection instead. + @param docID The ID of the document to observe. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] DocumentChangeListener addDocumentChangeListener(slice docID, + DocumentChangeListener::Callback callback) + { + auto l = DocumentChangeListener(callback); + l.setToken( CBLDatabase_AddDocumentChangeListener(ref(), docID, &_callDocListener, l.context()) ); + return l; + } + + // Notifications: + + using NotificationsReadyCallback = std::function; + + /** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref NotificationsReadyCallback will be called instead. + @param callback The function to be called when a notification is available. */ + void bufferNotifications(NotificationsReadyCallback callback) { + _notificationReadyCallbackAccess->setCallback(callback); + CBLDatabase_BufferNotifications(ref(), [](void *context, CBLDatabase *db) { + ((NotificationsReadyCallbackAccess*)context)->call(Database(db)); + }, _notificationReadyCallbackAccess.get()); + } + + /** Immediately issues all pending notifications for this database, by calling their listener callbacks. */ + void sendNotifications() { + CBLDatabase_SendNotifications(ref()); + } + + // Destructors: + + ~Database() { + clear(); + } + + protected: + friend class Collection; + friend class Scope; + + CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(Database, RefCounted, CBLDatabase) + + private: + void open(slice& name, const CBLDatabaseConfiguration* _cbl_nullable config) { + CBLError error {}; + _ref = (CBLRefCounted*)CBLDatabase_Open(name, config, &error); + check(_ref != nullptr, error); + + _notificationReadyCallbackAccess = std::make_shared(); + } + + class NotificationsReadyCallbackAccess { + public: + void setCallback(NotificationsReadyCallback callback) { + std::lock_guard lock(_mutex); + _callback = callback; + } + + void call(Database db) { + NotificationsReadyCallback callback; + { + std::lock_guard lock(_mutex); + callback = _callback; + } + if (callback) + callback(db); + } + private: + std::mutex _mutex; + NotificationsReadyCallback _callback {nullptr}; + }; + + static void _callListener(void* _cbl_nullable context, + const CBLDatabase *db, + unsigned nDocs, FLString *docIDs) + { + std::vector vec((slice*)&docIDs[0], (slice*)&docIDs[nDocs]); + ChangeListener::call(context, Database((CBLDatabase*)db), vec); + } + + static void _callDocListener(void* _cbl_nullable context, + const CBLDatabase *db, FLString docID) { + DocumentChangeListener::call(context, Database((CBLDatabase*)db), docID); + } + + std::shared_ptr _notificationReadyCallbackAccess; + + public: + Database(const Database &other) noexcept + :RefCounted(other) + ,_notificationReadyCallbackAccess(other._notificationReadyCallbackAccess) + { } + + Database(Database &&other) noexcept + :RefCounted((RefCounted&&)other) + ,_notificationReadyCallbackAccess(std::move(other._notificationReadyCallbackAccess)) + { } + + Database& operator=(const Database &other) noexcept { + RefCounted::operator=(other); + _notificationReadyCallbackAccess = other._notificationReadyCallbackAccess; + return *this; + } + + Database& operator=(Database &&other) noexcept { + RefCounted::operator=((RefCounted&&)other); + _notificationReadyCallbackAccess = std::move(other._notificationReadyCallbackAccess); + return *this; + } + + void clear() { + // Reset _notificationReadyCallbackAccess the releasing the _ref to + // ensure that CBLDatabase is deleted before _notificationReadyCallbackAccess. + RefCounted::clear(); + _notificationReadyCallbackAccess.reset(); + } + }; + + + /** A helper object for database transactions. + A Transaction object should be declared as a local (auto) variable. + You must explicitly call \ref commit to commit changes; if you don't, the transaction + will abort when it goes out of scope. */ + class Transaction { + public: + /** Begins a batch operation on the database that will end when the Batch instance + goes out of scope. */ + explicit Transaction(Database db) + :Transaction(db.ref()) + { } + + explicit Transaction (CBLDatabase *db) { + CBLError error; + RefCounted::check(CBLDatabase_BeginTransaction(db, &error), error); + _db = db; + } + + /** Commits changes and ends the transaction. */ + void commit() {end(true);} + + /** Ends the transaction, rolling back changes. */ + void abort() {end(false);} + + ~Transaction() {end(false);} + + private: + void end(bool commit) { + CBLDatabase *db = _db; + if (db) { + _db = nullptr; + CBLError error; + if (!CBLDatabase_EndTransaction(db, commit, &error)) { + // If an exception is thrown while a Batch is in scope, its destructor will + // call end(). If I'm in this situation I cannot throw another exception or + // the C++ runtime will abort the process. Detect this and just warn instead. + if (std::current_exception()) + CBL_Log(kCBLLogDomainDatabase, kCBLLogWarning, + "Transaction::end failed, while handling an exception"); + else + RefCounted::check(false, error); + } + } + } + + CBLDatabase* _cbl_nullable _db = nullptr; + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/Document.hh b/libcblite_community/include/cbl++/Document.hh new file mode 100644 index 0000000..365c7b6 --- /dev/null +++ b/libcblite_community/include/cbl++/Document.hh @@ -0,0 +1,286 @@ +// +// Document.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Collection.hh" +#include "cbl++/Database.hh" +#include "cbl/CBLDocument.h" +#include "fleece/Mutable.hh" +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class MutableDocument; + + /** Immutable Document. */ + class Document : protected RefCounted { + public: + // Metadata: + + /** A document's ID */ + std::string id() const {return asString(CBLDocument_ID(ref()));} + + /** A document's revision ID, which is a short opaque string that's guaranteed to be unique to every change made to + the document. If the document doesn't exist yet, this function returns an empty string. */ + std::string revisionID() const {return asString(CBLDocument_RevisionID(ref()));} + + /** A document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ + uint64_t sequence() const {return CBLDocument_Sequence(ref());} + + /** A document's collection or NULL for the new document that hasn't been saved. */ + Collection collection() const {return Collection(CBLDocument_Collection(ref()));} + + // Properties: + + /** A document's properties as an immutable dictionary. */ + fleece::Dict properties() const {return CBLDocument_Properties(ref());} + + /** A document's properties as JSON. */ + alloc_slice propertiesAsJSON() const {return alloc_slice(CBLDocument_CreateJSON(ref()));} + + /** A subscript operator to access a document's property value by key. */ + fleece::Value operator[] (slice key) const {return properties()[key];} + + // Operations: + + /** Creates a new mutable Document instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. */ + inline MutableDocument mutableCopy() const; + + protected: + friend class Collection; + friend class Database; + friend class Replicator; + + Document(CBLRefCounted* r) :RefCounted(r) { } + + static Document adopt(const CBLDocument* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + Document doc; + doc._ref = (CBLRefCounted*)d; + return doc; + } + + static bool checkSave(bool saveResult, CBLError &error) { + if (saveResult) + return true; + else if (error.code == kCBLErrorConflict && error.domain == kCBLDomain) + return false; + else + throw error; + } + + CBL_REFCOUNTED_BOILERPLATE(Document, RefCounted, const CBLDocument) + }; + + + /** Mutable Document. */ + class MutableDocument : public Document { + public: + /** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. */ + explicit MutableDocument(nullptr_t) {_ref = (CBLRefCounted*)CBLDocument_CreateWithID(fleece::nullslice);} + + /** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. */ + explicit MutableDocument(slice docID) {_ref = (CBLRefCounted*)CBLDocument_CreateWithID(docID);} + + /** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref MutableDict::getMutableDict() or \ref MutableDict::getMutableArray() */ + fleece::MutableDict properties() {return CBLDocument_MutableProperties(ref());} + + /** Sets a property key and value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + template + void set(slice key, const V &val) {properties().set(key, val);} + + /** Sets a property key and value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + template + void set(const K &key, const V &val) {properties().set(key, val);} + + /** A subscript operator to access a document's property value by key for either getting or setting the value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + fleece::keyref operator[] (slice key) + {return properties()[key];} + + /** Sets a mutable document's properties. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param properties The document properties. */ + void setProperties(fleece::MutableDict properties) { + CBLDocument_SetProperties(ref(), properties); + } + + /** Sets a mutable document's properties. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param properties The document properties. */ + void setProperties(fleece::Dict properties) { + CBLDocument_SetProperties(ref(), properties.mutableCopy()); + } + + /** Sets a mutable document's properties from a JSON Dictionary string. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param json A JSON Dictionaryt string */ + void setPropertiesAsJSON(slice json) { + CBLError error; + if (!CBLDocument_SetJSON(ref(), json, &error)) + throw error; + } + + protected: + static MutableDocument adopt(CBLDocument* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + MutableDocument doc; + doc._ref = (CBLRefCounted*)d; + return doc; + } + + friend class Collection; + friend class Database; + friend class Document; + CBL_REFCOUNTED_BOILERPLATE(MutableDocument, Document, CBLDocument) + }; + + // Document method bodies: + + inline MutableDocument Document::mutableCopy() const { + MutableDocument doc; + doc._ref = (CBLRefCounted*) CBLDocument_MutableCopy(ref()); + return doc; + } + + // Collection method bodies: + + inline Document Collection::getDocument(slice id) const { + CBLError error; + return Document::adopt(CBLCollection_GetDocument(ref(), id, &error), &error); + } + + inline MutableDocument Collection::getMutableDocument(slice id) const { + CBLError error; + return MutableDocument::adopt(CBLCollection_GetMutableDocument(ref(), id, &error), &error); + } + + inline void Collection::saveDocument(MutableDocument &doc) { + (void) saveDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl c) { + CBLError error; + return Document::checkSave( + CBLCollection_SaveDocumentWithConcurrencyControl(ref(), doc.ref(), c, &error), error); + } + + inline bool Collection::saveDocument(MutableDocument &doc, CollectionConflictHandler conflictHandler) { + CBLConflictHandler cHandler = [](void *context, CBLDocument *myDoc, + const CBLDocument *otherDoc) -> bool { + return (*(CollectionConflictHandler*)context)(MutableDocument(myDoc), + Document(otherDoc)); + }; + CBLError error; + return Document::checkSave( + CBLCollection_SaveDocumentWithConflictHandler(ref(), doc.ref(), cHandler, + &conflictHandler, &error), error); + } + + inline void Collection::deleteDocument(Document &doc) { + (void) deleteDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Collection::deleteDocument(Document &doc, CBLConcurrencyControl cc) { + CBLError error; + return Document::checkSave( + CBLCollection_DeleteDocumentWithConcurrencyControl(ref(), doc.ref(), cc, &error), error); + } + + inline void Collection::purgeDocument(Document &doc) { + CBLError error; + check(CBLCollection_PurgeDocument(ref(), doc.ref(), &error), error); + } + + // Database method bodies: + + inline Document Database::getDocument(slice id) const { + CBLError error; + return Document::adopt(CBLDatabase_GetDocument(ref(), id, &error), &error); + } + + inline MutableDocument Database::getMutableDocument(slice id) const { + CBLError error; + return MutableDocument::adopt(CBLDatabase_GetMutableDocument(ref(), id, &error), &error); + } + + inline void Database::saveDocument(MutableDocument &doc) { + (void) saveDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Database::saveDocument(MutableDocument &doc, CBLConcurrencyControl c) { + CBLError error; + return Document::checkSave( + CBLDatabase_SaveDocumentWithConcurrencyControl(ref(), doc.ref(), c, &error), + error); + } + + inline bool Database::saveDocument(MutableDocument &doc, + ConflictHandler conflictHandler) + { + CBLConflictHandler cHandler = [](void *context, CBLDocument *myDoc, + const CBLDocument *otherDoc) -> bool { + return (*(ConflictHandler*)context)(MutableDocument(myDoc), + Document(otherDoc)); + }; + CBLError error; + return Document::checkSave( + CBLDatabase_SaveDocumentWithConflictHandler(ref(), doc.ref(), cHandler, &conflictHandler, &error), + error); + } + + inline void Database::deleteDocument(Document &doc) { + (void) deleteDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Database::deleteDocument(Document &doc, CBLConcurrencyControl cc) { + CBLError error; + return Document::checkSave(CBLDatabase_DeleteDocumentWithConcurrencyControl( + ref(), doc.ref(), cc, &error), + error); + } + + inline void Database::purgeDocument(Document &doc) { + CBLError error; + check(CBLDatabase_PurgeDocument(ref(), doc.ref(), &error), error); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/Prediction.hh b/libcblite_community/include/cbl++/Prediction.hh new file mode 100644 index 0000000..f8d0302 --- /dev/null +++ b/libcblite_community/include/cbl++/Prediction.hh @@ -0,0 +1,88 @@ +// +// Prediction.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#ifdef COUCHBASE_ENTERPRISE + +#pragma once +#include "cbl++/Base.hh" +#include "cbl/CBLPrediction.h" +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + /** ENTERPRISE EDITION ONLY + + The PredictiveModel that allows to integrate machine learning model + into queries via invoking query's PREDICTION() function. + + @note The predictive index feature is not supported by Couchbase Lite for C. + The Predictive Model is currently for creating vector indexes using the PREDICTION() function, + which will call the specified predictive model for computing the vectors. */ + class PredictiveModel { + public: + /** Predicts and returns a mutable dictionary based on the input dictionary. + Override this function for the implementation. + @param input The input dictionary corresponding to the input dictionary expression given in the query's PREDICTION() function + @return The output dictionary. + - To create a new dictionary for returning, use fleece::MutableDict::newDict(). + - To create a null result to evaluate as MISSING, use fleece::MutableDict(). */ + virtual fleece::MutableDict prediction(fleece::Dict input) noexcept = 0; + + virtual ~PredictiveModel() = default; + }; + + static std::unordered_map> _sPredictiveModels; + + /** Predictive Model Registation + This class provides static methods to register and unregister predictive models. */ + class Prediction { + public: + /** Registers a predictive model with the given name. */ + static void registerModel(slice name, std::unique_ptr model) { + auto prediction = [](void* context, FLDict input) { + auto m = (PredictiveModel*)context; + return FLMutableDict_Retain((FLMutableDict) m->prediction(input)); + }; + + CBLPredictiveModel config { }; + config.context = model.get(); + config.prediction = prediction; + CBL_RegisterPredictiveModel(name, config); + + _sPredictiveModels[name] = std::move(model); + } + + /** Unregisters the predictive model with the given name. */ + static void unregisterModel(slice name) { + CBL_UnregisterPredictiveModel(name); + _sPredictiveModels.erase(name); + } + }; +} + +CBL_ASSUME_NONNULL_END + +#endif diff --git a/libcblite_community/include/cbl++/Query.hh b/libcblite_community/include/cbl++/Query.hh new file mode 100644 index 0000000..3314bba --- /dev/null +++ b/libcblite_community/include/cbl++/Query.hh @@ -0,0 +1,293 @@ +// +// Query.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Database.hh" +#include "cbl/CBLQuery.h" +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Query; + class ResultSet; + class ResultSetIterator; + + /** A database query. */ + class Query : private RefCounted { + public: + /** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref Query object around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref Query::setParameters(fleece::Dict parameters) each time you run the query. + @warning Deprecated : Use Database::createQuery(CBLQueryLanguage language, slice queryString) instead. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. */ + Query(const Database& db, CBLQueryLanguage language, slice queryString) { + CBLError error; + auto q = CBLDatabase_CreateQuery(db.ref(), language, queryString, nullptr, &error); + check(q, error); + _ref = (CBLRefCounted*)q; + } + + /** Returns the column names that will appear in the query results. + The column names are based on their expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ + inline std::vector columnNames() const; + + /** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param parameters The parameters in the form of a Fleece \ref Dict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the fleece::MutableDict) */ + void setParameters(fleece::Dict parameters) {CBLQuery_SetParameters(ref(), parameters);} + + /** Returns the query's current parameter bindings, if any. */ + fleece::Dict parameters() const {return CBLQuery_Parameters(ref());} + + /** Runs the query, returning the results. */ + inline ResultSet execute(); + + /** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. */ + std::string explain() { + return fleece::alloc_slice(CBLQuery_Explain(ref())).asString(); + } + + // Change listener (live query): + + class ChangeListener; + class Change; + + /** Registers a change listener callback to the query, turning it into a "live query" until + the listener is removed (via \ref ListenerToken::remove() ). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] inline ChangeListener addChangeListener(ListenerToken::Callback callback); + + private: + static void _callListener(void *context, CBLQuery*, CBLListenerToken* token); + CBL_REFCOUNTED_BOILERPLATE(Query, RefCounted, CBLQuery) + }; + + + /** A single query result; ResultSet::iterator iterates over these. */ + class Result { + public: + + /** Returns the number of columns in the current result. */ + uint64_t count() const { + return CBLQuery_ColumnCount(CBLResultSet_GetQuery(_ref)); + } + + /** Returns the current result as a JSON dictionary string. */ + alloc_slice toJSON() const { + FLDict dict = CBLResultSet_ResultDict(_ref); + return alloc_slice(FLValue_ToJSON((FLValue)dict)); + } + + /** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL Value, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ + fleece::Value valueAtIndex(unsigned i) const { + return CBLResultSet_ValueAtIndex(_ref, i); + } + + /** Returns the value of a column of the current result, given its column name. + This may return a NULL Value, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) */ + fleece::Value valueForKey(slice key) const { + return CBLResultSet_ValueForKey(_ref, key); + } + + /** A subscript operator that returns value of a column of the current result, given its (zero-based) numeric index. */ + fleece::Value operator[](int i) const {return valueAtIndex(i);} + + /** A subscript operator that returns the value of a column of the current result, given its column name. */ + fleece::Value operator[](slice key) const {return valueForKey(key);} + + protected: + explicit Result(CBLResultSet* _cbl_nullable ref) :_ref(ref) { } + CBLResultSet* _cbl_nullable _ref; + friend class ResultSetIterator; + }; + + /** The results of a query. The only access to the individual Results is to iterate them. */ + class ResultSet : private RefCounted { + public: + using iterator = ResultSetIterator; + inline iterator begin(); + inline iterator end(); + + private: + static ResultSet adopt(const CBLResultSet *d) { + ResultSet rs; + rs._ref = (CBLRefCounted*)d; + return rs; + } + + friend class Query; + CBL_REFCOUNTED_BOILERPLATE(ResultSet, RefCounted, CBLResultSet) + }; + + // Implementation of ResultSet::iterator + class ResultSetIterator { + public: + const Result& operator*() const {return _result;} + const Result& operator->() const {return _result;} + + bool operator== (const ResultSetIterator &i) const {return _rs == i._rs;} + bool operator!= (const ResultSetIterator &i) const {return _rs != i._rs;} + + ResultSetIterator& operator++() { + if (!CBLResultSet_Next(_rs.ref())) + _rs = ResultSet{}; + return *this; + } + protected: + ResultSetIterator() :_rs(), _result(nullptr) { } + explicit ResultSetIterator(ResultSet rs) + :_rs(rs), _result(_rs.ref()) + { + ++*this; // CBLResultSet_Next() has to be called first + } + + ResultSet _rs; + Result _result; + friend class ResultSet; + }; + + // Method implementations: + + inline std::vector Query::columnNames() const { + unsigned n = CBLQuery_ColumnCount(ref()); + std::vector cols; + cols.reserve(n); + for (unsigned i = 0; i < n ; ++i) { + fleece::slice name = CBLQuery_ColumnName(ref(), i); + cols.push_back(name.asString()); + } + return cols; + } + + inline ResultSet Query::execute() { + CBLError error; + auto rs = CBLQuery_Execute(ref(), &error); + check(rs, error); + return ResultSet::adopt(rs); + } + + class Query::ChangeListener : public ListenerToken { + public: + ChangeListener(): ListenerToken() { } + + ChangeListener(Query query, Callback cb) + :ListenerToken(cb) + ,_query(std::move(query)) + { } + + ResultSet results() { + if (!_query) { + throw std::runtime_error("Not allowed to call on uninitialized ChangeListeners"); + } + return getResults(_query, token()); + } + + private: + static ResultSet getResults(Query query, CBLListenerToken* token) { + CBLError error; + auto rs = CBLQuery_CopyCurrentResults(query.ref(), token, &error); + check(rs, error); + return ResultSet::adopt(rs); + } + + Query _query; + friend Change; + }; + + class Query::Change { + public: + Change(const Change& src) : _query(src._query), _token(src._token) {} + + ResultSet results() { + return ChangeListener::getResults(_query, _token); + } + + Query query() { + return _query; + } + + private: + friend class Query; + Change(Query q, CBLListenerToken* token) : _query(q), _token(token) {} + + Query _query; + CBLListenerToken* _token; + }; + + + inline Query::ChangeListener Query::addChangeListener(ChangeListener::Callback f) { + auto l = ChangeListener(*this, f); + l.setToken( CBLQuery_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + + inline void Query::_callListener(void *context, CBLQuery *q, CBLListenerToken* token) { + ChangeListener::call(context, Change{Query(q), token}); + } + + + inline ResultSet::iterator ResultSet::begin() { + return iterator(*this); + } + + inline ResultSet::iterator ResultSet::end() { + return iterator(); + } + + // Query + + Query Database::createQuery(CBLQueryLanguage language, slice queryString) { + return Query(*this, language, queryString); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/QueryIndex.hh b/libcblite_community/include/cbl++/QueryIndex.hh new file mode 100644 index 0000000..e2dc2d9 --- /dev/null +++ b/libcblite_community/include/cbl++/QueryIndex.hh @@ -0,0 +1,144 @@ +// +// QueryIndex.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#pragma once +#include "cbl++/Base.hh" +#include "cbl++/Collection.hh" +#include "cbl/CBLQueryIndex.h" + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { +#ifdef COUCHBASE_ENTERPRISE + class IndexUpdater; +#endif + + /** QueryIndex object representing an existing index in the collection. */ + class QueryIndex : private RefCounted { + public: + // Accessors: + + /** The index's name. */ + std::string name() const {return asString(CBLQueryIndex_Name(ref()));} + + /** A index's collection. */ + Collection collection() const {return Collection(CBLQueryIndex_Collection(ref()));} + +#ifdef COUCHBASE_ENTERPRISE + // Index Updater: + + /** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref IndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @param limit The maximum number of vectors to be computed. + @return An \ref IndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date. */ + inline IndexUpdater beginUpdate(size_t limit); +#endif + + protected: + friend class Collection; + + static QueryIndex adopt(const CBLQueryIndex* _cbl_nullable i, CBLError *error) { + if (!i && error->code != 0) + throw *error; + QueryIndex index; + index._ref = (CBLRefCounted*)i; + return index; + } + + CBL_REFCOUNTED_BOILERPLATE(QueryIndex, RefCounted, CBLQueryIndex) + }; + +#ifdef COUCHBASE_ENTERPRISE + + /** ENTERPRISE EDITION ONLY + + IndexUpdater is used for updating the index in lazy mode. Currently, the vector index is the only index type + that can be updated lazily. */ + class IndexUpdater : private RefCounted { + public: + /** The total number of vectors to compute and set for updating the index. */ + size_t count() const {return CBLIndexUpdater_Count(ref());} + + /** Get the value at the given index for computing the vector. + @param index The zero-based index. + @return The value. */ + fleece::Value value(size_t index) const { + return CBLIndexUpdater_Value(ref(), index); + } + + /** Sets the vector for the value corresponding to the given index. + Setting NULL vector means that there is no vector for the value, and any existing vector + will be removed when the \ref IndexUpdater::finish is called. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. */ + void setVector(unsigned index, const float* _cbl_nullable vector, size_t dimension) { + CBLError error; + check(CBLIndexUpdater_SetVector(ref(), index, vector, dimension, &error), error); + } + + /** Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the \ref QueryIndex::beginUpdate is later called. + @param index The zero-based index. */ + void skipVector(size_t index) { + CBLIndexUpdater_SkipVector(ref(), index); + } + + /** Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling \ref IndexUpdater::finish, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling \ref IndexUpdater::finish. */ + void finish() { + CBLError error; + check(CBLIndexUpdater_Finish(ref(), &error), error); + } + + protected: + static IndexUpdater adopt(const CBLIndexUpdater* _cbl_nullable i, CBLError *error) { + if (!i && error->code != 0) + throw *error; + IndexUpdater updater; + updater._ref = (CBLRefCounted*)i; + return updater; + } + + friend class QueryIndex; + CBL_REFCOUNTED_BOILERPLATE(IndexUpdater, RefCounted, CBLIndexUpdater) + }; + + IndexUpdater QueryIndex::beginUpdate(size_t limit) { + CBLError error {}; + auto updater = CBLQueryIndex_BeginUpdate(ref(), limit, &error); + return IndexUpdater::adopt(updater, &error); + } +#endif + + QueryIndex Collection::getIndex(slice name) { + CBLError error {}; + return QueryIndex::adopt(CBLCollection_GetIndex(ref(), name, &error), &error); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/Replicator.hh b/libcblite_community/include/cbl++/Replicator.hh new file mode 100644 index 0000000..c37c390 --- /dev/null +++ b/libcblite_community/include/cbl++/Replicator.hh @@ -0,0 +1,585 @@ +// +// Replicator.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Document.hh" +#include "cbl/CBLReplicator.h" +#include "cbl/CBLDefaults.h" +#include +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + + /** The replication endpoint representing the location of a database to replicate with. */ + class Endpoint { + public: + /** Creates a URL endpoint with a given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + @param url The url. */ + static Endpoint urlEndpoint(slice url) { + CBLError error {}; + auto endpoint = CBLEndpoint_CreateWithURL(url, &error); + if (!endpoint) + throw error; + return Endpoint(endpoint); + } + +#ifdef COUCHBASE_ENTERPRISE + /** Creates a database endpoint with another local database. (Enterprise Edition only.) */ + static Endpoint databaseEndpoint(Database db) { + return Endpoint(CBLEndpoint_CreateWithLocalDB(db.ref())); + } +#endif + + protected: + friend class ReplicatorConfiguration; + + CBLEndpoint* _cbl_nullable ref() const {return _ref.get();} + + private: + Endpoint() = default; + + Endpoint(CBLEndpoint* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLEndpoint_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** Authentication credentials for a remote server. */ + class Authenticator { + public: + /** Creates a basic authenticator authenticator using username/password credentials. */ + static Authenticator basicAuthenticator(slice username, slice password) { + return Authenticator(CBLAuth_CreatePassword(username, password)); + } + + /** Creates a sesssion authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ + static Authenticator sessionAuthenticator(slice sessionId, slice cookieName) { + return Authenticator(CBLAuth_CreateSession(sessionId, cookieName)); + } + + protected: + friend class ReplicatorConfiguration; + + CBLAuthenticator* _cbl_nullable ref() const {return _ref.get();} + + private: + Authenticator() = default; + + Authenticator(CBLAuthenticator* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLAuth_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** Replication Filter Function Callback. */ + using ReplicationFilter = std::function; + + /** Replication Conflict Resolver Function Callback. */ + using ConflictResolver = std::function; + + /** The collection and the configuration that can be configured specifically for the replication. */ + class ReplicationCollection { + public: + /** Creates ReplicationCollection with the collection. */ + ReplicationCollection(Collection collection) + :_collection(collection) + { } + + //-- Accessors: + /** The collection. */ + Collection collection() const {return _collection;} + + //-- Filtering: + /** Optional set of channels to pull from. */ + fleece::MutableArray channels = fleece::MutableArray::newArray(); + + /** Optional set of document IDs to replicate. */ + fleece::MutableArray documentIDs = fleece::MutableArray::newArray(); + + /** Optional callback to filter which docs are pushed. */ + ReplicationFilter pushFilter; + + /** Optional callback to validate incoming docs. */ + ReplicationFilter pullFilter; + + //-- Conflict Resolver: + /** Optional conflict-resolver callback. */ + ConflictResolver conflictResolver; + + private: + Collection _collection; + }; + + /** The configuration of a replicator. */ + class ReplicatorConfiguration { + public: + /** Creates a config using a database to represent the default collection and an endpoint. + @note Only the default collection will be used in the replication. + @warning Deprecated : + Use ReplicatorConfiguration::ReplicatorConfiguration(std::vectorcollections, Endpoint endpoint) + instead. + @param db The database to represent the default collection. + @param endpoint The endpoint to replicate with. */ + ReplicatorConfiguration(Database db, Endpoint endpoint) + :_database(db) + ,_endpoint(endpoint) + { } + + /** Creates a config with a list of collections and per-collection configurations to replicate and an endpoint + @param collections The collections and per-collection configurations. + @param endpoint The endpoint to replicate with. */ + ReplicatorConfiguration(std::vectorcollections, Endpoint endpoint) + :_collections(collections) + ,_endpoint(endpoint) + { } + + //-- Accessors: + /** Returns the configured database. */ + Database database() const {return _database;} + /** Returns the configured endpoint. */ + Endpoint endpoint() const {return _endpoint;} + /** Returns the configured collections. */ + std::vector collections() const {return _collections;} + + //-- Types: + /** Replicator type : Push, pull or both */ + CBLReplicatorType replicatorType = kCBLReplicatorTypePushAndPull; + /** Continuous replication or single-shot replication. */ + bool continuous = false; + + //-- Auto Purge: + /** Enabled auto-purge or not. + If auto purge is enabled, then the replicator will automatically purge any documents + that the replicating user loses access to via the Sync Function on Sync Gateway. */ + bool enableAutoPurge = true; + + //-- Retry Logic: + /** Max retry attempts where the initial connect to replicate counts toward the given value. + Specify 0 to use the default value, 10 times for a non-continuous replicator and max-int time for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts = 0; + /** Max wait time between retry attempts in seconds. + Specify 0 to use the default value of 300 seconds. */ + unsigned maxAttemptWaitTime = 0; + + //-- WebSocket: + /** The heartbeat interval in seconds. + Specify 0 to use the default value of 300 seconds. */ + unsigned heartbeat = 0; + + #ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. */ + std::string networkInterface; + #endif + + //-- HTTP settings: + /** Authentication credentials, if needed. */ + Authenticator authenticator; + /** HTTP client proxy settings. */ + CBLProxySettings* _cbl_nullable proxy = nullptr; + /** Extra HTTP headers to add to the WebSocket request. */ + fleece::MutableDict headers = fleece::MutableDict::newDict(); + + //-- Advance HTTP settings: + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default, which means that the parent-domain cookies are not permitted + to save by default. */ + bool acceptParentDomainCookies = kCBLDefaultReplicatorAcceptParentCookies; + + //-- TLS settings: + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + std::string pinnedServerCertificate; + /** Set of anchor certs (PEM format). */ + std::string trustedRootCertificates; + + //-- Filtering: + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::channels instead. */ + fleece::MutableArray channels = fleece::MutableArray::newArray(); + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::documentIDs instead. */ + fleece::MutableArray documentIDs = fleece::MutableArray::newArray(); + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::pushFilter instead. */ + ReplicationFilter pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::pullFilter instead. */ + ReplicationFilter pullFilter; + + //-- Conflict Resolver: + /** Optional conflict-resolver callback. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::conflictResolver instead. */ + ConflictResolver conflictResolver; + + protected: + friend class Replicator; + + /** Base config without database, collections, filters, and conflict resolver set. */ + operator CBLReplicatorConfiguration() const { + CBLReplicatorConfiguration conf = {}; + conf.endpoint = _endpoint.ref(); + assert(conf.endpoint); + conf.replicatorType = replicatorType; + conf.continuous = continuous; + conf.disableAutoPurge = !enableAutoPurge; + conf.maxAttempts = maxAttempts; + conf.maxAttemptWaitTime = maxAttemptWaitTime; + conf.heartbeat = heartbeat; + conf.authenticator = authenticator.ref(); + conf.acceptParentDomainCookies = acceptParentDomainCookies; + conf.proxy = proxy; + if (!headers.empty()) + conf.headers = headers; + #ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + if (!networkInterface.empty()) + conf.networkInterface = slice(networkInterface); + #endif + if (!pinnedServerCertificate.empty()) + conf.pinnedServerCertificate = slice(pinnedServerCertificate); + if (!trustedRootCertificates.empty()) + conf.trustedRootCertificates = slice(trustedRootCertificates); + return conf; + } + + private: + Database _database; + Endpoint _endpoint; + std::vector _collections; + }; + + /** Replicator for replicating documents in collections in local database and targeted database. */ + class Replicator : private RefCounted { + public: + /** Creates a new replicator using the specified config. */ + Replicator(const ReplicatorConfiguration& config) + { + // Get the current configured collections and populate one for the + // default collection if the config is configured with the database: + auto collections = config.collections(); + + auto database = config.database(); + if (database) { + assert(collections.empty()); + auto defaultCollection = database.getDefaultCollection(); + if (!defaultCollection) { + throw std::invalid_argument("default collection not exist"); + } + ReplicationCollection col = ReplicationCollection(defaultCollection); + col.channels = config.channels; + col.documentIDs = config.documentIDs; + col.pushFilter = config.pushFilter; + col.pullFilter = config.pullFilter; + col.conflictResolver = config.conflictResolver; + collections.push_back(col); + } + + // Created a shared collection map. The pointer of the collection map will be + // used as a context. + _collectionMap = std::shared_ptr(new CollectionToReplCollectionMap()); + + // Get base C config: + CBLReplicatorConfiguration c_config = config; + + // Construct C replication collections to set to the c_config: + std::vector replCols; + for (int i = 0; i < collections.size(); i++) { + ReplicationCollection& col = collections[i]; + + CBLReplicationCollection replCol {}; + replCol.collection = col.collection().ref(); + + if (!col.channels.empty()) { + replCol.channels = col.channels; + } + + if (!col.documentIDs.empty()) { + replCol.documentIDs = col.documentIDs; + } + + if (col.pushFilter) { + replCol.pushFilter = [](void* context, + CBLDocument* cDoc, + CBLDocumentFlags flags) -> bool { + auto doc = Document(cDoc); + auto map = (CollectionToReplCollectionMap*)context; + return map->find(doc.collection())->second.pushFilter(doc, flags); + }; + } + + if (col.pullFilter) { + replCol.pullFilter = [](void* context, + CBLDocument* cDoc, + CBLDocumentFlags flags) -> bool { + auto doc = Document(cDoc); + auto map = (CollectionToReplCollectionMap*)context; + return map->find(doc.collection())->second.pullFilter(doc, flags); + }; + } + + if (col.conflictResolver) { + replCol.conflictResolver = [](void* context, + FLString docID, + const CBLDocument* cLocalDoc, + const CBLDocument* cRemoteDoc) -> const CBLDocument* + { + auto localDoc = Document(cLocalDoc); + auto remoteDoc = Document(cRemoteDoc); + auto collection = localDoc ? localDoc.collection() : remoteDoc.collection(); + + auto map = (CollectionToReplCollectionMap*)context; + auto resolved = map->find(collection)->second. + conflictResolver(slice(docID), localDoc, remoteDoc); + + auto ref = resolved.ref(); + if (ref && ref != cLocalDoc && ref != cRemoteDoc) { + CBLDocument_Retain(ref); + } + return ref; + }; + } + replCols.push_back(replCol); + _collectionMap->insert({col.collection(), col}); + } + + c_config.collections = replCols.data(); + c_config.collectionCount = replCols.size(); + c_config.context = _collectionMap.get(); + + CBLError error {}; + _ref = (CBLRefCounted*) CBLReplicator_Create(&c_config, &error); + check(_ref, error); + } + + /** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ + void start(bool resetCheckpoint =false) {CBLReplicator_Start(ref(), resetCheckpoint);} + + /** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your replicator change listener if registered with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ + void stop() {CBLReplicator_Stop(ref());} + + /** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry. */ + void setHostReachable(bool r) {CBLReplicator_SetHostReachable(ref(), r);} + + /** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ + void setSuspended(bool s) {CBLReplicator_SetSuspended(ref(), s);} + + /** Returns the replicator's current status. */ + CBLReplicatorStatus status() const {return CBLReplicator_Status(ref());} + + /** Indicates which documents in the default collection have local changes that have not yet + been pushed to the server by this replicator. This is of course a snapshot, that will + go out of date as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + @note This function can be called on a stopped or un-started replicator. + @note Documents that would never be pushed by this replicator, due to its configuration's + `pushFilter` or `docIDs`, are ignored. + @warning If the default collection is not part of the replication, an error will be thrown. + @warning Deprecated : Use Replicator::pendingDocumentIDs(Collection& collection) instead. */ + fleece::Dict pendingDocumentIDs() const { + CBLError error; + fleece::Dict result = CBLReplicator_PendingDocumentIDs(ref(), &error); + check(result != nullptr, error); + return result; + } + + /** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref Replicator::pendingDocumentIDs() and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, an error will be thrown. + @warning Deprecated : Use Replicator::isDocumentPending(fleece::slice docID, Collection& collection) instead. */ + bool isDocumentPending(fleece::slice docID) const { + CBLError error; + bool pending = CBLReplicator_IsDocumentPending(ref(), docID, &error); + check(pending || error.code == 0, error); + return pending; + } + + /** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + @warning If the given collection is not part of the replication, an error will be thrown. */ + fleece::Dict pendingDocumentIDs(Collection& collection) const { + CBLError error; + fleece::Dict result = CBLReplicator_PendingDocumentIDs2(ref(), collection.ref(), &error); + check(result != nullptr, error); + return result; + } + + /** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref Replicator::pendingDocumentIDs(Collection& collection) and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, an error will be thrown. */ + bool isDocumentPending(fleece::slice docID, Collection& collection) const { + CBLError error; + bool pending = CBLReplicator_IsDocumentPending2(ref(), docID, collection.ref(), &error); + check(pending || error.code == 0, error); + return pending; + } + + /** A change listener that notifies you when the replicator's status changes. + @note The listener's callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. */ + using ChangeListener = cbl::ListenerToken; + + /** Registers a listener that will be called when the replicator's status changes. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] ChangeListener addChangeListener(ChangeListener::Callback callback) { + auto l = ChangeListener(callback); + l.setToken( CBLReplicator_AddChangeListener(ref(), &_callChangeListener, l.context()) ); + return l; + } + + /** A document replication listener that notifies you when documents are replicated. + @note The listener's callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. */ + using DocumentReplicationListener = cbl::ListenerToken>; + + /** Registers a listener that will be called when documents are replicated. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] DocumentReplicationListener addDocumentReplicationListener(DocumentReplicationListener::Callback callback) { + auto l = DocumentReplicationListener(callback); + l.setToken( CBLReplicator_AddDocumentReplicationListener(ref(), &_callDocListener, l.context()) ); + return l; + } + + private: + static void _callChangeListener(void* _cbl_nullable context, + CBLReplicator *repl, + const CBLReplicatorStatus *status) + { + ChangeListener::call(context, Replicator(repl), *status); + } + + static void _callDocListener(void* _cbl_nullable context, + CBLReplicator *repl, + bool isPush, + unsigned numDocuments, + const CBLReplicatedDocument* documents) + { + std::vector docs(&documents[0], &documents[numDocuments]); + DocumentReplicationListener::call(context, Replicator(repl), isPush, docs); + } + + using CollectionToReplCollectionMap = std::unordered_map; + std::shared_ptr _collectionMap; + + CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(Replicator, RefCounted, CBLReplicator) + + public: + Replicator(const Replicator &other) noexcept + :RefCounted(other) + ,_collectionMap(other._collectionMap) + { } + + Replicator(Replicator &&other) noexcept + :RefCounted((RefCounted&&)other) + ,_collectionMap(std::move(other._collectionMap)) + { } + + Replicator& operator=(const Replicator &other) noexcept { + RefCounted::operator=(other); + _collectionMap = other._collectionMap; + return *this; + } + + Replicator& operator=(Replicator &&other) noexcept { + RefCounted::operator=((RefCounted&&)other); + _collectionMap = std::move(other._collectionMap); + return *this; + } + + void clear() { + RefCounted::clear(); + _collectionMap.reset(); + } + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/cbl++/VectorIndex.hh b/libcblite_community/include/cbl++/VectorIndex.hh new file mode 100644 index 0000000..6f32110 --- /dev/null +++ b/libcblite_community/include/cbl++/VectorIndex.hh @@ -0,0 +1,189 @@ +// +// VectorIndex.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#ifdef COUCHBASE_ENTERPRISE + +#pragma once +#include "cbl++/Base.hh" +#include "cbl++/Collection.hh" +#include "cbl/CBLQueryIndexTypes.h" + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + /** ENTERPRISE EDITION ONLY + + Vector Encoding Type*/ + class VectorEncoding { + public: + /** Creates a no-encoding type to use in VectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ + static VectorEncoding none() { + return VectorEncoding(CBLVectorEncoding_CreateNone()); + } + + /** Creates a Scalar Quantizer encoding type to use in VectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ + static VectorEncoding scalarQuantizer(CBLScalarQuantizerType type) { + return VectorEncoding(CBLVectorEncoding_CreateScalarQuantizer(type)); + } + + /** Creates a Product Quantizer encoding type to use in VectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ + static VectorEncoding productQuantizer(unsigned int subquantizers, unsigned int bits) { + return VectorEncoding(CBLVectorEncoding_CreateProductQuantizer(subquantizers, bits)); + } + + VectorEncoding() = delete; + + protected: + friend class VectorIndexConfiguration; + + CBLVectorEncoding* ref() const {return _ref.get();} + + private: + VectorEncoding(CBLVectorEncoding* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLVectorEncoding_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ + class VectorIndexConfiguration { + public: + /** Creates the VectorIndexConfiguration. + @param expressionLanguage The language used in the expressions. + @param expression The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. + - For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + - For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref IndexUpdater to add or update the vector into the index. + @param dimensions The number of vector dimensions. + @note The maximum number of vector dimensions supported is 4096. + @param centroids The number of centroids which is the number buckets to partition the vectors in the index. + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000. */ + VectorIndexConfiguration(CBLQueryLanguage expressionLanguage, slice expression, + unsigned dimensions, unsigned centroids) + :_exprLang(expressionLanguage) + ,_expr(expression) + ,_dimensions(dimensions) + ,_centroids(centroids) + { } + + //-- Accessors: + + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage() const {return _exprLang;} + + /** The expression. */ + slice expression() const {return _expr;} + + /** The number of vector dimensions. */ + unsigned dimensions() const {return _dimensions;} + + /** The number of centroids. */ + unsigned centroids() const {return _centroids;} + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a \ref QueryIndex object. To get a \ref QueryIndex object, call \ref Collection::getIndex. */ + bool isLazy = false; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + VectorEncoding encoding = VectorEncoding::scalarQuantizer(kCBLSQ8); + + /** Distance Metric type. The default value is squared euclidean distance. */ + CBLDistanceMetric metric = kCBLDistanceMetricEuclideanSquared; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize = 0; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize = 0; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes = 0; + + protected: + friend Collection; + + /** To CBLVectorIndexConfiguration */ + operator CBLVectorIndexConfiguration() const { + CBLVectorIndexConfiguration config { _exprLang, _expr, _dimensions, _centroids }; + config.isLazy = isLazy; + config.encoding = encoding.ref(); + config.metric = metric; + config.minTrainingSize = minTrainingSize; + config.maxTrainingSize = maxTrainingSize; + config.numProbes = numProbes; + return config; + } + + private: + CBLQueryLanguage _exprLang; + slice _expr; + unsigned _dimensions; + unsigned _centroids; + }; + + void Collection::createVectorIndex(slice name, const VectorIndexConfiguration &config) { + CBLError error {}; + check(CBLCollection_CreateVectorIndex(ref(), name, config, &error), error); + } +} + +CBL_ASSUME_NONNULL_END + +#endif diff --git a/libcblite_community/include/cbl/CBLBase.h b/libcblite_community/include/cbl/CBLBase.h new file mode 100644 index 0000000..4590ad7 --- /dev/null +++ b/libcblite_community/include/cbl/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include "CBL_Edition.h" +#include "CBL_Compat.h" +#include "fleece/Fleece.h" +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLBlob.h b/libcblite_community/include/cbl/CBLBlob.h new file mode 100644 index 0000000..06daf8a --- /dev/null +++ b/libcblite_community/include/cbl/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLCollection.h b/libcblite_community/include/cbl/CBLCollection.h new file mode 100644 index 0000000..de90101 --- /dev/null +++ b/libcblite_community/include/cbl/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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" +#include "CBLDocument.h" +#include "CBLQueryIndexTypes.h" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; ///Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLDefaults.h b/libcblite_community/include/cbl/CBLDefaults.h new file mode 100644 index 0000000..696e648 --- /dev/null +++ b/libcblite_community/include/cbl/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include "CBL_Compat.h" +#include "CBLReplicator.h" +#include "CBLQueryIndexTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLDocument.h b/libcblite_community/include/cbl/CBLDocument.h new file mode 100644 index 0000000..6f7c3a8 --- /dev/null +++ b/libcblite_community/include/cbl/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLEncryptable.h b/libcblite_community/include/cbl/CBLEncryptable.h new file mode 100644 index 0000000..a3142ec --- /dev/null +++ b/libcblite_community/include/cbl/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/include/cbl/CBLLog.h b/libcblite_community/include/cbl/CBLLog.h new file mode 100644 index 0000000..25b53f9 --- /dev/null +++ b/libcblite_community/include/cbl/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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" + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLPlatform.h b/libcblite_community/include/cbl/CBLPlatform.h new file mode 100644 index 0000000..5f532a2 --- /dev/null +++ b/libcblite_community/include/cbl/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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" + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLPrediction.h b/libcblite_community/include/cbl/CBLPrediction.h new file mode 100644 index 0000000..cba35ce --- /dev/null +++ b/libcblite_community/include/cbl/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/include/cbl/CBLQuery.h b/libcblite_community/include/cbl/CBLQuery.h new file mode 100644 index 0000000..ad6f602 --- /dev/null +++ b/libcblite_community/include/cbl/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLQueryIndex.h b/libcblite_community/include/cbl/CBLQueryIndex.h new file mode 100644 index 0000000..2779f6a --- /dev/null +++ b/libcblite_community/include/cbl/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLQueryIndexTypes.h b/libcblite_community/include/cbl/CBLQueryIndexTypes.h new file mode 100644 index 0000000..48d6e66 --- /dev/null +++ b/libcblite_community/include/cbl/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLQueryTypes.h b/libcblite_community/include/cbl/CBLQueryTypes.h new file mode 100644 index 0000000..4082451 --- /dev/null +++ b/libcblite_community/include/cbl/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/include/cbl/CBLReplicator.h b/libcblite_community/include/cbl/CBLReplicator.h new file mode 100644 index 0000000..bffcb64 --- /dev/null +++ b/libcblite_community/include/cbl/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_community/include/cbl/CBL_Edition.h b/libcblite_community/include/cbl/CBL_Edition.h new file mode 100644 index 0000000..214ebe9 --- /dev/null +++ b/libcblite_community/include/cbl/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +/* #undef COUCHBASE_ENTERPRISE */ +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:23:40Z" diff --git a/libcblite_community/include/cbl/CouchbaseLite.h b/libcblite_community/include/cbl/CouchbaseLite.h new file mode 100644 index 0000000..180e5fb --- /dev/null +++ b/libcblite_community/include/cbl/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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" +#include "CBLBlob.h" +#include "CBLCollection.h" +#include "CBLDatabase.h" +#include "CBLDefaults.h" +#include "CBLDocument.h" +#include "CBLEncryptable.h" +#include "CBLLog.h" +#include "CBLPlatform.h" +#include "CBLPrediction.h" +#include "CBLQuery.h" +#include "CBLQueryIndex.h" +#include "CBLQueryIndexTypes.h" +#include "CBLQueryTypes.h" +#include "CBLReplicator.h" +#include "CBLScope.h" diff --git a/libcblite_community/include/fleece/CompilerSupport.h b/libcblite_community/include/fleece/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_community/include/fleece/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_community/include/fleece/Expert.hh b/libcblite_community/include/fleece/Expert.hh new file mode 100644 index 0000000..14109b8 --- /dev/null +++ b/libcblite_community/include/fleece/Expert.hh @@ -0,0 +1,207 @@ +// +// Expert.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_OBSCURE_HH +#define _FLEECE_OBSCURE_HH +#ifndef _FLEECE_HH +#include "Fleece.hh" +#endif + +#include "FLExpert.h" + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + + // VOLATILE API: These methods are meant for internal use, and will be removed + // in a future release + + // Rarely-needed or advanced functionality; a C++ wrapper around fleece/FLExpert.h + // For documentation, see the comments above the C functions these wrap. + + + /** Just a simple wrapper around \ref FLValue_FromData. + You should generally use a \ref Doc instead; it's safer.*/ + static inline Value ValueFromData(slice data, FLTrust t =kFLUntrusted) { + return FLValue_FromData(data,t); + } + + + //====== ENCODER: + + + /** Encoder subclass that exposes more bells and whistles, most of which are experimental. + You don't actually instantiate this, you call `expert(enc)` (below) to make a reference. */ + class Encoder_ExpertAPI : public Encoder { + public: + Encoder_ExpertAPI() = delete; + + /// Creates an Encoder that writes directly to a file. + static inline Encoder encodeToFile(FILE *file, bool uniqueStrings =true); + + inline void amend(slice base, bool reuseStrings =false, bool externPointers =false); + + slice base() const {return FLEncoder_GetBase(_enc);} + + void suppressTrailer() {FLEncoder_SuppressTrailer(_enc);} + + inline void writeRaw(slice data) {FLEncoder_WriteRaw(_enc, data);} + + size_t bytesWritten() const {return FLEncoder_BytesWritten(_enc);} + size_t nextWritePos() const {return FLEncoder_GetNextWritePos(_enc);} + + inline size_t finishItem() {return FLEncoder_FinishItem(_enc);} + }; + + // use this to call one of the above methods; e.g. `expert(e).suppressTrailer()`. + static inline auto& expert(Encoder &enc) {return (Encoder_ExpertAPI&)enc;} + static inline auto& expert(const Encoder &enc) {return (const Encoder_ExpertAPI&)(enc);} + + + //====== DELTAS: + + + /** Generates and applyies JSON-format deltas/diffs between two Fleece values. + See */ + class JSONDelta { + public: + static inline alloc_slice create(Value old, Value nuu); + static inline bool create(Value old, Value nuu, Encoder &jsonEncoder); + + [[nodiscard]] static inline alloc_slice apply(Value old, + slice jsonDelta, + FLError* FL_NULLABLE error); + /// Writes patched Fleece to the Encoder. + /// On failure, returns false and sets the Encoder's error property. + static inline bool apply(Value old, + slice jsonDelta, + Encoder &encoder); + }; + + + //====== SHARED KEYS: + + + /** Keeps track of a set of dictionary keys that are stored in abbreviated (small integer) form. + + Encoders can be configured to use an instance of this, and will use it to abbreviate keys + that are given to them as strings. (Note: This class is not thread-safe!) + + See */ + class SharedKeys { + public: + SharedKeys() :_sk(nullptr) { } + SharedKeys(FLSharedKeys FL_NULLABLE sk) :_sk(FLSharedKeys_Retain(sk)) { } + ~SharedKeys() {FLSharedKeys_Release(_sk);} + + static SharedKeys create() {return SharedKeys(FLSharedKeys_New(), 1);} + static inline SharedKeys create(slice state); + bool loadState(slice data) {return FLSharedKeys_LoadStateData(_sk, data);} + [[nodiscard]] bool loadState(Value state) {return FLSharedKeys_LoadState(_sk, state);} + alloc_slice stateData() const {return FLSharedKeys_GetStateData(_sk);} + inline void writeState(const Encoder &enc); + unsigned count() const {return FLSharedKeys_Count(_sk);} + void revertToCount(unsigned count) {FLSharedKeys_RevertToCount(_sk, count);} + void disableCaching() {if (_sk) FLSharedKeys_DisableCaching(_sk);} + + operator FLSharedKeys FL_NULLABLE () const {return _sk;} + bool operator== (SharedKeys other) const {return _sk == other._sk;} + + SharedKeys(const SharedKeys &other) noexcept :_sk(FLSharedKeys_Retain(other._sk)) { } + SharedKeys(SharedKeys &&other) noexcept :_sk(other._sk) {other._sk = nullptr;} + inline SharedKeys& operator= (const SharedKeys &other); + inline SharedKeys& operator= (SharedKeys &&other) noexcept; + + private: + SharedKeys(FLSharedKeys sk, int) :_sk(sk) { } + FLSharedKeys FL_NULLABLE _sk {nullptr}; + }; + + + //====== DEPRECATED: + + + /** A Dict that manages its own storage. This has been superseded by \ref Doc. */ + class AllocedDict : public Dict, alloc_slice { + public: + AllocedDict() + =default; + + explicit AllocedDict(alloc_slice s) + :Dict(FLValue_AsDict(FLValue_FromData(s, kFLUntrusted))) + ,alloc_slice(std::move(s)) + { } + + explicit AllocedDict(slice s) + :AllocedDict(alloc_slice(s)) { } + + const alloc_slice& data() const {return *this;} + explicit operator bool () const {return Dict::operator bool();} + + // MI disambiguation: + inline Value operator[] (slice key) const {return Dict::get(key);} + inline Value operator[] (const char *key) const {return Dict::get(key);} + }; + + + //====== IMPLEMENTATION GUNK: + + inline Encoder Encoder_ExpertAPI::encodeToFile(FILE *file, bool uniqueStrings) { + return Encoder(FLEncoder_NewWritingToFile(file, uniqueStrings)); + } + inline void Encoder_ExpertAPI::amend(slice base, bool reuseStrings, bool externPointers) { + FLEncoder_Amend(_enc, base, reuseStrings, externPointers); + } + + inline alloc_slice JSONDelta::create(Value old, Value nuu) { + return FLCreateJSONDelta(old, nuu); + } + inline bool JSONDelta::create(Value old, Value nuu, Encoder &jsonEncoder) { + return FLEncodeJSONDelta(old, nuu, jsonEncoder); + } + inline alloc_slice JSONDelta::apply(Value old, slice jsonDelta, FLError * FL_NULLABLE error) { + return FLApplyJSONDelta(old, jsonDelta, error); + } + inline bool JSONDelta::apply(Value old, + slice jsonDelta, + Encoder &encoder) + { + return FLEncodeApplyingJSONDelta(old, jsonDelta, encoder); + } + + inline void SharedKeys::writeState(const Encoder &enc) { + FLSharedKeys_WriteState(_sk, enc); + } + inline SharedKeys SharedKeys::create(slice state) { + auto sk = create(); + sk.loadState(state); + return sk; + } + inline SharedKeys& SharedKeys::operator= (const SharedKeys &other) { + auto sk = FLSharedKeys_Retain(other._sk); + FLSharedKeys_Release(_sk); + _sk = sk; + return *this; + } + inline SharedKeys& SharedKeys::operator= (SharedKeys &&other) noexcept { + FLSharedKeys_Release(_sk); + _sk = other._sk; + other._sk = nullptr; + return *this; + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_OBSCURE_HH diff --git a/libcblite_community/include/fleece/FLBase.h b/libcblite_community/include/fleece/FLBase.h new file mode 100644 index 0000000..d968f71 --- /dev/null +++ b/libcblite_community/include/fleece/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include "CompilerSupport.h" +#include "FLSlice.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_community/include/fleece/FLCollections.h b/libcblite_community/include/fleece/FLCollections.h new file mode 100644 index 0000000..146e94e --- /dev/null +++ b/libcblite_community/include/fleece/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_community/include/fleece/FLDeepIterator.h b/libcblite_community/include/fleece/FLDeepIterator.h new file mode 100644 index 0000000..2e57999 --- /dev/null +++ b/libcblite_community/include/fleece/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_community/include/fleece/FLDoc.h b/libcblite_community/include/fleece/FLDoc.h new file mode 100644 index 0000000..b62d8f3 --- /dev/null +++ b/libcblite_community/include/fleece/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_community/include/fleece/FLEncoder.h b/libcblite_community/include/fleece/FLEncoder.h new file mode 100644 index 0000000..b92d17d --- /dev/null +++ b/libcblite_community/include/fleece/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include "FLBase.h" +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_community/include/fleece/FLExpert.h b/libcblite_community/include/fleece/FLExpert.h new file mode 100644 index 0000000..5536f2c --- /dev/null +++ b/libcblite_community/include/fleece/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include "FLValue.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_community/include/fleece/FLJSON.h b/libcblite_community/include/fleece/FLJSON.h new file mode 100644 index 0000000..67c5e93 --- /dev/null +++ b/libcblite_community/include/fleece/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_community/include/fleece/FLKeyPath.h b/libcblite_community/include/fleece/FLKeyPath.h new file mode 100644 index 0000000..cd91877 --- /dev/null +++ b/libcblite_community/include/fleece/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_community/include/fleece/FLMutable.h b/libcblite_community/include/fleece/FLMutable.h new file mode 100644 index 0000000..d2f1d93 --- /dev/null +++ b/libcblite_community/include/fleece/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include "FLValue.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_community/include/fleece/FLSlice.h b/libcblite_community/include/fleece/FLSlice.h new file mode 100644 index 0000000..04e9720 --- /dev/null +++ b/libcblite_community/include/fleece/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include "CompilerSupport.h" +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_community/include/fleece/FLValue.h b/libcblite_community/include/fleece/FLValue.h new file mode 100644 index 0000000..9de1662 --- /dev/null +++ b/libcblite_community/include/fleece/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_community/include/fleece/Fleece+CoreFoundation.h b/libcblite_community/include/fleece/Fleece+CoreFoundation.h new file mode 100644 index 0000000..216c47b --- /dev/null +++ b/libcblite_community/include/fleece/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include "fleece/FLCollections.h" + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_community/include/fleece/Fleece.h b/libcblite_community/include/fleece/Fleece.h new file mode 100644 index 0000000..86ffc9f --- /dev/null +++ b/libcblite_community/include/fleece/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include "FLBase.h" +#include "FLCollections.h" +#include "FLDeepIterator.h" +#include "FLDoc.h" +#include "FLEncoder.h" +#include "FLJSON.h" +#include "FLKeyPath.h" +#include "FLMutable.h" +#include "FLValue.h" + +// #include "FLExpert.h" -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +# include "Fleece+CoreFoundation.h" +#endif + +#endif // _FLEECE_H diff --git a/libcblite_community/include/fleece/Fleece.hh b/libcblite_community/include/fleece/Fleece.hh new file mode 100644 index 0000000..5a0cffd --- /dev/null +++ b/libcblite_community/include/fleece/Fleece.hh @@ -0,0 +1,624 @@ +// +// Fleece.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_HH +#define _FLEECE_HH +#ifndef _FLEECE_H +#include "Fleece.h" +#endif +#include "slice.hh" +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + class Array; + class Dict; + class MutableArray; + class MutableDict; + class KeyPath; + class SharedKeys; + class Doc; + class Encoder; + + + /** A Fleece data value. Its subclasses are Array and Dict; Value itself is for scalars. */ + class Value { + public: + Value() =default; + Value(const Value &) noexcept =default; + Value(FLValue FL_NULLABLE v) :_val(v) { } + operator FLValue FL_NULLABLE () const {return _val;} + + static Value null() {return Value(kFLNullValue);} + static Value undefined() {return Value(kFLUndefinedValue);} + + inline FLValueType type() const; + inline bool isInteger() const; + inline bool isUnsigned() const; + inline bool isDouble() const; + inline bool isMutable() const; + + inline bool asBool() const; + inline int64_t asInt() const; + inline uint64_t asUnsigned() const; + inline float asFloat() const; + inline double asDouble() const; + inline slice asString() const; + inline FLTimestamp asTimestamp() const; + inline slice asData() const; + inline Array asArray() const; + inline Dict asDict() const; + + inline std::string asstring() const {return asString().asString();} + + inline alloc_slice toString() const; + inline alloc_slice toJSON(bool json5 =false, bool canonical =false) const; + inline std::string toJSONString() const {return std::string(toJSON());} + inline alloc_slice toJSON5() const {return toJSON(true);} + + explicit operator bool() const {return _val != nullptr;} + bool operator! () const {return _val == nullptr;} + bool operator== (Value v) const {return _val == v._val;} + bool operator== (FLValue FL_NULLABLE v) const {return _val == v;} + bool operator!= (Value v) const {return _val != v._val;} + bool operator!= (FLValue FL_NULLABLE v) const {return _val != v;} + + bool isEqual(Value v) const {return FLValue_IsEqual(_val, v);} + + Value& operator= (Value v) {_val = v._val; return *this;} + Value& operator= (std::nullptr_t) {_val = nullptr; return *this;} + + inline Value operator[] (const KeyPath &kp) const; + + inline Doc findDoc() const; + +#ifdef __OBJC__ + inline id asNSObject(NSMapTable* FL_NULLABLE sharedStrings =nil) const { + return FLValue_GetNSObject(_val, sharedStrings); + } +#endif + + // Disallowed because the mutable value would be released, which might free it: + Value(MutableArray&&) =delete; + Value& operator= (MutableArray&&) =delete; + Value(MutableDict&&) =delete; + Value& operator= (MutableDict&&) =delete; + + protected: + ::FLValue FL_NULLABLE _val {nullptr}; + }; + + + class valueptr { // A bit of ugly glue used to make Array/Dict iterator's operator-> work + public: + explicit valueptr(Value v) :_value(v) { } + Value* operator-> () {return &_value;} + private: + Value _value; + }; + + + /** An array of Fleece values. */ + class Array : public Value { + public: + Array() :Value() { } + Array(FLArray FL_NULLABLE a) :Value((FLValue)a) { } + Array(const Array&) noexcept = default; + operator FLArray FL_NULLABLE () const {return (FLArray)_val;} + + static Array emptyArray() {return Array(kFLEmptyArray);} + + inline uint32_t count() const; + [[nodiscard]] inline bool empty() const; + inline Value get(uint32_t index) const; + + inline Value operator[] (int index) const {return get(index);} + inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);} + + Array& operator= (Array a) {_val = a._val; return *this;} + Array& operator= (std::nullptr_t) {_val = nullptr; return *this;} + Value& operator= (Value v) =delete; + + [[nodiscard]] inline MutableArray asMutable() const; + + [[nodiscard]] inline MutableArray mutableCopy(FLCopyFlags =kFLDefaultCopy) const; + + + class iterator : private FLArrayIterator { + public: + inline iterator(Array); + inline iterator(const FLArrayIterator &i) :FLArrayIterator(i) { } + inline Value value() const; + inline uint32_t count() const {return FLArrayIterator_GetCount(this);} + inline bool next(); + inline valueptr operator -> () const {return valueptr(value());} + inline Value operator * () const {return value();} + inline explicit operator bool() const {return (bool)value();} + inline iterator& operator++ () {next(); return *this;} + inline bool operator!= (const iterator&) {return value() != nullptr;} + inline Value operator[] (unsigned n) const {return FLArrayIterator_GetValueAt(this,n);} + private: + iterator() =default; + friend class Array; + }; + + // begin/end are just provided so you can use the C++11 "for (Value v : array)" syntax. + inline iterator begin() const {return iterator(*this);} + inline iterator end() const {return iterator();} + + // Disallowed because the MutableArray would be released, which might free it: + Array(MutableArray&&) =delete; + Array& operator= (MutableArray&&) =delete; + }; + + + /** A mapping of strings to values. */ + class Dict : public Value { + public: + Dict() :Value() { } + Dict(FLDict FL_NULLABLE d) :Value((FLValue)d) { } + Dict(const Dict&) noexcept = default; + operator FLDict FL_NULLABLE () const {return (FLDict)_val;} + + static Dict emptyDict() {return Dict(kFLEmptyDict);} + + inline uint32_t count() const; + [[nodiscard]] inline bool empty() const; + + inline Value get(slice_NONNULL key) const; + + inline Value get(const char* key) const {return get(slice(key));} + + inline Value operator[] (slice_NONNULL key) const {return get(key);} + inline Value operator[] (const char *key) const {return get(key);} + inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);} + + Dict& operator= (Dict d) {_val = d._val; return *this;} + Dict& operator= (std::nullptr_t) {_val = nullptr; return *this;} + Value& operator= (Value v) =delete; + + [[nodiscard]] inline MutableDict asMutable() const; + + [[nodiscard]] inline MutableDict mutableCopy(FLCopyFlags =kFLDefaultCopy) const; + + /** An efficient key for a Dict. */ + class Key { + public: + explicit Key(slice_NONNULL string); + explicit Key(alloc_slice string); + inline const alloc_slice& string() const {return _str;} + operator const alloc_slice&() const {return _str;} + operator slice_NONNULL() const {return _str;} + private: + alloc_slice _str; + FLDictKey _key; + friend class Dict; + }; + + inline Value get(Key &key) const; + inline Value operator[] (Key &key) const {return get(key);} + + class iterator : private FLDictIterator { + public: + inline iterator(Dict); + inline iterator(const FLDictIterator &i) :FLDictIterator(i) { } + inline uint32_t count() const {return FLDictIterator_GetCount(this);} + inline Value key() const; + inline slice keyString() const; + inline Value value() const; + inline bool next(); + + inline valueptr operator -> () const {return valueptr(value());} + inline Value operator * () const {return value();} + inline explicit operator bool() const {return (bool)value();} + inline iterator& operator++ () {next(); return *this;} + inline bool operator!= (const iterator&) const {return value() != nullptr;} + +#ifdef __OBJC__ + inline NSString* keyAsNSString(NSMapTable *sharedStrings) const + {return FLDictIterator_GetKeyAsNSString(this, sharedStrings);} +#endif + private: + iterator() =default; + friend class Dict; + }; + + // begin/end are just provided so you can use the C++11 "for (Value v : dict)" syntax. + inline iterator begin() const {return iterator(*this);} + inline iterator end() const {return iterator();} + + // Disallowed because the MutableDict would be released, which might free it: + Dict(MutableDict&&) =delete; + Dict& operator= (MutableDict&&) =delete; + }; + + + /** Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + Similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + It looks like "foo.bar[2][-3].baz" -- that is, properties prefixed with a ".", and array + indexes in brackets. (Negative indexes count from the end of the array.) + A leading JSONPath-like "$." is allowed but ignored. + A '\' can be used to escape a special character ('.', '[' or '$') at the start of a + property name (but not yet in the middle of a name.) */ + class KeyPath { + public: + KeyPath(slice_NONNULL spec, FLError* FL_NULLABLE err) :_path(FLKeyPath_New(spec, err)) { } + ~KeyPath() {FLKeyPath_Free(_path);} + + KeyPath(KeyPath &&kp) :_path(kp._path) {kp._path = nullptr;} + KeyPath& operator=(KeyPath &&kp) {FLKeyPath_Free(_path); _path = kp._path; + kp._path = nullptr; return *this;} + + KeyPath(const KeyPath &kp) :KeyPath(std::string(kp), nullptr) { } + + explicit operator bool() const {return _path != nullptr;} + operator FLKeyPath FL_NONNULL () const {return _path;} + + Value eval(Value root) const { + return FLKeyPath_Eval(_path, root); + } + + static Value eval(slice_NONNULL specifier, Value root, FLError* FL_NULLABLE error) { + return FLKeyPath_EvalOnce(specifier, root, error); + } + + explicit operator std::string() const { + return std::string(alloc_slice(FLKeyPath_ToString(_path))); + } + + bool operator== (const KeyPath &kp) const {return FLKeyPath_Equals(_path, kp._path);} + private: + KeyPath& operator=(const KeyPath&) =delete; + friend class Value; + + FLKeyPath _path; + }; + + + /** An iterator that traverses an entire value hierarchy, descending into Arrays and Dicts. */ + class DeepIterator { + public: + DeepIterator(Value v) :_i(FLDeepIterator_New(v)) { } + ~DeepIterator() {FLDeepIterator_Free(_i);} + + Value value() const {return FLDeepIterator_GetValue(_i);} + slice key() const {return FLDeepIterator_GetKey(_i);} + uint32_t index() const {return FLDeepIterator_GetIndex(_i);} + Value parent() const {return FLDeepIterator_GetParent(_i);} + + size_t depth() const {return FLDeepIterator_GetDepth(_i);} + alloc_slice pathString() const {return FLDeepIterator_GetPathString(_i);} + alloc_slice JSONPointer() const {return FLDeepIterator_GetJSONPointer(_i);} + + void skipChildren() {FLDeepIterator_SkipChildren(_i);} + bool next() {return FLDeepIterator_Next(_i);} + + explicit operator bool() const {return value() != nullptr;} + DeepIterator& operator++() {next(); return *this;} + + private: + DeepIterator(const DeepIterator&) =delete; + + FLDeepIterator _i; + }; + + + /** A container for Fleece data in memory. Every Value belongs to the Doc whose memory range + contains it. The Doc keeps track of the SharedKeys used by its Dicts, and where to resolve + external pointers to. */ + class Doc { + public: + Doc(alloc_slice fleeceData, + FLTrust trust =kFLUntrusted, + FLSharedKeys FL_NULLABLE sk =nullptr, + slice externDest =nullslice) noexcept + { + // We construct FLSliceResult the following way to avoid unnecessary + // retain. (alloc_slice::operator FLSliceResult()& will apply a retain, which, + // if not matched by a release, will lead to memory leak.) + FLSliceResult sliceResult {fleeceData.buf, fleeceData.size}; + _doc = FLDoc_FromResultData(sliceResult, trust, sk, externDest); + } + + static inline Doc fromJSON(slice_NONNULL json, FLError* FL_NULLABLE outError = nullptr); + + Doc() :_doc(nullptr) { } + Doc(FLDoc FL_NULLABLE d, bool retain = true) :_doc(d) {if (retain) FLDoc_Retain(_doc);} + Doc(const Doc &other) noexcept :_doc(FLDoc_Retain(other._doc)) { } + Doc(Doc &&other) noexcept :_doc(other._doc) {other._doc=nullptr; } + Doc& operator=(const Doc &other); + Doc& operator=(Doc &&other) noexcept; + ~Doc() {FLDoc_Release(_doc);} + + slice data() const {return FLDoc_GetData(_doc);} + alloc_slice allocedData() const {return FLDoc_GetAllocedData(_doc);} + FLSharedKeys sharedKeys() const {return FLDoc_GetSharedKeys(_doc);} + + Value root() const {return FLDoc_GetRoot(_doc);} + explicit operator bool () const {return root() != nullptr;} + Array asArray() const {return root().asArray();} + Dict asDict() const {return root().asDict();} + + operator Value () const {return root();} + operator Dict () const {return asDict();} + operator FLDict FL_NULLABLE () const {return asDict();} + + Value operator[] (int index) const {return asArray().get(index);} + Value operator[] (slice key) const {return asDict().get(key);} + Value operator[] (const char *key) const {return asDict().get(key);} + Value operator[] (const KeyPath &kp) const {return root().operator[](kp);} + + bool operator== (const Doc &d) const {return _doc == d._doc;} + + operator FLDoc FL_NULLABLE () const {return _doc;} + FLDoc detach() {auto d = _doc; _doc = nullptr; return d;} + + static Doc containing(Value v) {return Doc(FLValue_FindDoc(v), false);} + bool setAssociated(void * FL_NULLABLE p, const char *t) {return FLDoc_SetAssociated(_doc, p, t);} + void* FL_NULLABLE associated(const char *type) const {return FLDoc_GetAssociated(_doc, type);} + + private: + friend class Value; + explicit Doc(FLValue v) :_doc(FLValue_FindDoc(v)) { } + + FLDoc FL_NULLABLE _doc; + }; + + + class Null { }; + /** A convenient way to specify (JSON) null when writing to an Encoder or mutable cllection */ + constexpr Null nullValue; + + + /** Generates Fleece-encoded data. */ + class Encoder { + public: + Encoder() :_enc(FLEncoder_New()) { } + + explicit Encoder(FLEncoderFormat format, + size_t reserveSize =0, + bool uniqueStrings =true) + :_enc(FLEncoder_NewWithOptions(format, reserveSize, uniqueStrings)) + { } + + explicit Encoder(FILE *file, + bool uniqueStrings =true) + :_enc(FLEncoder_NewWritingToFile(file, uniqueStrings)) + { } + + explicit Encoder(FLSharedKeys FL_NULLABLE sk) :Encoder() {setSharedKeys(sk);} + + explicit Encoder(FLEncoder enc) :_enc(enc) { } + Encoder(Encoder&& enc) :_enc(enc._enc) {enc._enc = nullptr;} + + void detach() {_enc = nullptr;} + + ~Encoder() {FLEncoder_Free(_enc);} + + void setSharedKeys(FLSharedKeys FL_NULLABLE sk) {FLEncoder_SetSharedKeys(_enc, sk);} + + operator ::FLEncoder FL_NONNULL () const {return _enc;} + + inline bool writeNull(); + inline bool writeUndefined(); + inline bool writeBool(bool); + inline bool writeInt(int64_t); + inline bool writeUInt(uint64_t); + inline bool writeFloat(float); + inline bool writeDouble(double); + inline bool writeString(slice); + inline bool writeString(const char *s) {return writeString(slice(s));} + inline bool writeString(std::string s) {return writeString(slice(s));} + inline bool writeDateString(FLTimestamp, bool asUTC =true); + inline bool writeData(slice); + inline bool writeValue(Value); + inline bool convertJSON(slice_NONNULL); + + inline bool beginArray(size_t reserveCount =0); + inline bool endArray(); + inline bool beginDict(size_t reserveCount =0); + inline bool writeKey(slice_NONNULL); + inline bool writeKey(Value); + inline bool endDict(); + + template + inline void write(slice_NONNULL key, T value) {writeKey(key); *this << value;} + + [[nodiscard]] inline Doc finishDoc(FLError* FL_NULLABLE =nullptr); + [[nodiscard]] inline alloc_slice finish(FLError* FL_NULLABLE =nullptr); + inline void reset(); + + inline FLError error() const; + inline const char* FL_NULLABLE errorMessage() const; + + //====== "<<" convenience operators; + + // Note: overriding <<(bool) would be dangerous due to implicit conversion + Encoder& operator<< (Null) {writeNull(); return *this;} + Encoder& operator<< (long long i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned long long i) {writeUInt(i); return *this;} + Encoder& operator<< (long i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned long i) {writeUInt(i); return *this;} + Encoder& operator<< (int i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned int i) {writeUInt(i); return *this;} + Encoder& operator<< (double d) {writeDouble(d); return *this;} + Encoder& operator<< (float f) {writeFloat(f); return *this;} + Encoder& operator<< (slice s) {writeString(s); return *this;} + Encoder& operator<< (const char *str) {writeString(str); return *this;} + Encoder& operator<< (const std::string &s) {writeString(s); return *this;} + Encoder& operator<< (Value v) {writeValue(v); return *this;} + + class keyref { + public: + keyref(Encoder &enc, slice key) :_enc(enc), _key(key) { } + template + inline void operator= (T value) {_enc.writeKey(_key); _enc << value;} + private: + Encoder &_enc; + slice _key; + }; + + // This enables e.g. `enc["key"_sl] = 17` + inline keyref operator[] (slice_NONNULL key) {return keyref(*this, key);} + +#ifdef __OBJC__ + bool writeNSObject(id obj) {return FLEncoder_WriteNSObject(_enc, obj);} + Encoder& operator<< (id obj) {writeNSObject(obj); return *this;} + NSData* finish(NSError **err) {return FLEncoder_FinishWithNSData(_enc, err);} +#endif + + protected: + Encoder(const Encoder&) =delete; + Encoder& operator=(const Encoder&) =delete; + + FLEncoder FL_NULLABLE _enc; + }; + + + /** Subclass of Encoder that generates JSON, not Fleece. */ + class JSONEncoder : public Encoder { + public: + JSONEncoder() :Encoder(kFLEncodeJSON) { } + inline void writeRaw(slice data) {FLEncoder_WriteRaw(_enc, data);} + }; + + /** Subclass of Encoder that generates JSON5 (an variant of JSON with cleaner syntax.) */ + class JSON5Encoder : public Encoder { + public: + JSON5Encoder() :Encoder(kFLEncodeJSON5) { } + }; + + + /** Use this instead of Encoder if you don't own the FLEncoder. Its destructor does not + free the underlying encoder object. */ + class SharedEncoder : public Encoder { + public: + explicit SharedEncoder(FLEncoder enc) :Encoder(enc) { } + + ~SharedEncoder() { + detach(); // prevents Encoder from freeing the FLEncoder + } + }; + + + //====== IMPLEMENTATION GUNK: + + inline FLValueType Value::type() const {return FLValue_GetType(_val);} + inline bool Value::isInteger() const {return FLValue_IsInteger(_val);} + inline bool Value::isUnsigned() const {return FLValue_IsUnsigned(_val);} + inline bool Value::isDouble() const {return FLValue_IsDouble(_val);} + inline bool Value::isMutable() const {return FLValue_IsMutable(_val);} + + inline bool Value::asBool() const {return FLValue_AsBool(_val);} + inline int64_t Value::asInt() const {return FLValue_AsInt(_val);} + inline uint64_t Value::asUnsigned() const {return FLValue_AsUnsigned(_val);} + inline float Value::asFloat() const {return FLValue_AsFloat(_val);} + inline double Value::asDouble() const {return FLValue_AsDouble(_val);} + inline FLTimestamp Value::asTimestamp() const {return FLValue_AsTimestamp(_val);} + inline slice Value::asString() const {return FLValue_AsString(_val);} + inline slice Value::asData() const {return FLValue_AsData(_val);} + inline Array Value::asArray() const {return FLValue_AsArray(_val);} + inline Dict Value::asDict() const {return FLValue_AsDict(_val);} + + inline alloc_slice Value::toString() const {return FLValue_ToString(_val);} + + inline alloc_slice Value::toJSON(bool json5, bool canonical) const { + return FLValue_ToJSONX(_val, json5, canonical); + } + + inline Value Value::operator[] (const KeyPath &kp) const + {return FLKeyPath_Eval(kp._path, _val);} + inline Doc Value::findDoc() const {return Doc(_val);} + + + + inline uint32_t Array::count() const {return FLArray_Count(*this);} + inline bool Array::empty() const {return FLArray_IsEmpty(*this);} + inline Value Array::get(uint32_t i) const {return FLArray_Get(*this, i);} + + inline Array::iterator::iterator(Array a) {FLArrayIterator_Begin(a, this);} + inline Value Array::iterator::value() const {return FLArrayIterator_GetValue(this);} + inline bool Array::iterator::next() {return FLArrayIterator_Next(this);} + + inline uint32_t Dict::count() const {return FLDict_Count(*this);} + inline bool Dict::empty() const {return FLDict_IsEmpty(*this);} + inline Value Dict::get(slice_NONNULL key) const {return FLDict_Get(*this, key);} + inline Value Dict::get(Dict::Key &key) const{return FLDict_GetWithKey(*this, &key._key);} + + inline Dict::Key::Key(alloc_slice s) :_str(std::move(s)), _key(FLDictKey_Init(_str)) { } + inline Dict::Key::Key(slice_NONNULL s) :Key(alloc_slice(s)) { } + + inline Dict::iterator::iterator(Dict d) {FLDictIterator_Begin(d, this);} + inline Value Dict::iterator::key() const {return FLDictIterator_GetKey(this);} + inline slice Dict::iterator::keyString() const {return FLDictIterator_GetKeyString(this);} + inline Value Dict::iterator::value() const {return FLDictIterator_GetValue(this);} + inline bool Dict::iterator::next() {return FLDictIterator_Next(this);} + + inline bool Encoder::writeNull() {return FLEncoder_WriteNull(_enc);} + inline bool Encoder::writeUndefined() {return FLEncoder_WriteUndefined(_enc);} + inline bool Encoder::writeBool(bool b) {return FLEncoder_WriteBool(_enc, b);} + inline bool Encoder::writeInt(int64_t n) {return FLEncoder_WriteInt(_enc, n);} + inline bool Encoder::writeUInt(uint64_t n) {return FLEncoder_WriteUInt(_enc, n);} + inline bool Encoder::writeFloat(float n) {return FLEncoder_WriteFloat(_enc, n);} + inline bool Encoder::writeDouble(double n) {return FLEncoder_WriteDouble(_enc, n);} + inline bool Encoder::writeString(slice s) {return FLEncoder_WriteString(_enc, s);} + inline bool Encoder::writeDateString(FLTimestamp ts, bool asUTC) + {return FLEncoder_WriteDateString(_enc, ts, asUTC);} + inline bool Encoder::writeData(slice data){return FLEncoder_WriteData(_enc, data);} + inline bool Encoder::writeValue(Value v) {return FLEncoder_WriteValue(_enc, v);} + inline bool Encoder::convertJSON(slice_NONNULL j) {return FLEncoder_ConvertJSON(_enc, j);} + inline bool Encoder::beginArray(size_t rsv) {return FLEncoder_BeginArray(_enc, rsv);} + inline bool Encoder::endArray() {return FLEncoder_EndArray(_enc);} + inline bool Encoder::beginDict(size_t rsv) {return FLEncoder_BeginDict(_enc, rsv);} + inline bool Encoder::writeKey(slice_NONNULL key) {return FLEncoder_WriteKey(_enc, key);} + inline bool Encoder::writeKey(Value key) {return FLEncoder_WriteKeyValue(_enc, key);} + inline bool Encoder::endDict() {return FLEncoder_EndDict(_enc);} + inline Doc Encoder::finishDoc(FLError* FL_NULLABLE err) {return Doc(FLEncoder_FinishDoc(_enc, err), false);} + inline alloc_slice Encoder::finish(FLError* FL_NULLABLE err) {return FLEncoder_Finish(_enc, err);} + inline void Encoder::reset() {return FLEncoder_Reset(_enc);} + inline FLError Encoder::error() const {return FLEncoder_GetError(_enc);} + inline const char* Encoder::errorMessage() const {return FLEncoder_GetErrorMessage(_enc);} + + // specialization for assigning bool value since there is no Encoder< + inline void Encoder::keyref::operator= (bool value) {_enc.writeKey(_key); _enc.writeBool(value);} + + inline Doc Doc::fromJSON(slice_NONNULL json, FLError * FL_NULLABLE outError) { + return Doc(FLDoc_FromJSON(json, outError), false); + } + + inline Doc& Doc::operator=(const Doc &other) { + if (other._doc != _doc) { + FLDoc_Release(_doc); + _doc = FLDoc_Retain(other._doc); + } + return *this; + } + + inline Doc& Doc::operator=(Doc &&other) noexcept { + if (other._doc != _doc) { + FLDoc_Release(_doc); + _doc = other._doc; + other._doc = nullptr; + } + return *this; + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_HH diff --git a/libcblite_community/include/fleece/InstanceCounted.hh b/libcblite_community/include/fleece/InstanceCounted.hh new file mode 100644 index 0000000..56c04a5 --- /dev/null +++ b/libcblite_community/include/fleece/InstanceCounted.hh @@ -0,0 +1,97 @@ +// +// InstanceCounted.hh +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/function_ref.hh" +#include //for size_t +#include +#include + +#ifndef INSTANCECOUNTED_TRACK + // TODO: Add this guard back in + //#if DEBUG + #define INSTANCECOUNTED_TRACK 1 + //#endif +#endif + +namespace fleece { + + /** Base class that keeps track of the total instance count of it and all subclasses. + This is useful for leak detection. + In debug builds or if INSTANCECOUNTED_TRACK is defined, the class will also track the + individual instance addresses, which can be logged by calling `dumpInstances`. */ + class InstanceCounted { + public: + + /** Total number of live objects that implement InstanceCounted. */ + static int liveInstanceCount() {return gInstanceCount;} + +#if INSTANCECOUNTED_TRACK + InstanceCounted() {track();} + InstanceCounted(const InstanceCounted&) {track();} + InstanceCounted(InstanceCounted &&old) {track(); old.untrack();} + virtual ~InstanceCounted() {untrack();} // must be virtual for RTTI + + /** Logs information to stderr about all live objects. */ + static void dumpInstances() {dumpInstances(nullptr);} + static void dumpInstances(function_ref f) {dumpInstances(&f);} + + protected: + InstanceCounted(size_t offset) {track(offset);} + private: + void track(size_t offset =0) const; + void untrack() const; + static void dumpInstances(function_ref*); + +#else + InstanceCounted() {++gInstanceCount;} + InstanceCounted(const InstanceCounted&) {++gInstanceCount;} + InstanceCounted(InstanceCounted &&old) {} // Do nothing, the old and new should balance + ~InstanceCounted() {--gInstanceCount;} +#endif + + private: + static std::atomic gInstanceCount; + }; + + + /** Alternative to InstanceCounted that must be used in cases where + - you're using multiple inheritance, + - InstanceCounted is not the first parent class listed, + - _and_ an earlier parent class has virtual methods. + In that situation, InstanceCounted won't be able to determine the exact address of the + object (due to the weird way C++ MI works), so instead you should use + InstanceCountedIn, where MyClass is the class you're declaring. For example: + class MyClass : public BaseClassWithVirtual, InstanceCountedIn { ... }; + */ + template + class InstanceCountedIn : public InstanceCounted { + public: +#if INSTANCECOUNTED_TRACK + InstanceCountedIn() + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { } + + InstanceCountedIn(const InstanceCountedIn&) + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { } + + InstanceCountedIn(InstanceCountedIn &&old) + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { + old.untrack(); + } +#endif + }; + + +} diff --git a/libcblite_community/include/fleece/Mutable.hh b/libcblite_community/include/fleece/Mutable.hh new file mode 100644 index 0000000..036aa55 --- /dev/null +++ b/libcblite_community/include/fleece/Mutable.hh @@ -0,0 +1,365 @@ +// +// Mutable.hh +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_MUTABLE_HH +#define _FLEECE_MUTABLE_HH +#include "Fleece.hh" + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + + // (this is a mostly-internal type that acts as a reference to an item of a MutableArray or + // MutableDict, and allows a value to be stored in it. It decouples dereferencing the collection + // from setting the value, which simplifies the code.) + class [[nodiscard]] Slot { + public: + void setNull() {FLSlot_SetNull(_slot);} + void operator= (Null) {FLSlot_SetNull(_slot);} + void operator= (bool v) {FLSlot_SetBool(_slot, v);} + void operator= (int v) {FLSlot_SetInt(_slot, v);} + void operator= (unsigned v) {FLSlot_SetUInt(_slot, v);} + void operator= (int64_t v) {FLSlot_SetInt(_slot, v);} + void operator= (uint64_t v) {FLSlot_SetUInt(_slot, v);} + void operator= (float v) {FLSlot_SetFloat(_slot, v);} + void operator= (double v) {FLSlot_SetDouble(_slot, v);} + void operator= (slice v) {FLSlot_SetString(_slot, v);} + void operator= (const char *v) {FLSlot_SetString(_slot, slice(v));} + void operator= (const std::string &v) {FLSlot_SetString(_slot, slice(v));} + void setData(slice v) {FLSlot_SetData(_slot, v);} + void operator= (Value v) {FLSlot_SetValue(_slot, v);} + + operator FLSlot FL_NONNULL() {return _slot;} + + private: + friend class MutableArray; + friend class MutableDict; + + Slot(FLSlot FL_NONNULL slot) :_slot(slot) { } + Slot(Slot&& slot) noexcept :_slot(slot._slot) { } + Slot(const Slot&) =delete; + Slot& operator=(const Slot&) =delete; + Slot& operator=(Slot&&) =delete; + + void operator= (const void*) = delete; // Explicitly disallow other pointer types! + + FLSlot const _slot; + }; + + + // (this is an internal type used to make `MutableArray` and `MutableDict`'s `operator[]` + // act idiomatically, supporting assignment. It's not used directly.) + template + class [[nodiscard]] keyref : public Value { + public: + keyref(Collection &coll, Key key) :Value(coll.get(key)), _coll(coll), _key(key) { } + template + void operator= (const keyref &ref) {_coll.set(_key, ref);} + template + void operator= (const T &value) {_coll.set(_key, value);} + + void setNull() {_coll.set(_key).setNull();} + void setData(slice value) {_coll.set(_key).setData(value);} + void remove() {_coll.remove(_key);} + + private: + Collection _coll; + Key _key; + }; + + + /** A mutable form of Array. Its storage lives in the heap, not in the (immutable) Fleece + document. It can be used to make a changed form of a document, which can then be + encoded to a new Fleece document. */ + class MutableArray : public Array { + public: + /** Creates a new, empty mutable array. */ + static MutableArray newArray() {return MutableArray(FLMutableArray_New(), false);} + + MutableArray() :Array() { } + MutableArray(FLMutableArray FL_NULLABLE a) :Array((FLArray)FLMutableArray_Retain(a)) { } + MutableArray(const MutableArray &a) :Array((FLArray)FLMutableArray_Retain(a)) { } + MutableArray(MutableArray &&a) noexcept :Array((FLArray)a) {a._val = nullptr;} + ~MutableArray() {FLMutableArray_Release(*this);} + + operator FLMutableArray FL_NULLABLE () const {return (FLMutableArray)_val;} + + MutableArray& operator= (const MutableArray &a) { + FLMutableArray_Retain(a); + FLMutableArray_Release(*this); + _val = a._val; + return *this; + } + + MutableArray& operator= (MutableArray &&a) noexcept { + if (a._val != _val) { + FLMutableArray_Release(*this); + _val = a._val; + a._val = nullptr; + } + return *this; + } + + /** The immutable Array this instance was constructed from (if any). */ + Array source() const {return FLMutableArray_GetSource(*this);} + + /** True if this array has been modified since it was created. */ + bool isChanged() const {return FLMutableArray_IsChanged(*this);} + + /** Removes a range of values from the array. */ + void remove(uint32_t first, uint32_t n =1) {FLMutableArray_Remove(*this, first, n);} + + /** Sets the array's size. If the array grows, new values begin as nulls. */ + void resize(uint32_t size) {FLMutableArray_Resize(*this, size);} + + Slot set(uint32_t i) {return Slot(FLMutableArray_Set(*this, i));} + void setNull(uint32_t i) {set(i).setNull();} + + template + void set(uint32_t i, T v) {set(i) = v;} + + Slot append() {return FLMutableArray_Append(*this);} + void appendNull() {append().setNull();} + + template + void append(T v) {append() = v;} + + void insertNulls(uint32_t i, uint32_t n) {FLMutableArray_Insert(*this, i, n);} + + // This enables e.g. `array[10] = 17` + inline keyref operator[] (int i) { + return keyref(*this, i); + } + + inline Value operator[] (int index) const {return get(index);} // const version + + + inline MutableArray getMutableArray(uint32_t i); + inline MutableDict getMutableDict(uint32_t i); + + private: + MutableArray(FLMutableArray FL_NULLABLE a, bool) :Array((FLArray)a) {} + friend class RetainedValue; + friend class RetainedArray; + friend class Array; + }; + + + /** A mutable form of Dict. Its storage lives in the heap, not in the (immutable) Fleece + document. It can be used to make a changed form of a document, which can then be + encoded to a new Fleece document. */ + class MutableDict : public Dict { + public: + static MutableDict newDict() {return MutableDict(FLMutableDict_New(), false);} + + MutableDict() :Dict() { } + MutableDict(FLMutableDict FL_NULLABLE d):Dict((FLDict)d) {FLMutableDict_Retain(*this);} + MutableDict(const MutableDict &d) :Dict((FLDict)d) {FLMutableDict_Retain(*this);} + MutableDict(MutableDict &&d) noexcept :Dict((FLDict)d) {d._val = nullptr;} + ~MutableDict() {FLMutableDict_Release(*this);} + + operator FLMutableDict FL_NULLABLE () const {return (FLMutableDict)_val;} + + MutableDict& operator= (const MutableDict &d) { + FLMutableDict_Retain(d); + FLMutableDict_Release(*this); + _val = d._val; + return *this; + } + + MutableDict& operator= (MutableDict &&d) noexcept { + if (d._val != _val) { + FLMutableDict_Release(*this); + _val = d._val; + d._val = nullptr; + } + return *this; + } + + Dict source() const {return FLMutableDict_GetSource(*this);} + bool isChanged() const {return FLMutableDict_IsChanged(*this);} + + void remove(slice key) {FLMutableDict_Remove(*this, key);} + + Slot set(slice key) {return FLMutableDict_Set(*this, key);} + void setNull(slice key) {set(key) = nullValue;} + + template + void set(slice key, T v) {set(key) = v;} + + + // This enables e.g. `dict["key"_sl] = 17` + inline keyref operator[] (slice key) + {return keyref(*this, key);} + inline keyref operator[] (const char *key) + {return keyref(*this, slice(key));} + inline keyref operator[] (Key &key) + {return keyref(*this, key);} + + inline Value operator[] (slice key) const {return Dict::get(key);} + inline Value operator[] (const char *key) const {return Dict::get(key);} + + inline MutableArray getMutableArray(slice key); + inline MutableDict getMutableDict(slice key); + + private: + MutableDict(FLMutableDict FL_NULLABLE d, bool) :Dict((FLDict)d) {} + friend class RetainedValue; + friend class RetainedDict; + friend class Dict; + }; + + + /** Equivalent to Value except that it retains (and releases) its contents. + This makes it safe for holding mutable arrays/dicts. It can also protect regular immutable + Values owned by a Doc from being freed, since retaining such a value causes its Doc to be + retained. */ + class RetainedValue : public Value { + public: + RetainedValue() =default; + RetainedValue(FLValue FL_NULLABLE v) :Value(FLValue_Retain(v)) { } + RetainedValue(const Value &v) :Value(FLValue_Retain(v)) { } + RetainedValue(RetainedValue &&v) noexcept :Value(v) {v._val = nullptr;} + RetainedValue(const RetainedValue &v) noexcept :RetainedValue(Value(v)) { } + RetainedValue(MutableArray &&v) noexcept :Value(v) {v._val = nullptr;} + RetainedValue(MutableDict &&v) noexcept :Value(v) {v._val = nullptr;} + ~RetainedValue() {FLValue_Release(_val);} + + RetainedValue& operator= (const Value &v) { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedValue& operator= (RetainedValue &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedValue& operator= (std::nullptr_t) { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + // NOTE: The RetainedArray and RetainedDict classes are copycats of the RetainedValue class + // above. Any future changes or bug fixes to the three classes should go together. + + /** Equivalent to Array except that it retains (and releases) its contents. + This makes it safe for holding a heap-allocated mutable array. */ + class RetainedArray : public Array { + public: + RetainedArray() =default; + RetainedArray(FLArray FL_NULLABLE v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(const Array &v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(RetainedArray &&v) noexcept :Array(v) {v._val = nullptr;} + RetainedArray(const RetainedArray &v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(MutableArray &&v) noexcept :Array(v) {v._val = nullptr;} + ~RetainedArray() {FLValue_Release(_val);} + + RetainedArray& operator= (const Array &v) noexcept { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedArray& operator= (RetainedArray &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedArray& operator= (std::nullptr_t) noexcept { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + /** Equivalent to Dict except that it retains (and releases) its contents. + This makes it safe for holding a heap-allocated mutable dict. */ + class RetainedDict : public Dict { + public: + RetainedDict() =default; + RetainedDict(FLDict FL_NULLABLE v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(const Dict &v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(RetainedDict &&v) noexcept :Dict(v) {v._val = nullptr;} + RetainedDict(const RetainedDict &v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(MutableDict &&v) noexcept :Dict(v) {v._val = nullptr;} + ~RetainedDict() {FLValue_Release(_val);} + + RetainedDict& operator= (const Dict &v) noexcept { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedDict& operator= (RetainedDict &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedDict& operator= (std::nullptr_t) noexcept { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + + //====== IMPLEMENTATION GUNK: + + inline MutableArray Array::mutableCopy(FLCopyFlags flags) const { + return MutableArray(FLArray_MutableCopy(*this, flags), false); + } + inline MutableDict Dict::mutableCopy(FLCopyFlags flags) const { + return MutableDict(FLDict_MutableCopy(*this, flags), false); + } + + inline MutableArray MutableArray::getMutableArray(uint32_t i) + {return FLMutableArray_GetMutableArray(*this, i);} + inline MutableDict MutableArray::getMutableDict(uint32_t i) + {return FLMutableArray_GetMutableDict(*this, i);} + inline MutableArray MutableDict::getMutableArray(slice key) + {return FLMutableDict_GetMutableArray(*this, key);} + inline MutableDict MutableDict::getMutableDict(slice key) + {return FLMutableDict_GetMutableDict(*this, key);} + + inline MutableArray Array::asMutable() const { + return MutableArray(FLArray_AsMutable(*this)); + } + + inline MutableDict Dict::asMutable() const { + return MutableDict(FLDict_AsMutable(*this)); + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_MUTABLE_HH diff --git a/libcblite_community/include/fleece/PlatformCompat.hh b/libcblite_community/include/fleece/PlatformCompat.hh new file mode 100644 index 0000000..477f9f6 --- /dev/null +++ b/libcblite_community/include/fleece/PlatformCompat.hh @@ -0,0 +1,90 @@ +// +// PlatformCompat.hh +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/CompilerSupport.h" +#ifdef __APPLE__ + #include + #include "TargetConditionals.h" +#endif + +#ifdef _MSC_VER + #define NOINLINE __declspec(noinline) + #define ALWAYS_INLINE inline + #define ASSUME(cond) __assume(cond) + #define LITECORE_UNUSED + #define __typeof decltype + + #define __func__ __FUNCTION__ + + #include + typedef SSIZE_T ssize_t; + + #define MAXFLOAT FLT_MAX + + #define __printflike(A, B) + + #define cbl_strdup _strdup + #define cbl_getcwd _getcwd + + #include + +#else + + // Suppresses "unused function" warnings + #if __has_attribute(unused) + # define LITECORE_UNUSED __attribute__((unused)) + #endif + + // Disables inlining a function. Use when the space savings are worth more than speed. + #if __has_attribute(noinline) + # define NOINLINE __attribute((noinline)) + #else + # define NOINLINE + #endif + + // Forces function to be inlined. Use with care for speed-critical code. + #if __has_attribute(always_inline) + #define ALWAYS_INLINE __attribute__((always_inline)) inline + #else + #define ALWAYS_INLINE inline + #endif + + // Tells the optimizer it may assume `cond` is true (but does not generate code to evaluate it.) + // A typical use cases is like `ASSUME(x != nullptr)`. + // Note: Avoid putting function calls inside it; I've seen cases where those functions appear + // inlined at the call site in the optimized code, even though they're not supposed to.) + #if __has_builtin(__builtin_assume) + #define ASSUME(cond) __builtin_assume(cond) + #else + #define ASSUME(cond) (void(0)) + #endif + + // Declares this function takes a printf-like format string, and the subsequent args should + // be type-checked against it. + #if __has_attribute(__format__) && !defined(__printflike) + # define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif + + // Windows has underscore prefixes before these function names, so define a common name + #define cbl_strdup strdup + #define cbl_getcwd getcwd + +#endif + +// Platform independent string substitutions +#if defined(__linux__) +#define PRIms "ld" +#else +#define PRIms "lld" +#endif diff --git a/libcblite_community/include/fleece/RefCounted.hh b/libcblite_community/include/fleece/RefCounted.hh new file mode 100644 index 0000000..a719575 --- /dev/null +++ b/libcblite_community/include/fleece/RefCounted.hh @@ -0,0 +1,288 @@ +// +// RefCounted.hh +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/PlatformCompat.hh" +#include +#include +#include + +namespace fleece { + + /** Simple thread-safe ref-counting implementation. + `RefCounted` objects should be managed by \ref Retained smart-pointers: + `Retained foo = new Foo(...)` or `auto foo = make_retained(...)`. + \note The ref-count starts at 0, so you must call retain() on an instance, or assign it + to a Retained, right after constructing it. */ + class RefCounted { + public: + RefCounted() =default; + + int refCount() const FLPURE {return _refCount;} + + protected: + RefCounted(const RefCounted &) { } + + /** Destructor is accessible only so that it can be overridden. + **Never call `delete`**, only `release`! Overrides should be made protected or private. */ + virtual ~RefCounted(); + + private: + template + friend T* retain(T*) noexcept; + friend void release(const RefCounted*) noexcept; + friend void assignRef(RefCounted* &dst, RefCounted *src) noexcept; + +#if DEBUG + void _retain() const noexcept {_careful_retain();} + void _release() const noexcept {_careful_release();} +#else + ALWAYS_INLINE void _retain() const noexcept { ++_refCount; } + void _release() const noexcept; +#endif + + static constexpr int32_t kCarefulInitialRefCount = -6666666; + void _careful_retain() const noexcept; + void _careful_release() const noexcept; + + mutable std::atomic _refCount +#if DEBUG + {kCarefulInitialRefCount}; +#else + {0}; +#endif + }; + + + /** Retains a RefCounted object and returns the object. Does nothing given a null pointer. + (See also `retain(Retained&&)`, below.) + \warning Manual retain/release is error prone. This function is intended mostly for interfacing + with C code that can't use \ref Retained. */ + template + ALWAYS_INLINE REFCOUNTED* retain(REFCOUNTED *r) noexcept { + if (r) r->_retain(); + return r; + } + + /** Releases a RefCounted object. Does nothing given a null pointer. + \warning Manual retain/release is error prone. This function is intended mostly for interfacing + with C code that can't use \ref Retained. */ + NOINLINE void release(const RefCounted *r) noexcept; + + + // Used internally by Retained's operator=. Marked noinline to prevent code bloat. + NOINLINE void assignRef(RefCounted* &holder, RefCounted *newValue) noexcept; + + // Makes `assignRef` polymorphic with RefCounted subclasses. + template + static inline void assignRef(T* &holder, RefCounted *newValue) noexcept { + assignRef((RefCounted*&)holder, newValue); + } + + + + /** A smart pointer that retains the RefCounted instance it holds. */ + template + class Retained { + public: + Retained() noexcept :_ref(nullptr) { } + Retained(T *t) noexcept :_ref(retain(t)) { } + + Retained(const Retained &r) noexcept :_ref(retain(r._ref)) { } + Retained(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + + template + Retained(const Retained &r) noexcept :_ref(retain(r._ref)) { } + + template + Retained(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + + ~Retained() {release(_ref);} + + operator T* () const & noexcept FLPURE STEPOVER {return _ref;} + T* operator-> () const noexcept FLPURE STEPOVER {return _ref;} + T* get() const noexcept FLPURE STEPOVER {return _ref;} + + explicit operator bool () const FLPURE {return (_ref != nullptr);} + + Retained& operator=(T *t) noexcept {assignRef(_ref, t); return *this;} + + Retained& operator=(const Retained &r) noexcept {return *this = r._ref;} + + template + Retained& operator=(const Retained &r) noexcept {return *this = r._ref;} + + Retained& operator= (Retained &&r) noexcept { + // Unexpectedly, the simplest & most efficient way to implement this is by simply + // swapping the refs, instead of the commented-out code below. + // The reason this works is that `r` is going to get destructed anyway when it goes + // out of scope in the caller's stack frame, and at that point it will contain my + // previous `_ref`, ensuring it gets cleaned up. + std::swap(_ref, r._ref); + // Older code: + // auto oldRef = _ref; + // _ref = std::move(r).detach(); + // release(oldRef); + return *this; + } + + template + Retained& operator= (Retained &&r) noexcept { + auto oldRef = _ref; + if (oldRef != r._ref) { // necessary to avoid premature release + _ref = std::move(r).detach(); + release(oldRef); + } + return *this; + } + + /// Converts a Retained into a raw pointer with a +1 reference that must be released. + /// Used in C++ functions that bridge to C and return C references. + [[nodiscard]] + T* detach() && noexcept {auto r = _ref; _ref = nullptr; return r;} + + // The operator below is often a dangerous mistake, so it's deliberately made impossible. + // It happens in these sorts of contexts, where it can produce a dangling pointer to a + // deleted object: + // Retained createFoo(); + // ... + // Foo *foo = createFoo(); // ☠️ + // or: + // return createFoo(); // ☠️ + // + // However, it _is_ valid if you're passing the Retained r-value as a function parameter, + // since it will not be released until after the function returns: + // void handleFoo(Foo*); + // ... + // handleFoo( createFoo() ); // Would be OK, but prohibited due to the above + // In this case you can use an explicit `get()` to work around the prohibition: + // handleFoo( createFoo().get() ); // OK! + // ...or promote it to an l-value: + // Retained foo = createFoo(); + // handleFoo(foo); // OK! + // ...or change `handleFoo`s parameter to Retained: + // void handleFoo(Retained); + // ... + // handleFoo( createFoo() ); // OK! + operator T* () const && =delete; // see above^ + + private: + template friend class Retained; + template friend class RetainedConst; + template friend Retained adopt(U*) noexcept; + + Retained(T *t, bool) noexcept :_ref(t) { } // private no-retain ctor + + T *_ref; + }; + + + /** Same as Retained, but when you only have a const pointer to the object. */ + template + class RetainedConst { + public: + RetainedConst() noexcept :_ref(nullptr) { } + RetainedConst(const T *t) noexcept :_ref(retain(t)) { } + RetainedConst(const RetainedConst &r) noexcept :_ref(retain(r._ref)) { } + RetainedConst(RetainedConst &&r) noexcept :_ref(std::move(r).detach()) { } + RetainedConst(const Retained &r) noexcept :_ref(retain(r._ref)) { } + RetainedConst(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + ALWAYS_INLINE ~RetainedConst() {release(_ref);} + + operator const T* () const & noexcept FLPURE STEPOVER {return _ref;} + const T* operator-> () const noexcept FLPURE STEPOVER {return _ref;} + const T* get() const noexcept FLPURE STEPOVER {return _ref;} + + RetainedConst& operator=(const T *t) noexcept { + auto oldRef = _ref; + _ref = retain(t); + release(oldRef); + return *this; + } + + RetainedConst& operator=(const RetainedConst &r) noexcept { + return *this = r._ref; + } + + RetainedConst& operator= (RetainedConst &&r) noexcept { + std::swap(_ref, r._ref); + return *this; + } + + template + RetainedConst& operator=(const Retained &r) noexcept { + return *this = r._ref; + } + + template + RetainedConst& operator= (Retained &&r) noexcept { + std::swap(_ref, r._ref); + return *this; + } + + [[nodiscard]] + const T* detach() && noexcept {auto r = _ref; _ref = nullptr; return r;} + + operator const T* () const && =delete; // Usually a mistake; see above under Retained + + private: + const T *_ref; + }; + + + /** Easy instantiation of a ref-counted object: `auto f = retained(new Foo());`*/ + template + [[nodiscard]] inline Retained retained(REFCOUNTED *r) noexcept { + return Retained(r); + } + + /** Easy instantiation of a const ref-counted object: `auto f = retained(new Foo());`*/ + template + [[nodiscard]] inline RetainedConst retained(const REFCOUNTED *r) noexcept { + return RetainedConst(r); + } + + /** Converts a raw pointer with a +1 reference into a Retained object. + This has no effect on the object's ref-count; the existing +1 ref will be released when the + Retained destructs. */ + template + [[nodiscard]] inline Retained adopt(REFCOUNTED *r) noexcept { + return Retained(r, false); + } + + + + /** make_retained(...) is equivalent to `std::make_unique` and `std::make_shared`. + It constructs a new RefCounted object, passing params to the constructor, returning a `Retained`. */ + template + [[nodiscard]] static inline Retained + make_retained(_Args&&... __args) { + return Retained(new T(std::forward<_Args>(__args)...)); + } + + + /** Extracts the pointer from a Retained. It must later be released via `release`. + This is used in bridging functions that return a direct pointer for a C API. */ + template + [[nodiscard]] ALWAYS_INLINE REFCOUNTED* retain(Retained &&retained) noexcept { + return std::move(retained).detach(); + } + + /** Extracts the pointer from a RetainedConst. It must later be released via `release`. + This is used in bridging functions that return a direct pointer for a C API. */ + template + [[nodiscard]] + ALWAYS_INLINE const REFCOUNTED* retain(RetainedConst &&retained) noexcept { + return std::move(retained).detach(); + } + +} diff --git a/libcblite_community/include/fleece/function_ref.hh b/libcblite_community/include/fleece/function_ref.hh new file mode 100644 index 0000000..feea300 --- /dev/null +++ b/libcblite_community/include/fleece/function_ref.hh @@ -0,0 +1,73 @@ +// +// function_ref.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// +// +// Extracted from LLVM source code retrieved from +// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/ADT/STLExtras.h + +//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some templates that are useful if you are working with the +// STL at all. +// +// No library is required when using these functions. +// +//===----------------------------------------------------------------------===// + +#pragma once +#include +#include +#include + +namespace fleece { + + +/// An efficient, type-erasing, non-owning reference to a callable. This is +/// intended for use as the type of a function parameter that is not used +/// after the function in question returns. +/// +/// This class does not own the callable, so it is not in general safe to store +/// a function_ref. +template class function_ref; + +template +class function_ref { + Ret (*callback)(intptr_t callable, Params ...params); + intptr_t callable; + + template + static Ret callback_fn(intptr_t callable, Params ...params) { + return (*reinterpret_cast(callable))( + std::forward(params)...); + } + +public: + template + function_ref(Callable &&callabl, + typename std::enable_if< + !std::is_same::type, + function_ref>::value>::type * = nullptr) + : callback(callback_fn::type>), + callable(reinterpret_cast(&callabl)) {} + Ret operator()(Params ...params) const { + return callback(callable, std::forward(params)...); + } +}; + + +} diff --git a/libcblite_community/include/fleece/slice.hh b/libcblite_community/include/fleece/slice.hh new file mode 100644 index 0000000..88d5d5c --- /dev/null +++ b/libcblite_community/include/fleece/slice.hh @@ -0,0 +1,901 @@ +// +// slice.hh +// +// Copyright 2014-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_SLICE_HH +#define _FLEECE_SLICE_HH + +#include "FLSlice.h" +#include // for std::min() +#include +#include +#include // for fputs() +#include // for memcpy(), memcmp() +#include + +#ifndef assert +# include +#endif +# ifndef assert_precondition +# define assert_precondition(e) assert(e) +#endif + +#ifdef __APPLE__ + struct __CFString; + struct __CFData; +# ifdef __OBJC__ + @class NSData; + @class NSString; + @class NSMapTable; +# endif +#endif + +// Figure out whether and how string_view is available +#ifdef __has_include +# if __has_include() +# include +# define SLICE_SUPPORTS_STRING_VIEW +# endif +#endif + + +// Utility for using slice with printf-style formatting. +// Use "%.*" in the format string; then for the corresponding argument put FMTSLICE(theslice). +// NOTE: The argument S will be evaluated twice. +#define FMTSLICE(S) (int)(S).size, (const char*)(S).buf + + +FL_ASSUME_NONNULL_BEGIN + + +namespace fleece { + struct slice; + struct alloc_slice; + struct nullslice_t; + +#ifdef SLICE_SUPPORTS_STRING_VIEW + using string_view = std::string_view; // create typedef with correct namespace +#endif + +#ifdef __APPLE__ + using CFStringRef = const struct ::__CFString *; + using CFDataRef = const struct ::__CFData *; +#endif + + /** Adds a byte offset to a pointer. */ + template + FLCONST constexpr14 inline const T* FL_NONNULL offsetby(const T * FL_NONNULL t, ptrdiff_t offset) noexcept { + return (const T*)((uint8_t*)t + offset); + } + + /** Adds a byte offset to a pointer. */ + template + FLCONST constexpr14 inline T* FL_NONNULL offsetby(T * FL_NONNULL t, ptrdiff_t offset) noexcept { + return (T*)((uint8_t*)t + offset); + } + + /** Subtracts the 2nd pointer from the 1st, returning the difference in addresses. */ + FLCONST constexpr inline ptrdiff_t _pointerDiff(const void* FL_NULLABLE a, const void* FL_NULLABLE b) noexcept { + return (uint8_t*)a - (uint8_t*)b; + } + + /** Subtracts the 2nd pointer from the 1st, returning the difference in addresses. */ + FLCONST constexpr inline ptrdiff_t pointerDiff(const void* a, const void* b) noexcept { + return _pointerDiff(a, b); + } + + +#pragma mark - PURE_SLICE: + + + /** Abstract superclass of `slice` and `alloc_slice`. + A simple pointer to a range of memory: `size` bytes starting at address `buf`. + + \note Not generally used directly; instead, use subclasses \ref slice and \ref alloc_slice. + `pure_slice` mostly serves to factor out their common API. + + * `buf` may be NULL, but only if `size` is zero; this is called `nullslice`. + * `size` may be zero with a non-NULL `buf`; that's called an "empty slice". + * **No ownership is implied!** Just like a regular pointer, it's the client's responsibility + to ensure the memory buffer remains valid. The `alloc_slice` subclass does provide + ownership: it manages a ref-counted heap-allocated buffer. + * Instances are immutable: `buf` and `size` cannot be changed. The `slice` subclass + changes this. + * The memory pointed to cannot be modified through this class. `slice` has some + methods that allow writes. */ + struct pure_slice { + const void* FL_NULLABLE const buf; + size_t const size; + + pure_slice(const pure_slice &) noexcept = default; + /// True if the slice's length is zero. + bool empty() const noexcept FLPURE {return size == 0;} + + /// Testing a slice as a bool results in false for nullslice, true for anything else. + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + + // These methods allow iterating a slice's bytes with a `for(:)` loop: + constexpr const uint8_t* FL_NULLABLE begin() const noexcept FLPURE {return (uint8_t*)buf;} + constexpr const uint8_t* FL_NULLABLE end() const noexcept FLPURE {return begin() + size;} + + /// Returns true if the address is within this slice or equal to its \ref end. + inline bool validAddress(const void * FL_NULLABLE addr) const noexcept FLPURE; + + /// Returns true if the byte at this address is in this slice; does _not_ include \ref end. + inline bool containsAddress(const void * FL_NULLABLE addr) const noexcept FLPURE; + + /// Returns true if the given slice is a subset of me. + inline bool containsAddressRange(pure_slice) const noexcept FLPURE; + + const void* offset(size_t o) const noexcept FLPURE; + size_t offsetOf(const void* ptr) const noexcept FLPURE; + + inline const uint8_t& operator[](size_t i) const noexcept FLPURE; + inline slice operator()(size_t i, size_t n) const noexcept FLPURE; + + inline slice upTo(const void* pos) const noexcept FLPURE; + inline slice from(const void* pos) const noexcept FLPURE; + inline slice upTo(size_t offset) const noexcept FLPURE; + inline slice from(size_t offset) const noexcept FLPURE; + + inline bool containsBytes(pure_slice bytes) const noexcept FLPURE; + inline slice find(pure_slice target) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findByte(uint8_t b) const FLPURE; + inline const uint8_t* FL_NULLABLE findByteOrEnd(uint8_t byte) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findAnyByteOf(pure_slice targetBytes) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findByteNotIn(pure_slice targetBytes) const noexcept FLPURE; + + inline int compare(pure_slice s) const noexcept FLPURE {return FLSlice_Compare(*this,s);} + inline int caseEquivalentCompare(pure_slice) const noexcept FLPURE; + inline bool caseEquivalent(pure_slice) const noexcept FLPURE; + + // Relational operators, implemented with FLSlice_Equal and compare(): + + bool operator==(const pure_slice &s) const noexcept FLPURE {return FLSlice_Equal(*this,s);} + bool operator!=(const pure_slice &s) const noexcept FLPURE {return !(*this == s);} + bool operator<(pure_slice s) const noexcept FLPURE {return compare(s) < 0;} + bool operator>(pure_slice s) const noexcept FLPURE {return compare(s) > 0;} + bool operator<=(pure_slice s) const noexcept FLPURE {return compare(s) <= 0;} + bool operator>=(pure_slice s) const noexcept FLPURE {return compare(s) >= 0;} + + inline bool hasPrefix(pure_slice) const noexcept FLPURE; + inline bool hasSuffix(pure_slice) const noexcept FLPURE; + bool hasPrefix(uint8_t b) const noexcept FLPURE {return size > 0 && (*this)[0] == b;} + bool hasSuffix(uint8_t b) const noexcept FLPURE {return size > 0 && (*this)[size-1] == b;} + + /** Computes a 32-bit non-cryptographic hash of the slice's contents. */ + uint32_t hash() const noexcept FLPURE {return FLSlice_Hash(*this);} + + /// Copies my contents to memory starting at `dst`, using `memcpy`. + void copyTo(void *dst) const noexcept {FLMemCpy(dst, buf, size);} + + /// Returns new malloc'ed slice containing same data. Call free() on it when done. + inline slice copy() const; + + // String conversions: + + explicit operator std::string() const {return std::string((const char*)buf, size);} + std::string asString() const {return (std::string)*this;} + + std::string hexString() const; + + /** Copies into a C string buffer of the given size. Result is always NUL-terminated and + will not overflow the buffer. Returns false if the slice was truncated. */ + inline bool toCString(char *buf, size_t bufSize) const noexcept; + + // FLSlice interoperability: + constexpr operator FLSlice () const noexcept {return {buf, size};} + +#ifdef SLICE_SUPPORTS_STRING_VIEW + // std::string_view interoperability: + constexpr pure_slice(string_view str) noexcept :pure_slice(str.data(), str.length()) {} + operator string_view() const noexcept STEPOVER {return string_view((const char*)buf, size);} +#endif + +#ifdef __APPLE__ + // Implementations in slice+CoreFoundation.cc and slice+ObjC.mm + explicit pure_slice(CFDataRef FL_NULLABLE data) noexcept; + CFStringRef createCFString() const; + CFDataRef createCFData() const; +# ifdef __OBJC__ + explicit pure_slice(NSData* FL_NULLABLE data) noexcept; + NSData* copiedNSData() const; + /** Creates an NSData using initWithBytesNoCopy and freeWhenDone:NO. + The data is not copied and does not belong to the NSData object, so make sure it + remains valid for the lifespan of that object!. */ + NSData* uncopiedNSData() const; + NSString* asNSString() const; + NSString* asNSString(NSMapTable* FL_NULLABLE sharedStrings) const; +# endif +#endif + + constexpr pure_slice(std::nullptr_t) noexcept :pure_slice() {} + constexpr pure_slice(const char* FL_NULLABLE str) noexcept :buf(str), size(_strlen(str)) {} + pure_slice(const std::string& str) noexcept :buf(&str[0]), size(str.size()) {} + + // Raw memory allocation. These throw std::bad_alloc on failure. + RETURNS_NONNULL inline static void* newBytes(size_t sz); + template RETURNS_NONNULL + static inline T* FL_NONNULL reallocBytes(T* FL_NULLABLE bytes, size_t newSz); + + protected: + constexpr pure_slice() noexcept :buf(nullptr), size(0) {} + inline constexpr pure_slice(const void* FL_NULLABLE b, size_t s) noexcept; + + inline void setBuf(const void *b) noexcept; + inline void setSize(size_t s) noexcept; + inline void set(const void * FL_NULLABLE, size_t) noexcept; + + // (Assignment must be custom because `buf` is declared as const/immutable.) + pure_slice& operator=(const pure_slice &s) noexcept {set(s.buf, s.size); return *this;} + static inline constexpr size_t _strlen(const char* FL_NULLABLE str) noexcept FLPURE; + // Throws std::bad_alloc, or if exceptions are disabled calls std::terminate() + [[noreturn]] static void failBadAlloc(); + // Sanity-checks `buf` and `size` + inline constexpr void checkValidSlice() const; + // Calls `assert_precondition(validAddress(addr))`, then returns `addr` + inline const void* check(const void *addr) const; + // Calls `assert_precondition(offset <= size)`, then returns `addr` + inline size_t check(size_t offset) const; + }; + + +#pragma mark - SLICE: + + + /** A simple pointer to a range of memory: `size` bytes starting at address `buf`. + \warning **No ownership is implied!** Just like a regular pointer, it's the client's + responsibility to ensure the memory buffer remains valid. + Some invariants: + * `buf` may be NULL, but only if `size` is zero; this is called `nullslice`. + * `size` may be zero with a non-NULL `buf`; that's called an "empty slice". */ + struct slice : public pure_slice { + constexpr slice() noexcept STEPOVER :pure_slice() {} + constexpr slice(std::nullptr_t) noexcept STEPOVER :pure_slice() {} + inline constexpr slice(nullslice_t) noexcept STEPOVER; + constexpr slice(const void* FL_NULLABLE b, size_t s) noexcept STEPOVER :pure_slice(b, s) {} + inline constexpr slice(const void* start, const void* end) noexcept STEPOVER; + inline constexpr slice(const alloc_slice&) noexcept STEPOVER; + + slice(const std::string& str) noexcept STEPOVER :pure_slice(str) {} + constexpr slice(const char* FL_NULLABLE str) noexcept STEPOVER :pure_slice(str) {} + + slice& operator= (alloc_slice&&) =delete; // Disallowed: might lead to ptr to freed buf + slice& operator= (const alloc_slice &s) noexcept {return *this = slice(s);} + slice& operator= (std::nullptr_t) noexcept {set(nullptr, 0); return *this;} + inline slice& operator= (nullslice_t) noexcept; + + /// Sets `size`. + void setSize(size_t s) noexcept {pure_slice::setSize(s);} + /// Sets `size`; asserts that the new size is not larger. + inline void shorten(size_t s); + + /// Adjusts `size` so that \ref end returns the given value. + void setEnd(const void* e) noexcept {setSize(pointerDiff(e, buf));} + /// Sets `buf` without moving the end, adjusting `size` accordingly. + inline void setStart(const void* s) noexcept; + /// Moves `buf` without moving the end, adjusting `size` accordingly. + void moveStart(ptrdiff_t delta) noexcept {set(offsetby(buf, delta), size - delta);} + /// Like \ref moveStart but returns false if the move is illegal. + bool checkedMoveStart(size_t delta) noexcept {if (size(static_cast(s)).retain();} + static void release(slice s) noexcept {static_cast(static_cast(s)).release();} + + private: + void assignFrom(pure_slice s) {set(s.buf, s.size);} + }; + + + + /** A slice whose `buf` may not be NULL. For use as a parameter type. */ + struct slice_NONNULL : public slice { + constexpr slice_NONNULL(const void* b, size_t s) :slice(b, s) {} + constexpr slice_NONNULL(slice s) :slice_NONNULL(s.buf, s.size) {} + constexpr slice_NONNULL(FLSlice s) :slice_NONNULL(s.buf,s.size) {} + constexpr slice_NONNULL(const char *str NONNULL) :slice(str) {} + slice_NONNULL(alloc_slice s) :slice_NONNULL(s.buf,s.size) {} + slice_NONNULL(const std::string &str) :slice_NONNULL(str.data(),str.size()) {} +#ifdef SLICE_SUPPORTS_STRING_VIEW + slice_NONNULL(string_view str) :slice_NONNULL(str.data(),str.size()) {} +#endif + slice_NONNULL(std::nullptr_t) =delete; + slice_NONNULL(nullslice_t) =delete; + }; + + + +#ifdef __APPLE__ + /** A slice holding the UTF-8 data of an NSString. If possible, it gets a pointer directly into + the NSString in O(1) time -- so don't modify or release the NSString while this is in scope. + Alternatively it will copy the string's UTF-8 into a small internal buffer, or allocate + a larger buffer on the heap (and free it in its destructor.) */ + struct nsstring_slice : public slice { + nsstring_slice(CFStringRef FL_NULLABLE); +# ifdef __OBJC__ + nsstring_slice(NSString* FL_NULLABLE str) :nsstring_slice((__bridge CFStringRef)str) { } +# endif + ~nsstring_slice(); + private: + long getBytes(CFStringRef, long lengthInChars); + char _local[127]; + bool _needsFree; + }; +#endif + + + /** Functor class for hashing the contents of a slice. + \note The below declarations of `std::hash` usually make it unnecessary to use this. */ + struct sliceHash { + std::size_t operator() (pure_slice const& s) const {return s.hash();} + }; + + + +#pragma mark - PURE_SLICE METHOD BODIES: + + + // like strlen but can run at compile time +#if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + inline constexpr size_t pure_slice::_strlen(const char* FL_NULLABLE str) noexcept { + if (!str) + return 0; + auto c = str; + while (*c) ++c; + return c - str; + } +#else + // (In C++11, constexpr functions couldn't contain loops; use (tail-)recursion instead) + inline constexpr size_t pure_slice::_strlen(const char* FL_NULLABLE str) noexcept { + return str ? _strlen(str, 0) : 0; + } + inline constexpr size_t pure_slice::_strlen(const char *str, size_t n) noexcept { + return *str ? _strlen(str + 1, n + 1) : n; + } +#endif + + + inline constexpr pure_slice::pure_slice(const void* FL_NULLABLE b, size_t s) noexcept + :buf(b), size(s) + { + checkValidSlice(); + } + + + inline void pure_slice::setBuf(const void *b) noexcept { + const_cast(buf) = b; + checkValidSlice(); + } + + inline void pure_slice::setSize(size_t s) noexcept { + const_cast(size) = s; + checkValidSlice(); + } + + inline void pure_slice::set(const void * FL_NULLABLE b, size_t s) noexcept { + const_cast(buf) = b; + const_cast(size) = s; + checkValidSlice(); + } + + + inline bool pure_slice::validAddress(const void * FL_NULLABLE addr) const noexcept { + // Note: unsigned comparison handles case when addr < buf + return size_t(_pointerDiff(addr, buf)) <= size; + } + + + inline bool pure_slice::containsAddress(const void * FL_NULLABLE addr) const noexcept { + return size_t(_pointerDiff(addr, buf)) < size; + } + + + inline bool pure_slice::containsAddressRange(pure_slice s) const noexcept { + return s.buf >= buf && s.end() <= end(); + } + + + inline constexpr void pure_slice::checkValidSlice() const { + assert_precondition(buf != nullptr || size == 0); + assert_precondition(size < (1ull << (8*sizeof(void*)-1))); // check accidental negative size + } + + + inline const void* pure_slice::check(const void *addr) const { + assert_precondition(validAddress(addr)); + return addr; + } + + inline size_t pure_slice::check(size_t offset) const { + assert_precondition(offset <= size); + return offset; + } + + + inline const void* pure_slice::offset(size_t o) const noexcept { + return (uint8_t*)buf + check(o); + } + + inline size_t pure_slice::offsetOf(const void* ptr NONNULL) const noexcept { + return pointerDiff(check(ptr), buf); + } + + + inline slice pure_slice::upTo(const void* pos) const noexcept { + return slice(buf, check(pos)); + } + + inline slice pure_slice::from(const void* pos) const noexcept { + return slice(check(pos), end()); + } + + inline slice pure_slice::upTo(size_t off) const noexcept { + return slice(buf, check(off)); + } + + inline slice pure_slice::from(size_t off) const noexcept { + return slice(offset(check(off)), end()); + } + + inline const uint8_t& pure_slice::operator[](size_t off) const noexcept { + assert_precondition(off < size); + return ((const uint8_t*)buf)[off]; + } + + inline slice pure_slice::operator()(size_t off, size_t nBytes) const noexcept { + assert_precondition(off + nBytes <= size); + return slice(offset(off), nBytes); + } + + + inline bool pure_slice::toCString(char *str, size_t bufSize) const noexcept { + size_t n = std::min(size, bufSize-1); + FLMemCpy(str, buf, n); + str[n] = 0; + return n == size; + } + + + inline std::string pure_slice::hexString() const { + static const char kDigits[17] = "0123456789abcdef"; + std::string result; + result.reserve(2 * size); + for (size_t i = 0; i < size; i++) { + uint8_t byte = (*this)[(unsigned)i]; + result += kDigits[byte >> 4]; + result += kDigits[byte & 0xF]; + } + return result; + } + + +#pragma mark COMPARISON & FIND: + + + __hot + inline int pure_slice::caseEquivalentCompare(pure_slice b) const noexcept { + size_t minSize = std::min(size, b.size); + for (size_t i = 0; i < minSize; i++) { + if ((*this)[i] != b[i]) { + int cmp = ::tolower((*this)[i]) - ::tolower(b[i]); + if (cmp != 0) + return cmp; + } + } + return (int)size - (int)b.size; + } + + + __hot + inline bool pure_slice::caseEquivalent(pure_slice b) const noexcept { + if (size != b.size) + return false; + for (size_t i = 0; i < size; i++) + if (::tolower((*this)[i]) != ::tolower(b[i])) + return false; + return true; + } + + + __hot + inline slice pure_slice::find(pure_slice target) const noexcept { + char* src = (char *)buf; + char* search = (char *)target.buf; + char* found = std::search(src, src + size, search, search + target.size); + if(found == src + size) { + return nullslice; + } + + return {found, target.size}; + } + + + inline bool pure_slice::containsBytes(pure_slice bytes) const noexcept { + return bool(find(bytes)); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByte(uint8_t b) const { + if (_usuallyFalse(size == 0)) + return nullptr; + return (const uint8_t*)::memchr(buf, b, size); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByteOrEnd(uint8_t byte) const noexcept { + auto result = findByte(byte); + return result ? result : (const uint8_t*)end(); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findAnyByteOf(pure_slice targetBytes) const noexcept { + // this could totally be optimized, if it turns out to matter... + const void* result = nullptr; + for (size_t i = 0; i < targetBytes.size; ++i) { + auto r = findByte(targetBytes[i]); + if (r && (!result || r < result)) + result = r; + } + return (const uint8_t*)result; + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByteNotIn(pure_slice targetBytes) const noexcept { + for (auto c = (const uint8_t*)buf; c != end(); ++c) { + if (!targetBytes.findByte(*c)) + return c; + } + return nullptr; + } + + + inline bool pure_slice::hasPrefix(pure_slice s) const noexcept { + return s.size > 0 && size >= s.size && ::memcmp(buf, s.buf, s.size) == 0; + } + + + inline bool pure_slice::hasSuffix(pure_slice s) const noexcept { + return s.size > 0 && size >= s.size + && ::memcmp(offsetby(buf, size - s.size), s.buf, s.size) == 0; + } + + +#pragma mark MEMORY ALLOCATION + + + /** Raw memory allocation. Just like malloc but throws/terminates on failure. */ + RETURNS_NONNULL + inline void* pure_slice::newBytes(size_t sz) { + void* result = ::malloc(sz); + if (_usuallyFalse(!result)) failBadAlloc(); + return result; + } + + + /** Like realloc but throws/terminates on failure. */ + template + RETURNS_NONNULL + inline T* FL_NONNULL pure_slice::reallocBytes(T* FL_NULLABLE bytes, size_t newSz) { + T* newBytes = (T*)::realloc(bytes, newSz); + if (_usuallyFalse(!newBytes)) failBadAlloc(); + return newBytes; + } + + inline slice pure_slice::copy() const { + if (buf == nullptr) + return nullslice; + void* copied = newBytes(size); + FLMemCpy(copied, buf, size); + return slice(copied, size); + } + + + [[noreturn]] + inline void pure_slice::failBadAlloc() { +#ifdef __cpp_exceptions + throw std::bad_alloc(); +#else + ::fputs("*** FATAL ERROR: heap allocation failed (fleece/slice.cc) ***\n", stderr); + std::terminate(); +#endif + } + + +#pragma mark - SLICE METHOD BODIES: + + + inline constexpr slice::slice(nullslice_t) noexcept :pure_slice() {} + inline constexpr slice::slice(const alloc_slice &s) noexcept :pure_slice(s) { } + + + inline constexpr slice::slice(const void* start, const void* end) noexcept + :slice(start, pointerDiff(end, start)) + { + assert_precondition(end >= start); + } + + + inline slice& slice::operator= (nullslice_t) noexcept { + set(nullptr, 0); + return *this; + } + + + inline slice::operator FLSliceResult () const noexcept { + return FLSliceResult(alloc_slice(*this)); + } + + + inline void slice::shorten(size_t s) { + setSize(check(s)); + } + + + inline void slice::setStart(const void *s) noexcept { + check(s); + set(s, pointerDiff(end(), s)); + } + + +#pragma mark - ALLOC_SLICE METHOD BODIES: + + + __hot + inline alloc_slice::alloc_slice(size_t sz) + :alloc_slice(FLSliceResult_New(sz)) + { + if (_usuallyFalse(!buf)) + failBadAlloc(); + } + + + __hot + inline alloc_slice::alloc_slice(pure_slice s) + :alloc_slice(FLSlice_Copy(s)) + { + if (_usuallyFalse(!buf) && s.buf) + failBadAlloc(); + } + + + inline alloc_slice alloc_slice::nullPaddedString(pure_slice str) { + // Leave a trailing null byte after the end, so it can be used as a C string + alloc_slice a(str.size + 1); + str.copyTo((void*)a.buf); + ((char*)a.buf)[str.size] = '\0'; + a.shorten(str.size); // the null byte is not part of the slice + return a; + } + + + __hot + inline alloc_slice& alloc_slice::operator=(const alloc_slice& s) noexcept { + if (_usuallyTrue(s.buf != buf)) { + release(); + assignFrom(s); + retain(); + } + return *this; + } + + + __hot + inline alloc_slice& alloc_slice::operator=(FLHeapSlice s) noexcept { + if (_usuallyTrue(s.buf != buf)) { + release(); + assignFrom(slice(s)); + retain(); + } + return *this; + } + + + inline void alloc_slice::resize(size_t newSize) { + if (newSize == size) { + return; + } else if (buf == nullptr) { + reset(newSize); + } else { + // We don't realloc the current buffer; that would affect other alloc_slice objects + // sharing the buffer, and possibly confuse them. Instead, alloc a new buffer & copy. + alloc_slice newSlice(newSize); + FLMemCpy((void*)newSlice.buf, buf, std::min(size, newSize)); + *this = std::move(newSlice); + } + } + + + inline void alloc_slice::append(pure_slice source) { + if (_usuallyFalse(source.size == 0)) + return; + const void *src = source.buf; + size_t oldSize = size; + if (_usuallyFalse(containsAddress(src))) { + // Edge case, where I contain the source bytes: update source address after realloc + size_t srcOff = size_t(pointerDiff(src, buf)); + resize(oldSize + source.size); + src = offset(srcOff); + } else { + resize(oldSize + source.size); + } + ::memcpy((void*)offset(oldSize), src, source.size); // already checked source.size > 0 + } + + + inline void alloc_slice::shorten(size_t s) { + pure_slice::setSize(check(s)); + } + +} + + +namespace std { + // Declare the default hash function for `slice` and `alloc_slice`. This allows them to be + // used in hashed collections like `std::unordered_map` and `std::unordered_set`. + template<> struct hash { + std::size_t operator() (fleece::pure_slice const& s) const {return s.hash();} + }; + template<> struct hash { + std::size_t operator() (fleece::pure_slice const& s) const {return s.hash();} + }; +} + + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_SLICE_HH diff --git a/libcblite_community/lib/aarch64-linux-android/libcblite.so b/libcblite_community/lib/aarch64-linux-android/libcblite.so new file mode 100644 index 0000000..9465fae Binary files /dev/null and b/libcblite_community/lib/aarch64-linux-android/libcblite.so differ diff --git a/libcblite_community/lib/aarch64-linux-android/libcblite.stripped.so b/libcblite_community/lib/aarch64-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..5a13e10 Binary files /dev/null and b/libcblite_community/lib/aarch64-linux-android/libcblite.stripped.so differ diff --git a/libcblite_community/lib/arm-linux-androideabi/libcblite.so b/libcblite_community/lib/arm-linux-androideabi/libcblite.so new file mode 100644 index 0000000..9352233 Binary files /dev/null and b/libcblite_community/lib/arm-linux-androideabi/libcblite.so differ diff --git a/libcblite_community/lib/arm-linux-androideabi/libcblite.stripped.so b/libcblite_community/lib/arm-linux-androideabi/libcblite.stripped.so new file mode 100755 index 0000000..8a47f5d Binary files /dev/null and b/libcblite_community/lib/arm-linux-androideabi/libcblite.stripped.so differ diff --git a/libcblite_community/lib/i686-linux-android/libcblite.so b/libcblite_community/lib/i686-linux-android/libcblite.so new file mode 100644 index 0000000..6618448 Binary files /dev/null and b/libcblite_community/lib/i686-linux-android/libcblite.so differ diff --git a/libcblite_community/lib/i686-linux-android/libcblite.stripped.so b/libcblite_community/lib/i686-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..c36bbb9 Binary files /dev/null and b/libcblite_community/lib/i686-linux-android/libcblite.stripped.so differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/Info.plist b/libcblite_community/lib/ios/CouchbaseLite.xcframework/Info.plist new file mode 100644 index 0000000..15c418a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/Info.plist @@ -0,0 +1,44 @@ + + + + + AvailableLibraries + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + CouchbaseLite.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64 + LibraryPath + CouchbaseLite.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite new file mode 100755 index 0000000..0b6db8e Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h new file mode 100644 index 0000000..d7866eb --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include +#include +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h new file mode 100644 index 0000000..a2d6eaa --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..35941b5 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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 +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; /// +#include + +CBL_CAPI_BEGIN + +/** \defgroup database Database + @{ + A \ref CBLDatabase is both a filesystem object and a container for documents. + */ + +#ifdef COUCHBASE_ENTERPRISE + +#ifdef __APPLE__ +#pragma mark - Database Extension +#endif + +/** \name Database Extension + @{ */ + +/** ENTERPRISE EDITION ONLY + + Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @param outError On return, will be set to the error that occurred. + @return True on success, false if there was an error. + @note Must be called before opening a database that intends to use the vector search extension. */ +bool CBL_EnableVectorSearch(FLString path, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +#ifdef __APPLE__ +#pragma mark - CONFIGURATION +#endif + +/** \name Database configuration + @{ */ + +#ifdef COUCHBASE_ENTERPRISE +/** Database encryption algorithms (available only in the Enterprise Edition). */ +typedef CBL_ENUM(uint32_t, CBLEncryptionAlgorithm) { + kCBLEncryptionNone = 0, ///< No encryption (default) + kCBLEncryptionAES256 ///< AES with 256-bit key +}; + +/** Encryption key sizes (in bytes). */ +typedef CBL_ENUM(uint64_t, CBLEncryptionKeySize) { + kCBLEncryptionKeySizeAES256 = 32, ///< Key size for \ref kCBLEncryptionAES256 +}; + +/** Encryption key specified in a \ref CBLDatabaseConfiguration. */ +typedef struct { + CBLEncryptionAlgorithm algorithm; ///< Encryption algorithm + uint8_t bytes[32]; ///< Raw key data +} CBLEncryptionKey; +#endif + +/** Database configuration options. */ +typedef struct { + FLString directory; ///< The parent directory of the database +#ifdef COUCHBASE_ENTERPRISE + CBLEncryptionKey encryptionKey; ///< The database's encryption key (if any) +#endif + /** As Couchbase Lite normally configures its databases, There is a very + small (though non-zero) chance that a power failure at just the wrong + time could cause the most recently committed transaction's changes to + be lost. This would cause the database to appear as it did immediately + before that transaction. + + Setting this mode true ensures that an operating system crash or + power failure will not cause the loss of any data. FULL synchronous + is very safe but it is also dramatically slower. */ + bool fullSync; + + /** + Disable memory-mapped I/O. By default, memory-mapped I/O is enabled. + Disabling it may affect database performance. Typically, there is no need to modify this setting. + @note Memory-mapped I/O is always disabled on macOS to prevent database corruption, + so setting mmapDisabled value has no effect on the macOS platform. */ + bool mmapDisabled; +} CBLDatabaseConfiguration; + +/** Returns the default database configuration. */ +CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Derives an encryption key from a password. If your UI uses passwords, call this function to + create the key used to encrypt the database. It is designed for security, and deliberately + runs slowly to make brute-force attacks impractical. + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPassword(CBLEncryptionKey *key, FLString password) CBLAPI; + +/** VOLATILE API: Derives an encryption key from a password in a way that is + compatible with certain variants of Couchbase Lite in which a slightly different + hashing algorithm is used. The same notes apply as in CBLEncryptionKey_FromPassword + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPasswordOld(CBLEncryptionKey *key, FLString password) CBLAPI; +#endif + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - FILE OPERATIONS +#endif +/** \name Database file operations + @{ + These functions operate on database files without opening them. + */ + +/** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ +bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; + +/** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On return, will be set to the error that occurred, if applicable. + @note While a database is open, one or more of its files may be in use. Attempting to copy a file, while it is in use, will fail. We recommend that you close a database before attempting to copy it. */ +bool CBL_CopyDatabase(FLString fromPath, + FLString toName, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a database file. If the database file is open, an error is returned. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. + @param outError On return, will be set to the error that occurred, or a 0 code if no error. + @return True if the database was deleted, false if it doesn't exist or deletion failed. + (You can tell the last two cases apart by looking at \p outError.)*/ +bool CBL_DeleteDatabase(FLString name, + FLString inDirectory, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - LIFECYCLE +#endif +/** \name Database lifecycle + @{ + Opening, closing, and managing open databases. + */ + +/** Opens a database, or creates it if it doesn't exist yet, returning a new \ref CBLDatabase + instance. + It's OK to open the same database file multiple times. Each \ref CBLDatabase instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On failure, the error will be written here. + @return The new database object, or NULL on failure. */ +_cbl_warn_unused +CBLDatabase* _cbl_nullable CBLDatabase_Open(FLSlice name, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Closes an open database. */ +bool CBLDatabase_Close(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDatabase*, Database); + +/** Closes and deletes a database. If there are any other connections to the database, + an error is returned. */ +bool CBLDatabase_Delete(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Begins a transaction. You **must** later call \ref + CBLDatabase_EndTransaction to commit or abort the transaction. + @note Multiple writes are much faster when grouped in a transaction. + @note Changes will not be visible to other CBLDatabase instances on the same database until + the transaction ends. + @note Transactions can nest. Changes are not committed until the outer transaction ends. */ +bool CBLDatabase_BeginTransaction(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Ends a transaction, either committing or aborting. */ +bool CBLDatabase_EndTransaction(CBLDatabase*, + bool commit, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Encrypts or decrypts a database, or changes its encryption key. + + If \p newKey is NULL, or its \p algorithm is \ref kCBLEncryptionNone, the database will be decrypted. + Otherwise the database will be encrypted with that key; if it was already encrypted, it will be + re-encrypted with the new key.*/ +bool CBLDatabase_ChangeEncryptionKey(CBLDatabase*, + const CBLEncryptionKey* _cbl_nullable newKey, + CBLError* outError) CBLAPI; +#endif + +/** Maintenance Type used when performing database maintenance. */ +typedef CBL_ENUM(uint32_t, CBLMaintenanceType) { + /// Compact the database file and delete unused attachments + kCBLMaintenanceTypeCompact = 0, + + /// Rebuild the entire database's indexes. + kCBLMaintenanceTypeReindex, + + /// Check for the database’s corruption. If found, an error will be returned + kCBLMaintenanceTypeIntegrityCheck, + + /// Partially scan indexes to gather database statistics that help optimize queries. + /// This operation is also performed automatically when closing the database. + kCBLMaintenanceTypeOptimize, + + /// Fully scans all indexes to gather database statistics that help optimize queries. + /// This may take some time, depending on the size of the indexes, but it doesn't have to + /// be redone unless the database changes drastically, or new indexes are created. + kCBLMaintenanceTypeFullOptimize +}; + +/** Performs database maintenance. */ +bool CBLDatabase_PerformMaintenance(CBLDatabase* db, + CBLMaintenanceType type, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - ACCESSORS +#endif +/** \name Database accessors + @{ + Getting information about a database. + */ + +/** Returns the database's name. */ +FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; + +/** Returns the database's full filesystem path, or null slice if the database is closed or deleted. */ +_cbl_warn_unused +FLStringResult CBLDatabase_Path(const CBLDatabase*) CBLAPI; + +/** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d1c39a9 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h new file mode 100644 index 0000000..c42809b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h new file mode 100644 index 0000000..4665b9a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h new file mode 100644 index 0000000..2c2c1b9 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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 + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h new file mode 100644 index 0000000..8032b5a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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 + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h new file mode 100644 index 0000000..625e736 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h new file mode 100644 index 0000000..321b424 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h new file mode 100644 index 0000000..79bed5a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h new file mode 100644 index 0000000..b26350e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h new file mode 100644 index 0000000..25ad9aa --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h new file mode 100644 index 0000000..1c61c87 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + +CBL_CAPI_BEGIN + +/** \defgroup scope Scope + @{ + A \ref CBLScope represents a scope or namespace of the collections. + + The scope implicitly exists when there is at least one collection created under the scope. + The default scope is exceptional in that it will always exists even there are no collections + under it. + + ## `CBLScope` Lifespan + `CBLScope` is ref-counted. Same as the CBLCollection, the CBLScope objects + retrieved from the database must be released after you are done using them. + When the database is closed or released, the scope objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with + \ref kCBLErrorNotOpen error result. */ + +CBL_REFCOUNTED(CBLScope*, Scope); + +/** \name Default Scope Name + @{ + The default scope name constant. + */ + +/** The default scope's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultScopeName; + +/** @} */ + +/** \name Scope Accessors + @{ + Getting information about a scope. + */ + +/** Returns the name of the scope. + @param scope The scope. + @return The name of the scope. */ +FLString CBLScope_Name(const CBLScope* scope) CBLAPI; + +/** Returns the scope's database. + @note The database object is owned by the scope object; you do not need to release it. + @param scope The scope. + @return The database of the scope. */ +CBLDatabase* CBLScope_Database(const CBLScope* scope) CBLAPI; + +/** @} */ + +/** \name Collections + @{ + Accessing the collections under the scope. + */ + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param scope The scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLScope_CollectionNames(const CBLScope* scope, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing collection in the scope with the given name. + @note You are responsible for releasing the returned collection. + @param scope The scope. + @param collectionName The name of the collection. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLScope_Collection(const CBLScope* scope, + FLString collectionName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h new file mode 100644 index 0000000..0612778 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -0,0 +1,134 @@ +// +// CBL_Compat.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +#ifdef _MSC_VER + #include + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h new file mode 100644 index 0000000..2aa2d6e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +/* #undef COUCHBASE_ENTERPRISE */ +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:30:53Z" diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h new file mode 100644 index 0000000..bce263b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h new file mode 100644 index 0000000..5b57154 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..5e2489e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h new file mode 100644 index 0000000..d1699bf --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..49f4747 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7ce213e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..9dd697f --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..677d3e4 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..9ed12e3 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..1072e64 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h new file mode 100644 index 0000000..9713584 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h new file mode 100644 index 0000000..874172f --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h new file mode 100644 index 0000000..ce14e29 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h new file mode 100644 index 0000000..6476347 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include +#endif + +#endif // _FLEECE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist new file mode 100644 index 0000000..9ae8222 Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap new file mode 100644 index 0000000..42fd88e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap @@ -0,0 +1,38 @@ +framework module CouchbaseLite { + header "CouchbaseLite.h" + header "CBL_Compat.h" + header "CBL_Edition.h" + header "CBLBase.h" + header "CBLBlob.h" + header "CBLCollection.h" + header "CBLDatabase.h" + header "CBLDefaults.h" + header "CBLDocument.h" + header "CBLEncryptable.h" + header "CBLLog.h" + header "CBLPlatform.h" + header "CBLPrediction.h" + header "CBLQuery.h" + header "CBLQueryIndex.h" + header "CBLQueryIndexTypes.h" + header "CBLQueryTypes.h" + header "CBLReplicator.h" + header "CBLScope.h" + + module Fleece { + header "Fleece.h" + header "FLBase.h" + header "FLCollections.h" + header "FLDeepIterator.h" + header "FLDoc.h" + header "Fleece+CoreFoundation.h" + header "FLEncoder.h" + header "FLExpert.h" + header "FLJSON.h" + header "FLKeyPath.h" + header "FLMutable.h" + header "FLSlice.h" + header "FLValue.h" + header "CompilerSupport.h" + } +} diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..6cb5e91 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist new file mode 100644 index 0000000..dedf43b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.com.couchbase.CouchbaseLite-C + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 3.2.1 + CFBundleVersion + 9 + + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite new file mode 100644 index 0000000..a12b198 Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite new file mode 100755 index 0000000..2e8e2eb Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h new file mode 100644 index 0000000..d7866eb --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include +#include +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h new file mode 100644 index 0000000..a2d6eaa --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..35941b5 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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 +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; /// +#include + +CBL_CAPI_BEGIN + +/** \defgroup database Database + @{ + A \ref CBLDatabase is both a filesystem object and a container for documents. + */ + +#ifdef COUCHBASE_ENTERPRISE + +#ifdef __APPLE__ +#pragma mark - Database Extension +#endif + +/** \name Database Extension + @{ */ + +/** ENTERPRISE EDITION ONLY + + Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @param outError On return, will be set to the error that occurred. + @return True on success, false if there was an error. + @note Must be called before opening a database that intends to use the vector search extension. */ +bool CBL_EnableVectorSearch(FLString path, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +#ifdef __APPLE__ +#pragma mark - CONFIGURATION +#endif + +/** \name Database configuration + @{ */ + +#ifdef COUCHBASE_ENTERPRISE +/** Database encryption algorithms (available only in the Enterprise Edition). */ +typedef CBL_ENUM(uint32_t, CBLEncryptionAlgorithm) { + kCBLEncryptionNone = 0, ///< No encryption (default) + kCBLEncryptionAES256 ///< AES with 256-bit key +}; + +/** Encryption key sizes (in bytes). */ +typedef CBL_ENUM(uint64_t, CBLEncryptionKeySize) { + kCBLEncryptionKeySizeAES256 = 32, ///< Key size for \ref kCBLEncryptionAES256 +}; + +/** Encryption key specified in a \ref CBLDatabaseConfiguration. */ +typedef struct { + CBLEncryptionAlgorithm algorithm; ///< Encryption algorithm + uint8_t bytes[32]; ///< Raw key data +} CBLEncryptionKey; +#endif + +/** Database configuration options. */ +typedef struct { + FLString directory; ///< The parent directory of the database +#ifdef COUCHBASE_ENTERPRISE + CBLEncryptionKey encryptionKey; ///< The database's encryption key (if any) +#endif + /** As Couchbase Lite normally configures its databases, There is a very + small (though non-zero) chance that a power failure at just the wrong + time could cause the most recently committed transaction's changes to + be lost. This would cause the database to appear as it did immediately + before that transaction. + + Setting this mode true ensures that an operating system crash or + power failure will not cause the loss of any data. FULL synchronous + is very safe but it is also dramatically slower. */ + bool fullSync; + + /** + Disable memory-mapped I/O. By default, memory-mapped I/O is enabled. + Disabling it may affect database performance. Typically, there is no need to modify this setting. + @note Memory-mapped I/O is always disabled on macOS to prevent database corruption, + so setting mmapDisabled value has no effect on the macOS platform. */ + bool mmapDisabled; +} CBLDatabaseConfiguration; + +/** Returns the default database configuration. */ +CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Derives an encryption key from a password. If your UI uses passwords, call this function to + create the key used to encrypt the database. It is designed for security, and deliberately + runs slowly to make brute-force attacks impractical. + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPassword(CBLEncryptionKey *key, FLString password) CBLAPI; + +/** VOLATILE API: Derives an encryption key from a password in a way that is + compatible with certain variants of Couchbase Lite in which a slightly different + hashing algorithm is used. The same notes apply as in CBLEncryptionKey_FromPassword + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPasswordOld(CBLEncryptionKey *key, FLString password) CBLAPI; +#endif + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - FILE OPERATIONS +#endif +/** \name Database file operations + @{ + These functions operate on database files without opening them. + */ + +/** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ +bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; + +/** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On return, will be set to the error that occurred, if applicable. + @note While a database is open, one or more of its files may be in use. Attempting to copy a file, while it is in use, will fail. We recommend that you close a database before attempting to copy it. */ +bool CBL_CopyDatabase(FLString fromPath, + FLString toName, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a database file. If the database file is open, an error is returned. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. + @param outError On return, will be set to the error that occurred, or a 0 code if no error. + @return True if the database was deleted, false if it doesn't exist or deletion failed. + (You can tell the last two cases apart by looking at \p outError.)*/ +bool CBL_DeleteDatabase(FLString name, + FLString inDirectory, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - LIFECYCLE +#endif +/** \name Database lifecycle + @{ + Opening, closing, and managing open databases. + */ + +/** Opens a database, or creates it if it doesn't exist yet, returning a new \ref CBLDatabase + instance. + It's OK to open the same database file multiple times. Each \ref CBLDatabase instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On failure, the error will be written here. + @return The new database object, or NULL on failure. */ +_cbl_warn_unused +CBLDatabase* _cbl_nullable CBLDatabase_Open(FLSlice name, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Closes an open database. */ +bool CBLDatabase_Close(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDatabase*, Database); + +/** Closes and deletes a database. If there are any other connections to the database, + an error is returned. */ +bool CBLDatabase_Delete(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Begins a transaction. You **must** later call \ref + CBLDatabase_EndTransaction to commit or abort the transaction. + @note Multiple writes are much faster when grouped in a transaction. + @note Changes will not be visible to other CBLDatabase instances on the same database until + the transaction ends. + @note Transactions can nest. Changes are not committed until the outer transaction ends. */ +bool CBLDatabase_BeginTransaction(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Ends a transaction, either committing or aborting. */ +bool CBLDatabase_EndTransaction(CBLDatabase*, + bool commit, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Encrypts or decrypts a database, or changes its encryption key. + + If \p newKey is NULL, or its \p algorithm is \ref kCBLEncryptionNone, the database will be decrypted. + Otherwise the database will be encrypted with that key; if it was already encrypted, it will be + re-encrypted with the new key.*/ +bool CBLDatabase_ChangeEncryptionKey(CBLDatabase*, + const CBLEncryptionKey* _cbl_nullable newKey, + CBLError* outError) CBLAPI; +#endif + +/** Maintenance Type used when performing database maintenance. */ +typedef CBL_ENUM(uint32_t, CBLMaintenanceType) { + /// Compact the database file and delete unused attachments + kCBLMaintenanceTypeCompact = 0, + + /// Rebuild the entire database's indexes. + kCBLMaintenanceTypeReindex, + + /// Check for the database’s corruption. If found, an error will be returned + kCBLMaintenanceTypeIntegrityCheck, + + /// Partially scan indexes to gather database statistics that help optimize queries. + /// This operation is also performed automatically when closing the database. + kCBLMaintenanceTypeOptimize, + + /// Fully scans all indexes to gather database statistics that help optimize queries. + /// This may take some time, depending on the size of the indexes, but it doesn't have to + /// be redone unless the database changes drastically, or new indexes are created. + kCBLMaintenanceTypeFullOptimize +}; + +/** Performs database maintenance. */ +bool CBLDatabase_PerformMaintenance(CBLDatabase* db, + CBLMaintenanceType type, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - ACCESSORS +#endif +/** \name Database accessors + @{ + Getting information about a database. + */ + +/** Returns the database's name. */ +FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; + +/** Returns the database's full filesystem path, or null slice if the database is closed or deleted. */ +_cbl_warn_unused +FLStringResult CBLDatabase_Path(const CBLDatabase*) CBLAPI; + +/** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d1c39a9 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h new file mode 100644 index 0000000..c42809b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h new file mode 100644 index 0000000..4665b9a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h new file mode 100644 index 0000000..2c2c1b9 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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 + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h new file mode 100644 index 0000000..8032b5a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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 + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h new file mode 100644 index 0000000..625e736 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h new file mode 100644 index 0000000..321b424 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h new file mode 100644 index 0000000..79bed5a --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h new file mode 100644 index 0000000..b26350e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h new file mode 100644 index 0000000..25ad9aa --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h new file mode 100644 index 0000000..1c61c87 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + +CBL_CAPI_BEGIN + +/** \defgroup scope Scope + @{ + A \ref CBLScope represents a scope or namespace of the collections. + + The scope implicitly exists when there is at least one collection created under the scope. + The default scope is exceptional in that it will always exists even there are no collections + under it. + + ## `CBLScope` Lifespan + `CBLScope` is ref-counted. Same as the CBLCollection, the CBLScope objects + retrieved from the database must be released after you are done using them. + When the database is closed or released, the scope objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with + \ref kCBLErrorNotOpen error result. */ + +CBL_REFCOUNTED(CBLScope*, Scope); + +/** \name Default Scope Name + @{ + The default scope name constant. + */ + +/** The default scope's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultScopeName; + +/** @} */ + +/** \name Scope Accessors + @{ + Getting information about a scope. + */ + +/** Returns the name of the scope. + @param scope The scope. + @return The name of the scope. */ +FLString CBLScope_Name(const CBLScope* scope) CBLAPI; + +/** Returns the scope's database. + @note The database object is owned by the scope object; you do not need to release it. + @param scope The scope. + @return The database of the scope. */ +CBLDatabase* CBLScope_Database(const CBLScope* scope) CBLAPI; + +/** @} */ + +/** \name Collections + @{ + Accessing the collections under the scope. + */ + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param scope The scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLScope_CollectionNames(const CBLScope* scope, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing collection in the scope with the given name. + @note You are responsible for releasing the returned collection. + @param scope The scope. + @param collectionName The name of the collection. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLScope_Collection(const CBLScope* scope, + FLString collectionName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h new file mode 100644 index 0000000..0612778 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -0,0 +1,134 @@ +// +// CBL_Compat.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +#ifdef _MSC_VER + #include + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h new file mode 100644 index 0000000..0eecf75 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +/* #undef COUCHBASE_ENTERPRISE */ +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:28:02Z" diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h new file mode 100644 index 0000000..bce263b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h new file mode 100644 index 0000000..5b57154 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..5e2489e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h new file mode 100644 index 0000000..d1699bf --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..49f4747 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7ce213e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..9dd697f --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..677d3e4 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..9ed12e3 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..1072e64 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h new file mode 100644 index 0000000..9713584 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h new file mode 100644 index 0000000..874172f --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h new file mode 100644 index 0000000..ce14e29 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h new file mode 100644 index 0000000..6476347 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include +#endif + +#endif // _FLEECE_H diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist new file mode 100644 index 0000000..27fb217 Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap new file mode 100644 index 0000000..42fd88e --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap @@ -0,0 +1,38 @@ +framework module CouchbaseLite { + header "CouchbaseLite.h" + header "CBL_Compat.h" + header "CBL_Edition.h" + header "CBLBase.h" + header "CBLBlob.h" + header "CBLCollection.h" + header "CBLDatabase.h" + header "CBLDefaults.h" + header "CBLDocument.h" + header "CBLEncryptable.h" + header "CBLLog.h" + header "CBLPlatform.h" + header "CBLPrediction.h" + header "CBLQuery.h" + header "CBLQueryIndex.h" + header "CBLQueryIndexTypes.h" + header "CBLQueryTypes.h" + header "CBLReplicator.h" + header "CBLScope.h" + + module Fleece { + header "Fleece.h" + header "FLBase.h" + header "FLCollections.h" + header "FLDeepIterator.h" + header "FLDoc.h" + header "Fleece+CoreFoundation.h" + header "FLEncoder.h" + header "FLExpert.h" + header "FLJSON.h" + header "FLKeyPath.h" + header "FLMutable.h" + header "FLSlice.h" + header "FLValue.h" + header "CompilerSupport.h" + } +} diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..6cb5e91 --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist new file mode 100644 index 0000000..dedf43b --- /dev/null +++ b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.com.couchbase.CouchbaseLite-C + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 3.2.1 + CFBundleVersion + 9 + + diff --git a/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite new file mode 100644 index 0000000..b46c048 Binary files /dev/null and b/libcblite_community/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite_community/lib/macos/libcblite.3.dylib b/libcblite_community/lib/macos/libcblite.3.dylib new file mode 100755 index 0000000..c435684 Binary files /dev/null and b/libcblite_community/lib/macos/libcblite.3.dylib differ diff --git a/libcblite_community/lib/x86_64-linux-android/libcblite.so b/libcblite_community/lib/x86_64-linux-android/libcblite.so new file mode 100644 index 0000000..226f5eb Binary files /dev/null and b/libcblite_community/lib/x86_64-linux-android/libcblite.so differ diff --git a/libcblite_community/lib/x86_64-linux-android/libcblite.stripped.so b/libcblite_community/lib/x86_64-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..144e8e6 Binary files /dev/null and b/libcblite_community/lib/x86_64-linux-android/libcblite.stripped.so differ diff --git a/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.dll b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.dll new file mode 100644 index 0000000..6d08934 Binary files /dev/null and b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.dll differ diff --git a/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.lib b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.lib new file mode 100644 index 0000000..8973598 Binary files /dev/null and b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.lib differ diff --git a/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.stripped.dll b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.stripped.dll new file mode 100755 index 0000000..061c719 Binary files /dev/null and b/libcblite_community/lib/x86_64-pc-windows-gnu/cblite.stripped.dll differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libcblite.so.3 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libcblite.so.3 new file mode 100644 index 0000000..f1b9a2c Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libcblite.so.3 differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libicudata.so.66 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicudata.so.66 new file mode 100644 index 0000000..b7392d4 Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicudata.so.66 differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 new file mode 100644 index 0000000..c8d5c4f Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuio.so.66 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuio.so.66 new file mode 100644 index 0000000..28161da Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuio.so.66 differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libicutu.so.66 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicutu.so.66 new file mode 100644 index 0000000..44c0f1e Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicutu.so.66 differ diff --git a/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 new file mode 100644 index 0000000..c4d8625 Binary files /dev/null and b/libcblite_community/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 differ diff --git a/libcblite_enterprise/LICENSE.txt b/libcblite_enterprise/LICENSE.txt new file mode 100644 index 0000000..e829534 --- /dev/null +++ b/libcblite_enterprise/LICENSE.txt @@ -0,0 +1,799 @@ +COUCHBASE, INC. LICENSE AGREEMENT +IMPORTANT--READ CAREFULLY: BY CLICKING THE "I ACCEPT" BOX OR INSTALLING, +DOWNLOADING OR OTHERWISE USING THE SOFTWARE AND ANY ASSOCIATED +DOCUMENTATION, YOU, ON BEHALF OF YOURSELF AND/OR AS AN AUTHORIZED +REPRESENTATIVE ON BEHALF OF AN ENTITY (COLLECTIVELY, "CUSTOMER"), +AGREE TO ALL THE TERMS OF THIS LICENSE AGREEMENT AND, IF APPLICABLE, +THE NON-GA OFFERING SUPPLEMENTAL TERMS (COLLECTIVELY, THE "AGREEMENT") +REGARDING CUSTOMER'S USE OF THE SOFTWARE. YOU REPRESENT AND WARRANT THAT +YOU HAVE FULL LEGAL AUTHORITY TO BIND CUSTOMER TO THIS AGREEMENT. IF +YOU DO NOT AGREE WITH ALL OF THESE TERMS, DO NOT SELECT THE "I ACCEPT" +BOX AND DO NOT INSTALL, DOWNLOAD OR OTHERWISE USE THE SOFTWARE. THE +EFFECTIVE DATE OF THIS AGREEMENT IS THE DATE ON WHICH YOU CLICK "I ACCEPT" +OR OTHERWISE INSTALL, DOWNLOAD OR USE THE SOFTWARE. + + +1. Definitions. + 1.1 Capitalized terms used herein shall have the following definitions: + "Commercial Details" means the identified products and/or services, + quantity (number of Licensed Nodes, Licensed Devices, and/or service + entitlements), price, server size, support level, subscription start + and end date, and Professional Services description. + "Core" means the virtual representation of one or more hardware + threads. A hardware thread can be either a physical core or a + hyper-threaded core. + "Cross-Data Center Replication" means an asynchronous data replication + system, involving replicating active data to multiple, geographically + diverse data centers or data repositories. + "Customer" means the person, legal entity or organization, as + applicable, accepting the terms and conditions hereunder and/or + entering into an Order that references this Agreement. + "Deployment" means all Licensed Nodes and Licensed Devices within + a particular workload or application. "Documentation" means the + technical user guides or manuals provided by Couchbase related to + the Software. + "Fees" means any sums, fees or charges specified on an Order or + otherwise payable under this Agreement. + "Licensed Device" means a unique device (such as a mobile device, + laptop, or IoT device) that stores data locally using the "Couchbase + Lite" product during a rolling thirty (30) day period. + "Licensed Node" means an instance of the Software running on a server, + including a physical server, server blade, virtual machine, software + container, or cloud server (whether in a testing, development, + production, or other environment). + "Order" means a transaction document (such as a signed sales quote or + statement of work) identifying the applicable Professional Services, + Software, number of Licensed Nodes and Licensed Devices, Fees and + Subscription Term. + "Privacy Notice" means the privacy notice located at + https://www.couchbase.com/privacy-policy (and any successor location + designated by Couchbase), as may be updated from time to time. + "Professional Services" means consulting services, training, + and other professional services as well as the resulting reports, + written materials, or other outputs provided to Customer as part of + an engagement as identified in the applicable Order. + "RAM" or Random Access Memory, means the main memory used to store + data for quick access by a computer's processor. + "Software" means the applicable Couchbase product either (i) + as reflected in an Order or (ii) as otherwise made available to + Customer under this Agreement. + "Subscription Term" means, as applicable: (i) the period stated + on an Order, if any, during which Customer is licensed to use the + Software and Documentation and receive the Professional Services (if + applicable) and Support; (ii) the first date an Enterprise License is + required (including before an Order is signed) until the date such + Enterprise License is either (a) memorialized in an Order (in which + case the definition of subsection (i) herein shall apply), or (b) + terminated in accordance with the terms herein; or (iii) the date + of download for a Free License until the date such Free License is + either (a) converted into an Enterprise License (in which case the + definitions of subsections (i) or (ii) shall apply, as applicable), + or (b) terminated in accordance with the terms herein. + "Support" means the technical support and Software maintenance + services (with the right to receive Software updates and upgrades made + generally available by Couchbase) as described in the then-current + Couchbase support services terms at www.couchbase.com/support-policy + (and any successor location designated by Couchbase), as may be + updated from time to time. + +The term "including" means including but not limited to. + +2. License Grants. + 2.1 License Grant as to Free Licenses. A "Free License" is allowed only + for development use and evaluation of the Software and is provided with + no Support or any other services. Couchbase is under no obligation to + provide or continue to provide the Free Licenses (including any update, + upgrade or new version of the Software licensed thereunder). During + the Subscription Term, and subject to Customer's compliance with the + terms and conditions of this Agreement, Couchbase grants to Customer a + revocable, unpaid, non-exclusive, non-transferable, non-sublicensable, + non-fee bearing download license to install and use the Software only + for Customer's own internal development use and evaluation of the + Software. Prior to using the Software for any other use (including + for testing, quality assurance, or in production), Customer agrees to + enter into an Order with Couchbase and pay the applicable Fees. If, + at any time, Customer uses the Software for any other use (including + for testing, quality assurance, or in production) without an active + Order, then (i) Customer acknowledges and agrees that its Free License + is automatically converted to an Enterprise License, (ii) Couchbase + shall have the right to audit and charge Customer for such use as set + forth in Section 8 herein, and (iii) Customer shall use best efforts to + enter into an Order with Couchbase for such use in order to remedy the + noncompliant use as soon as possible. Free Licenses granted to Customer + hereunder are revocable and terminable at any time in Couchbase's sole + and absolute discretion. + + 2.2 License Grant as to Enterprise Licenses. An "Enterprise License" + is required if Customer uses the Software (a) for testing, quality + assurance, or in production, (b) for any use other than solely + for internal development use or evaluation of the Software, or (c) + after Customer's initial request for Support. After Customer in the + first instance uses the Software for testing, quality assurance, + or in production, or converts to an Enterprise License otherwise, + then the Enterprise License terms of this Agreement (absent another + applicable enterprise agreement between the parties) shall apply. During + the Subscription Term, and subject to Customer's compliance with the + terms and conditions of this Agreement, Couchbase grants to Customer a + revocable, non-exclusive, non-transferable, non-sublicensable (except + as explicitly set forth herein), fee-bearing license to install and + use the Software and Documentation only for Customer's own internal + use and limited to the type, size, and number of Licensed Nodes and + Licensed Devices paid for by Customer and in accordance with any + additional license terms specified in the applicable Order, and for + no other purposes whatsoever. + + 2.3 Tools, Connectors, and Third Party Products. The Software may: + (i) include certain components developed and owned by Couchbase + ("Couchbase Components") which connect to products, components, files, + programs, databases, content sources or other materials developed and + owned by third parties ("Third Party Products"); and (ii) include or + be distributed with Third Party Products. Customer's use of Couchbase + Components and Third Party Products may be subject to additional terms + and conditions and third party license terms, including as set forth + in Exhibit A of this Agreement. Further, Third Party Products may be + subject to third party licenses provided by such third party or executed + between Customer and such third party (in each case, a "Third Party + License"). Couchbase has not developed or published and does not own, + control or license such Third Party Products. Customer shall be solely + responsible for (i) its compliance with any such Third Party License + in its use of any Third Party Products and (ii) the confidentiality, + security, and integrity of any content or data Customer chooses + to transfer to any Third Party Products. Couchbase shall have no + responsibility or liability whatsoever for the installation, operation, + or support functionality of, or otherwise related to or arising out + of any Third Party Products, including any loss or compromise of data. + +3. Customer Responsibilities. + 3.1 Customer shall not (and shall not allow any third party to): + (a) copy or use the Software, Documentation, or any related reports, + technologies or services in any manner except as expressly permitted + in this Agreement; + (b) for Enterprise Licenses, use or deploy the Software in excess of + the number of Licensed Nodes and Licensed Devices for which Customer + has paid the applicable Fees; + (c) for Enterprise Licenses, use or deploy the Software in excess + of the number of Cores and RAM for each Licensed Node for which + Customer has paid the applicable Fees; + (d) transfer, sell, rent, lease, lend, distribute, market, + commercialize or sublicense the Software, Documentation, or any + related reports, technologies or services to any third party, + provided that Customer may use the Software in connection with an + application made available to Customer's end users as long as they + cannot access the Software directly; + (e) use the Software for providing time-sharing services, service + bureau services or as part of an application services provider or + as a service offering primarily designed to offer the functionality + of the Software; + (f) reverse engineer, disassemble, or decompile the Software (except + to the extent such restrictions are prohibited); + (g) alter, modify, enhance or prepare any derivative work from or + of the Software and Documentation; + (h) alter or remove any proprietary notices in the Software, + Documentation or any related reports, technologies or services; + (i) for Enterprise Licenses, use or transfer Licensed Nodes and/or + Licensed Devices designated to a particular Deployment or project + to another or new Deployment or project; or + (j) use the Software, Documentation or any related reports, + technologies or services for the purposes of, or publicly display or + communicate the results of, benchmarking or competitive analysis of + the Software, or developing, using, providing, or supporting products + or services competitive to Couchbase. + + 3.2 Customer understands that the Software, Documentation, and any + related technology or services are subject to U.S. export control + laws and regulations. Customer shall comply with all applicable + laws in connection with its use of the Software, Documentation, + Professional Services and Support, including but not limited to + applicable international and domestic export controls, including + economic sanctions, laws, regulations, or orders that apply to Customer, + the Software the Documentation and any related reports, technologies + or services ("Export Laws"). In furtherance of this obligation, + Customer shall ensure that: (a) Customer does not use the Software, + technology or services in violation of any Export Laws; and (b) it + does not provide access to the Software, technology or services to + (i) persons on the U.S. Department of Commerce's Denied Persons List + or Entity List, or the U.S. Treasury Department's list of Specially + Designated Nationals, (ii) military end-users or for military end-use, + or (iii) parties engaged in activities directly or indirectly related + to the proliferation of weapons of mass destruction. + + 3.3 If Customer does not comply with the license terms or the foregoing + restrictions, Couchbase may (without refund or credit, if applicable, + and without prejudice to any other rights or remedies Couchbase + may have under this Agreement or at law), at its sole discretion: + (i) terminate this Agreement (including all active Orders hereunder) + thereby revoking Customer's Free and/or Enterprise License(s) to the + Software and Documentation, or (ii) suspend Customer's Free and/or + Enterprise License(s) to the Software and Documentation until Customer + comes into compliance with such terms and restrictions. + + 3.4 Customer acknowledges that a breach of its obligations to Couchbase + under this Agreement, other than the payment obligations, will result + in irreparable and continuing damage for which monetary damages may not + be sufficient, and agrees that Couchbase will be entitled to receive + in addition to its other rights and remedies hereunder or at law, + injunctive and/or other equitable relief. All remedies of Couchbase + set forth in this Agreement are cumulative and in addition to, and + not in lieu of any other remedy of Couchbase as law or in equity. + +4. Services. + 4.1 This entire Section 4 applies only to Enterprise Licenses fully + paid for by Customer and not to Free Licenses. + + 4.2 The parties may agree to have Couchbase provide Professional + Services to Customer, which shall be set forth on an Order signed + by both parties. Such Professional Services shall be governed by the + terms and conditions of this Agreement. + + 4.3 Professional Services and any related reports, technologies or + services are accepted when delivered unless otherwise set forth in an + Order. Couchbase may engage qualified subcontractors to provide the + Professional Services, provided that Couchbase remains responsible for + any subcontractor's compliance with this Agreement. Couchbase grants to + Customer a royalty-free, perpetual, non-exclusive, non-transferable, + non-sublicensable license to use and reproduce any reports for + Customer's internal business purposes. + + 4.4 Unless explicitly set forth in an Order, any Professional Services + purchased under this Agreement shall expire upon the end of the + Subscription Term (up to and including any expiration date) or after + twelve (12) months if no expiration date is specified (in each case, + the "Services Expiration Date"). Any unused Professional Services + after such Services Expiration Date shall expire without refund + of any prepaid Fees. For Professional Services that would have been + invoiceable in arrears, Couchbase will provide a final invoice for the + unused Professional Services in accordance with this Agreement. Unless + otherwise stated in an Order, Customer shall pay Couchbase's reasonable + travel and incidental expenses incurred in conducting (in relation to + the Professional Services or otherwise) on-site activities at Customer's + site upon receiving an invoice from Couchbase. + +5. Proprietary Rights. + 5.1 This Agreement does not transfer any right, title or interest + in any intellectual property to any party, except as expressly + set forth in this Agreement. The Software (including the source + code, any modifications, improvements, enhancements or derivatives + thereto), and all Documentation and outputs resulting from Professional + Services, are and shall remain the sole property of Couchbase and its + licensors. Except for the license rights granted under this Agreement, + Couchbase and its licensors retain all right, title and interest in and + to the Software, Documentation, and Professional Services (including + resulting reports or written materials), including all intellectual + property rights therein and thereto. + + 5.2 The Software may include open source software components and such + open source components shall be licensed to Customer under the terms of + the applicable open source license conditions and/or copyright notices + that can be found in the licenses files, Documentation or materials + accompanying the Software. + + 5.3 If Customer provides any suggestions or feedback regarding the + Software, Documentation, Support, or Professional Services, Couchbase + may use such information without obligation to Customer, and Customer + hereby irrevocably assigns to Couchbase all right, title, and interest + in that feedback or those suggestions. + + 5.4 If Customer is the United States Government or any contractor + thereof, all licenses granted hereunder are subject to the following: + (a) for acquisition by or on behalf of civil agencies, as necessary + to obtain protection as "commercial computer software" and related + documentation in accordance with the terms of this Agreement and as + specified in Subpart 12.1212 of the Federal Acquisition Regulation + (FAR), 48 C.F.R.12.1212, and its successors; and + (b) for acquisition by or on behalf of the Department of Defense + (DOD) and any agencies or units thereof, as necessary to obtain + protection as "commercial computer software" and related documentation + in accordance with the terms of this Agreement and as specified in + Subparts 227.7202-1 and 227.7202-3 of the DOD FAR Supplement, 48 + C.F.R.227.7202-1 and 227.7202-3, and its successors, manufacturer + is Couchbase, Inc. + +6. Support. + 6.1 This entire Section 6 applies only to Enterprise Licenses fully + paid for by Customer and not to Free Licenses. + + 6.2 Couchbase will provide Customer with the level of Support + indicated on the applicable Order and paid for by Customer. For all + Licensed Nodes and Licensed Devices within a specific Deployment, + all such nodes and instances must be at the same level of Support, + including any that are used for disaster recovery or backup that are + associated with the specific Deployment. For the avoidance of doubt, + each specific Deployment can have its own level of Support. + + 6.3 When using the Cross-Data Center Replication feature, Customer + must have all Licensed Nodes and Licensed Devices at the same level of + Support for all instances on all sides of the replication connection, + including if one side of the connection is only used for disaster + recovery or backup. + + 6.4 Couchbase may modify the terms of Support from time to time, + provided that such modifications do not materially and adversely affect + Customer's Support subscription. + +7. Fees. + 7.1 This Section 7 applies only to Enterprise Licenses fully paid for + by Customer and not to Free Licenses. + + 7.2 Customer will pay Couchbase the Fees in advance, within thirty (30) + days of the date of the invoice, unless otherwise explicitly indicated + in the applicable Order. If Customer purchases licenses or services + related to the Software through an approved third-party partner, + then the applicable agreement with that third-party will govern with + respect to Customer for the appropriate payment terms, provided that + such third-party agreement shall not override or attempt to override the + payment terms in place between Couchbase and such approved third-party + partner. All other terms and restrictions with respect to the use of + the Software shall continue to apply to Customer. All payments are + non-cancelable, not subject to the Limitation of Liability in Section + 12 below, and shall be made in the currency stated on the applicable + Order. Fees are non-refundable except to the extent expressly provided + for in this Agreement. Late payments will bear interest at the lesser + of one- and one-half percent (1 1/2 %) per month or the maximum rate + allowed by applicable law. Customer will reimburse Couchbase for all + reasonable costs and expenses incurred (including reasonable attorneys' + fees) in collecting any overdue amounts. + + 7.3 All Fees payable by Customer are exclusive of applicable taxes + and duties (such as, without limitation, VAT, Service Tax, GST, + excise taxes, sales and transactions taxes, and gross receipts tax + (collectively, the "Transaction Taxes"). If applicable, Couchbase may + charge and Customer shall pay all Transaction Taxes that Couchbase + is legally obligated or authorized to collect from Customer. Customer + will provide such information to Couchbase as reasonably required to + determine whether Couchbase is obligated to collect Transaction Taxes + from Customer. Couchbase will not collect, and Customer will not pay, + any Transaction Taxes for which Customer furnishes a properly completed + exemption certificate or a direct payment permit certificate for + which Couchbase may claim an available exemption from such Transaction + Taxes. All payments made by Customer to Couchbase under this Agreement + will be made free and clear of any deduction or withholding, as may + be required by law. If any such deduction or withholding (including + but not limited to cross-border withholding taxes) is required on any + payment, Customer will pay such additional amounts as are necessary so + that the net amount received by Couchbase is equal to the amount then + due and payable under this Agreement. Couchbase will provide Customer + with such tax forms as are reasonably requested in order to reduce + or eliminate the amount of any withholding or deduction for taxes in + respect of payments made under this Agreement. + + 7.4 Customer is obligated to pay all applicable Fees without any + requirement for Couchbase to provide a purchase order ("PO") number on + Couchbase's invoice (or otherwise). If Customer sends Couchbase a PO + in lieu of executing an Order, the PO will be deemed a binding contract + offer which Couchbase may accept by (i) signing the PO or (ii) sending + a written order acknowledgment of acceptance of the PO (thereby forming + a mutually agreed Order governed by this Agreement). In any event, + only the Commercial Details listed on PO shall be considered part of + the Order created (exclusive of any pre-printed terms on the PO). Any + other terms on the PO which either (i) conflict with the terms of this + Agreement, or (ii) are not agreed under this Agreement, will be void and + without effect, even if Couchbase signs the PO. All accepted POs will + automatically be governed by this Agreement (even if the PO does not + reference this Agreement). It is expressly agreed that Section 7 shall + apply in respect of any PO sent by Customer and accepted by Couchbase. + +8. Records Retention and Audit. + 8.1 During any Subscription Term and for at least one (1) year + thereafter, Customer shall maintain complete and accurate records to + permit Couchbase to verify Customer's compliance with this Agreement + (including the number of Licensed Nodes and Licensed Devices used + by Customer as well as Customer's compliance with its obligations + post-termination or expiration), and provide Couchbase with such + records within ten (10) days of request. + + 8.2 Every three (3) months within a Subscription Term (or on another + cadence as mutually agreed between the parties) or upon request by + Couchbase for any use requiring an Enterprise License where no Order + is in place, Customer shall self-certify to Couchbase the total number + of Licensed Nodes and Licensed Devices used in any production, test, + development, or other Deployment. Such self-certification shall + be in accordance with Couchbase's instruction and in the form of + either a (i) written report signed by an authorized representative of + Customer or (ii) copy of an automatically generated report created by + Customer. Couchbase will review such reports and determine if any true + up Order is required. Additional fees for any excess usage shall be + calculated based on the fees specified in the applicable Order for the + applicable Licensed Node or Licensed Device size and type, and prorated, + as applicable. If (i) the excess usage includes nodes or device sizes or + types for which fees are not specified in the applicable existing Order + or (ii) use requiring an Enterprise License occurred without an Order, + then the (additional) fees shall be calculated based on Couchbase's + list price in effect at the time and prorated, as applicable. + + 8.3 Upon at least thirty (30) days prior written notice, but no + more than once in any twelve (12) month period, Couchbase may audit + Customer's use of the Software solely as necessary to verify Customer's + compliance with the terms of this Agreement during the Subscription + Term and for one (1) year thereafter. Any such audit will be conducted + during regular business hours at Customer's facilities and will not + unreasonably interfere with Customer's business activities. Customer + will provide Couchbase with access to the relevant Customer records + and facilities. + +9. Confidentiality. + 9.1 Customer and Couchbase will maintain the confidentiality of + Confidential Information. "Confidential Information" means any + proprietary information received by the other party during, or prior to + entering into, this Agreement that a party should know is confidential + or proprietary based on the circumstances surrounding the disclosure, + including the Software and any non-public technical and business + information (including Commercial Details). Confidential Information + does not include information that (a) is or becomes generally known + to the public through no fault of or breach of this Agreement by the + receiving party; (b) is rightfully known by the receiving party at + the time of disclosure without an obligation of confidentiality to + the disclosing party; (c) is independently developed by the receiving + party without use of the disclosing party's Confidential Information; or + (d) the receiving party rightfully obtains from a third party without + restriction on use or disclosure. + + 9.2 The receiving party of any Confidential Information of the other + party agrees not to use such Confidential Information for any purpose + except as necessary to fulfill its obligations and exercise its rights + under this Agreement. The receiving party shall protect the secrecy + of and prevent any unauthorized disclosure or use of the disclosing + party's Confidential Information using the same degree of care that + it takes to protect its own confidential information and in no event + shall use less than reasonable care. + + 9.3 Upon termination of this Agreement, the receiving party will, at + the disclosing party's option, promptly return or destroy (and provide + written certification of such destruction) the disclosing party's + Confidential Information. A party may disclose the other party's + Confidential Information to the extent required by law or regulation. + +10. DISCLAIMER OF WARRANTY. +THE SOFTWARE, DOCUMENTATION AND ANY PROFESSIONAL SERVICES PROVIDED +HEREUNDER ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND INCLUDING +THAT THE SOFTWARE, DOCUMENTATION OR PROFESSIONAL SERVICES PROVIDED +HEREUNDER WILL MEET CUSTOMER'S REQUIREMENTS, OPERATE IN THE COMBINATIONS +CUSTOMER MAY SELECT FOR USE, WILL BE ERROR-FREE OR UNINTERRUPTED, OR +THAT ALL SOFTWARE ERRORS OR DEFECTS WILL BE CORRECTED. TO THE MAXIMUM +EXTENT PERMITTED BY APPLICABLE LAW, COUCHBASE, ANY OF ITS AFFILIATES OR +LICENSORS (COLLECTIVELY, THE "COUCHBASE PARTIES") HEREBY DISCLAIM ALL +WARRANTIES, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +NON-INFRINGEMENT, TITLE, AND ANY WARRANTIES ARISING OUT OF COURSE OF +DEALING, USAGE OR TRADE. THE COUCHBASE PARTIES DO NOT WARRANT THAT THE +SOFTWARE IS DESIGNED, MANUFACTURED, OR INTENDED FOR USE IN HAZARDOUS +ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE WHERE THE FAILURE OF THE +PRODUCT COULD LEAD TO DEATH, PERSONAL INJURY, OR SIGNIFICANT PHYSICAL +OR ENVIRONMENTAL DAMAGE. + +11. Indemnification of Third-Party Claims. + 11.1 Couchbase Indemnification. Subject to the terms of this Section + 11, Couchbase will indemnify and defend Customer from and against + any damages finally awarded against Customer resulting from any + third-party claims that the non-open source software components of + the Software, Documentation or Professional Services infringe any + valid, enforceable United States patent, United States copyright, + or United States trademark; provided that: (a) Customer promptly + notifies Couchbase of the claim; (b) Customer gives Couchbase all + necessary information regarding the claim and reasonably cooperates + with Couchbase; (c) Customer allows Couchbase exclusive control of the + defense and all related settlement negotiations; and (d) Customer does + not admit fault or liability with respect to this Agreement, any Order, + Customer's actions or those of Couchbase. + + 11.2 Enjoinment. Without limiting the forgoing, and notwithstanding + anything to the contrary in this Agreement, if use of the Software + is enjoined, or Couchbase determines that such use may be enjoined, + Couchbase will, at its sole option and expense, (i) procure for + Customer the right to continue using the affected Software; (ii) + replace or modify the affected Software such that it does not infringe; + or (iii) if either option (i) or (ii) is not commercially feasible in + Couchbase's reasonable opinion, as applicable, terminate the affected + portions of an Order and refund Customer any prepaid but unused Fees + for the affected Software. + + 11.3 Customer Indemnification. Customer will indemnify and defend + the Couchbase Parties from and against any damages awarded against + Couchbase in connection with any third-party claim arising out of (a) + Customer's use, operation or combination of the Software, including + Customer's data or content, that infringes any United States patent, + United States copyright or United States trademark; (b) use of, + or inability to use the Software by Customer, or any third party + that receives or obtains access to or relies on the Software or any + component thereof from or through (directly or indirectly) Customer; + and (c) any breach by Customer of any provisions of this Agreement, + provided that: (i) Couchbase promptly notifies Customer of the claim; + (ii) Couchbase gives Customer all necessary information regarding the + claim and reasonably cooperates with Customer; (iii) Couchbase allows + Customer exclusive control of the defense and all related settlement + negotiations; and (iv) Couchbase does not admit fault or liability + with respect to this Agreement, any Order, Couchbase's actions or + those of Customer. + + 11.4 Exclusions. Couchbase will have no liability or obligation to + indemnify under Section 11.1 for any infringement claim arising out of + (i) modifications made by a party other than Couchbase, to the extent + a claim would not have occurred but for such modifications, (ii) the + use of any non-current version of the Software provided that Couchbase + has given reasonable written notice to Customer to migrate to the + then-current version of the Software (unless the infringing portion is + also in the then-current, unaltered release), (iii) the use, operation + or combination of the Software with non-Couchbase programs, data, or + equipment to the extent such infringement would have been avoided but + for such use, operation or combination, (iv) any open source software + components, (v) use in violation of this Agreement or in non-compliance + with the applicable Documentation, (vi) Customer's continuation of its + allegedly infringing activity after being notified thereof or after + being provided a replacement or modification by Couchbase that would + have avoided the alleged infringement; or (vii) Couchbase's compliance + with any materials, designs, specifications or instructions provided + by Customer. The Couchbase indemnification obligations will also not + apply to any claim to the extent it arises from any matter for which + Customer is obligated to indemnify Couchbase pursuant to Section 11.3. + + 11.5 Sole Remedy. THE TERMS OF THIS SECTION 11 CONSTITUTE THE ENTIRE + LIABILITY OF THE COUCHBASE PARTIES, AND CUSTOMER'S SOLE AND EXCLUSIVE + REMEDY WITH RESPECT TO ANY THIRD-PARTY CLAIMS OF INFRINGEMENT OR + MISAPPROPRIATION OF INTELLECTUAL PROPERTY RIGHTS OF ANY KIND. + + 11.6 Applicability. Section 11, excluding 11.3 above, applies only to + Enterprise Licenses fully paid for by Customer and not to Free Licenses. + +12. LIMITATION OF LIABILITY. +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL THE +COUCHBASE PARTIES BE LIABLE TO CUSTOMER OR TO ANY THIRD PARTY FOR: (A) +ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES; +OR (B) THE COST OF PROCURING SUBSTITUTE PRODUCTS OR PROFESSIONAL +SERVICES ARISING OUT OF OR IN ANY WAY RELATING TO THIS AGREEMENT, +OR THE USE OF OR INABILITY TO USE THE SOFTWARE, DOCUMENTATION OR THE +PROFESSIONAL SERVICES; OR (C) DAMAGES OR OTHER LOSSES FOR LOSS OF USE, +LOSS OF BUSINESS, LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS +OF DATA, COMPUTER FAILURE OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR +LOSSES EVEN IF ADVISED OF THE POSSIBILITY THEREOF AND REGARDLESS OF +THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH +THE CLAIM IS BASED. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, +IN NO EVENT WILL THE COUCHBASE PARTIES' AGGREGATE LIABILITY TO CUSTOMER, +FROM ALL CAUSES OF ACTION AND UNDER ALL THEORIES OF LIABILITY, EXCEED THE +TOTAL AMOUNT OF FEES PAID OR DUE AND OWING UNDER THE APPLICABLE ORDER(S) +BY CUSTOMER TO COUCHBASE THAT ARE ATTRIBUTABLE TO THE ORDER GIVING RISE +TO THE LIABILITY IN THE TWELVE (12) MONTH PERIOD IMMEDIATELY PRECEDING THE +ACT OR OMISSION FIRST GIVING RISE TO THE LIABILITY. The parties expressly +acknowledge and agree that Couchbase has set its prices and entered into +this Agreement in reliance upon the limitations of liability specified +herein, which allocate the risk between Couchbase and Customer and form +a basis of the bargain between the parties. + +13. Term and Termination. + 13.1 This Agreement is effective as of the date of Customer's acceptance + of this Agreement (the "Effective Date") and will continue until: + (i) Customer ceases all use of the Software, or (ii) ninety (90) days + after all of Customer's active Orders hereunder have expired whether + either party gives notice or not, or (iii) either party terminates this + Agreement as set forth in this Section, provided that the parties' + rights and obligations under the provisions listed in Section 13.4 + shall survive any termination for all of the foregoing subsections + (i) through (iii). This Agreement shall govern: (i) Customer's Free + Licenses and/or Enterprise Licenses whether Customer has entered + into an Order or not, (ii) Orders that reference this Agreement, and + (iii) any POs submitted by Customer as set forth in Section 7.4. The + Subscription Term for each Order shall commence and have the duration + as set forth in the applicable Order. + + 13.2 Subject to Couchbase's rights under Section 3 above, either party + may terminate the applicable Order, if the other party materially + breaches its obligations thereunder and, where such breach is curable, + such breach remains uncured for thirty (30) days following written + notice of the breach. Customer's obligation to make a payment of + any outstanding, unpaid fees for any Enterprise License shall survive + termination or expiration of an Order or this Agreement. + + 13.3 Upon termination or expiration of all active Orders, any Enterprise + Licenses without an Order, and/or this Agreement, Customer will (i) + promptly pay any outstanding fees accrued for any Enterprise Licenses + or as determined under Section 8 hereof, (ii) promptly return or + destroy the Documentation (except as explicitly permitted to be + retained by Customer in an Order) and all copies and portions thereof, + in all forms and types of media, and (iii) uninstall the Software as + described in the then-current Couchbase uninstallation instructions + (located https://docs.couchbase.com/manual/uninstall/). Upon request, + Customer shall provide written certification signed by an officer + of Customer of cessation of use and destruction as set forth herein + within five (5) calendar days of request. + + 13.4 The following sections will survive termination or expiration + of any Order and/or this Agreement: Section 2.3 (Tools, Connectors, + and Third Party Products), Sections 3 (Customer Responsibilities), + 5 (Proprietary Rights), 7 (Fees), 8 (Records Retention and Audit), 9 + (Confidentiality), 10 (Disclaimer of Warranty), 11 (Indemnification + of Third-Party Claims), 12 (Limitation of Liability), 13 (Term and + Termination), and 14 (General). + +14. General. + 14.1 Neither party shall be liable for any delay or failure in + performance (except for any payment obligations by Customer) due to + causes beyond its reasonable control. + + 14.2 Customer agrees that Couchbase may include the Customer's name + and logo in client lists that Couchbase may publish for promotional + purposes from time to time and grants Couchbase a limited license to + its trademark solely for this purpose, provided that Couchbase complies + with Customer's branding guidelines. + + 14.3 Customer may not assign or transfer its rights or obligations under + this Agreement or an Order, in whole or in part, by operation of law or + otherwise, without Couchbase's prior written consent. Any attempt to + assign or otherwise transfer this Agreement or an Order without such + consent will be null and of no effect. Subject to the foregoing, + this Agreement will bind and inure to the benefit of each party's + successors and permitted assigns. + + 14.4 If for any reason a court of competent jurisdiction finds any + provision of this Agreement invalid or unenforceable, that provision + of this Agreement will be enforced to the maximum extent permissible + and the other provisions of this Agreement will remain in full force + and effect. The failure by either party to enforce any provision + of this Agreement will not constitute a waiver of future enforcement + of that or any other provision. All waivers must be in writing and + signed by both parties. + + 14.5 Any notice or communication provided by Couchbase under this + Agreement may be provided by posting a notice on the Couchbase website, + or by mail or email to the relevant address associated with Customer's + account, if available. Any notice or communication provided by Customer + to Couchbase under this Agreement shall be provided to Couchbase by + certified mail, return receipt requested, to Couchbase, Inc., Attn: + Legal Dept, 3250 Olcott Street, Santa Clara, CA 95054, United States, + with a copy emailed to legal@couchbase.com. + + 14.6 This Agreement shall be governed by the laws of the State of + California, U.S.A., excluding its conflicts of law rules. The parties + expressly agree that the UN Convention for the International Sale of + Goods will not apply. Any legal action or proceeding arising under + this Agreement will be brought exclusively in the federal or state + courts located in Santa Clara County, California and the parties + hereby irrevocably consent to the personal jurisdiction and venue + therein. Except as otherwise set forth in this Agreement, Couchbase + may modify this Agreement (including the Support terms) at any time + by (i) posting a revised version on the Couchbase website or (ii) + by otherwise notifying Customer in accordance with Section 14.5, + and by continuing to use the Software after the effective date of any + such modifications to this Agreement, Customer agrees to be bound by + this Agreement, as modified. The date Couchbase last modified this + Agreement is set forth at the end of this Agreement. Notwithstanding + the foregoing, any Orders placed under this version of the Agreement + may only be modified by a mutually signed amendment by the parties. + + 14.7 This Agreement incorporates the Privacy Notice by reference, + and together with each Order constitute the entire agreement and + understanding of the parties and supersedes all prior or contemporaneous + oral or written agreements regarding the subject matter hereof, + including any agreement on confidentiality previously executed by + the parties. Furthermore, no additional or conflicting terms set + forth on any other document shall have any force or effect and are + hereby rejected unless expressly agreed upon by the parties' duly + authorized representatives in writing. To the extent that any terms + and conditions set forth in an Order conflict with the terms of this + Agreement, the applicable terms of the Order shall prevail. + + 14.8 Except as expressly set forth in this Agreement, the exercise by + either party of any of its remedies under this Agreement will be without + prejudice to its other remedies under this Agreement or otherwise. + + 14.9 The parties to this Agreement are independent contractors and + this Agreement will not establish any relationship of partnership, + joint venture, employment, franchise, or agency between the parties. + + 14.10 Neither party will have the power to bind the other or incur + obligations on the other's behalf without the other's prior written + consent. + + 14.11 Customer has not relied on the availability of any future version + of the Software or any future product in making its decision to enter + into this Agreement. + + 14.12 This Agreement may be executed in any number of counterparts, + each of which shall be deemed an original, but all of which together + shall constitute one instrument. Signatures transmitted electronically + or by facsimile shall be deemed original signatures. + + 14.13 This Agreement is applicable both to use of the Software without + a signed Order, but also to use of the Software pursuant to any Order + signed by You or Customer. + +----------------------------------------- + +IMPORTANT CLARIFICATION: From time to time, Couchbase may release +versions of the Software and/or certain features that are not generally +available (the "Non-GA Offering"), including test, alpha, beta, trial, +pre-production, preview and/or developer preview versions or features. If +Customer uses any Non-GA Offering, then the same terms and conditions +of the "Free Licenses" under the Agreement above shall apply, subject +to the modifications below. + +Non-GA Offering Supplemental Terms + +For any Non-GA Offering, the definition of Software in Section 1 of +the Agreement shall be replaced by the following and all references to +"Software" in the applicable provisions shall refer to the below instead: + +"Software" means the applicable Couchbase product, including any Non-GA +Offering, either (i) as reflected in an Order or (ii) as otherwise made +available to Customer under this Agreement. + +Section 2.1 of the Agreement shall be replaced in its entirety by the +following: + +2.1. License Grant. Subject to Customer's compliance with the terms and +conditions of this Agreement and the Documentation, Couchbase hereby +grants to Customer a revocable, non-exclusive, non-transferable, +non-sublicensable, royalty-free, non-fee bearing limited license to +install and use the Non-GA Offering of the Software only for Customer's +own internal non-production use for the purpose of evaluation and +development, if applicable (the "Non-GA Offering License"). By accepting +an invitation to install or use, or by installing or using the Non-GA +Offering, Customer acknowledges and agrees that (i) it has relied upon +its own skill and judgment in electing to use such Non-GA Offering in its +sole discretion, (ii) the Non-GA Offering may not work correctly or in +the same way the final version may work and is offered exclusive of any +warranty (as described in Section 10 of the Agreement) or service level +agreement, (iii) the license granted to Customer with respect to the +Non-GA Offering is revocable and terminable at any time in Couchbase's +sole and absolute discretion, (iv) Couchbase may change, withdraw or +discontinue the Non-GA Offering at any time without notice and is under +no obligation to make such generally available, and (v) Couchbase is +not obligated to provide any services or support, including Support, +Professional Services, updates, patches, enhancements, or fixes (either +in the form of descriptions in the Documentation or on the Couchbase +website or otherwise). Couchbase may use any data, feedback or information +that Customer makes available to Couchbase or that Couchbase derives or +generates from Customer's use of the Non-GA Offering ("Feedback"), and +Customer hereby irrevocably assigns to Couchbase all right, title, and +interest in such Feedback. Customer agrees to the restrictions generally +applicable to the Free Licenses and Software, as applicable, under +this Agreement and any additional requirements set forth by Couchbase +in writing (whether in the Documentation or otherwise) regarding any +particular Non-GA Offering. For the avoidance of doubt, Customer shall +not use any Non-GA Offering in production under any circumstance. + +Section 12 of the Agreement shall be replaced by the following: + +12. Limitation of Liability. +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL THE +COUCHBASE PARTIES BE LIABLE TO CUSTOMER OR TO ANY THIRD PARTY FOR: (A) +ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES; +OR (B) THE COST OF PROCURING SUBSTITUTE PRODUCTS OR PROFESSIONAL +SERVICES ARISING OUT OF OR IN ANY WAY RELATING TO THIS AGREEMENT, +OR THE USE OF OR INABILITY TO USE THE SOFTWARE, DOCUMENTATION OR THE +PROFESSIONAL SERVICES; OR (C) DAMAGES OR OTHER LOSSES FOR LOSS OF USE, +LOSS OF BUSINESS, LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS +OF DATA, COMPUTER FAILURE OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR +LOSSES EVEN IF ADVISED OF THE POSSIBILITY THEREOF AND REGARDLESS OF THE +LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE +CLAIM IS BASED. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN +NO EVENT WILL THE COUCHBASE PARTIES' AGGREGATE LIABILITY TO CUSTOMER, +FROM ALL CAUSES OF ACTION AND UNDER ALL THEORIES OF LIABILITY EXCEED +ONE HUNDRED DOLLARS (US $100). The parties expressly acknowledge and +agree that Couchbase has set its prices and entered into this Agreement +in reliance upon the limitations of liability specified herein, which +allocate the risk between Couchbase and Customer and form a basis of +the bargain between the parties. + +Section 13.1 of the Agreement shall be replaced by the following: + +13.1 This Agreement is effective as of the date of Customer's acceptance +of this Agreement and will continue until: (i) Customer ceases to use +the Non-GA Offering and/or the Non-GA Offering License, (ii) the Non-GA +Offering becomes generally available (in which case the terms of the +Free License or the Enterprise License (with or without an Order), as +applicable, shall automatically apply to Customer's use of the Software), +(iii) Couchbase discontinues and terminates the Non-GA Offering and/or +Non-GA Offering Licenses, in its sole discretion, or (iv) either party +terminates this Agreement as set forth in this Section, provided that +the parties' rights and obligations of the provisions listed in Section +13.4 shall survive any termination. + +If you have any questions regarding this Agreement, please contact us +at legal@couchbase.com. + +Exhibit A +Additional Terms and Conditions for Couchbase Components and Third +Party Products + +Couchbase Component: Connector to Tableau Software, LLC +Additional Terms and Conditions: www.couchbase.com/toollicenses/tableau + +Product License V11: 20230213 diff --git a/libcblite_enterprise/include/cbl++/Base.hh b/libcblite_enterprise/include/cbl++/Base.hh new file mode 100644 index 0000000..d425f5d --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Base.hh @@ -0,0 +1,173 @@ +// +// Base.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl/CBLBase.h" +#include "fleece/slice.hh" +#include +#include +#include +#include +#include + +#if DEBUG +# include "cbl/CBLLog.h" +#endif + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +static inline bool operator== (const CBLError &e1, const CBLError &e2) { + if (e1.code != 0) + return e1.domain == e2.domain && e1.code == e2.code; + else + return e2.code == 0; +} + +namespace cbl { + + using slice = fleece::slice; + using alloc_slice = fleece::alloc_slice; + + // Artificial base class of the C++ wrapper classes; just manages ref-counting. + class RefCounted { + protected: + RefCounted() noexcept :_ref(nullptr) { } + explicit RefCounted(CBLRefCounted* _cbl_nullable ref) noexcept :_ref(CBL_Retain(ref)) { } + RefCounted(const RefCounted &other) noexcept :_ref(CBL_Retain(other._ref)) { } + RefCounted(RefCounted &&other) noexcept :_ref(other._ref) {other._ref = nullptr;} + ~RefCounted() noexcept {CBL_Release(_ref);} + + RefCounted& operator= (const RefCounted &other) noexcept { + CBL_Retain(other._ref); + CBL_Release(_ref); + _ref = other._ref; + return *this; + } + + RefCounted& operator= (RefCounted &&other) noexcept { + if (other._ref != _ref) { + CBL_Release(_ref); + _ref = other._ref; + other._ref = nullptr; + } + return *this; + } + + void clear() {CBL_Release(_ref); _ref = nullptr;} + bool valid() const {return _ref != nullptr;} \ + explicit operator bool() const {return valid();} \ + + static std::string asString(FLSlice s) {return slice(s).asString();} + static std::string asString(FLSliceResult &&s) {return alloc_slice(s).asString();} + + static void check(bool ok, CBLError &error) { + if (!ok) { +#if DEBUG + alloc_slice message = CBLError_Message(&error); + CBL_Log(kCBLLogDomainDatabase, kCBLLogError, "API returning error %d/%d: %.*s", + error.domain, error.code, (int)message.size, (char*)message.buf); +#endif + throw error; + } + } + + CBLRefCounted* _cbl_nullable _ref; + + friend class Extension; + friend class Transaction; + }; + +// Internal use only: Copy/move ctors and assignment ops that have to be declared in subclasses +#define CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +public: \ + CLASS() noexcept :SUPER() { } \ + CLASS& operator=(std::nullptr_t) {clear(); return *this;} \ + bool valid() const {return RefCounted::valid();} \ + explicit operator bool() const {return valid();} \ + bool operator==(const CLASS &other) const {return _ref == other._ref;} \ + bool operator!=(const CLASS &other) const {return _ref != other._ref;} \ + C_TYPE* _cbl_nullable ref() const {return (C_TYPE*)_ref;}\ +protected: \ + explicit CLASS(C_TYPE* _cbl_nullable ref) :SUPER((CBLRefCounted*)ref) { } + +#define CBL_REFCOUNTED_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(CLASS, SUPER, C_TYPE) \ +public: \ + CLASS(const CLASS &other) noexcept :SUPER(other) { } \ + CLASS(CLASS &&other) noexcept :SUPER((SUPER&&)other) { } \ + CLASS& operator=(const CLASS &other) noexcept {SUPER::operator=(other); return *this;} \ + CLASS& operator=(CLASS &&other) noexcept {SUPER::operator=((SUPER&&)other); return *this;} + + /** A token representing a registered listener; instances are returned from the various + methods that register listeners, such as \ref Database::addListener. + When this object goes out of scope, the listener will be unregistered. + @note ListenerToken is now allowed to copy. */ + template + class ListenerToken { + public: + using Callback = std::function; + + ListenerToken() =default; + ~ListenerToken() {CBLListener_Remove(_token);} + + ListenerToken(Callback cb) + :_callback(new Callback(cb)) + { } + + ListenerToken(ListenerToken &&other) + :_token(other._token), + _callback(std::move(other._callback)) + {other._token = nullptr;} + + ListenerToken& operator=(ListenerToken &&other) { + CBLListener_Remove(_token); + _token = other._token; + other._token = nullptr; + _callback = std::move(other._callback); + return *this; + } + + /** Unregisters the listener early, before it leaves scope. */ + void remove() { + CBLListener_Remove(_token); + _token = nullptr; + _callback = nullptr; + } + + void* _cbl_nullable context() const {return _callback.get();} + CBLListenerToken* _cbl_nullable token() const {return _token;} + void setToken(CBLListenerToken* token) {assert(!_token); _token = token;} + + static void call(void* _cbl_nullable context, Args... args) { + auto listener = (Callback*)context; + (*listener)(args...); + } + + private: + CBLListenerToken* _cbl_nullable _token {nullptr}; + std::shared_ptr _callback; // Use shared_ptr instead of unique_ptr to allow to move + + ListenerToken(const ListenerToken&) =delete; + ListenerToken& operator=(const ListenerToken &other) =delete; + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/Blob.hh b/libcblite_enterprise/include/cbl++/Blob.hh new file mode 100644 index 0000000..31e94bd --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Blob.hh @@ -0,0 +1,173 @@ +// +// Blob.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Document.hh" +#include "cbl/CBLBlob.h" +#include "fleece/Mutable.hh" +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class BlobReadStream; + class BlobWriteStream; + + /** A reference to a binary data blob associated with a document. + A blob's persistent form is a special dictionary in the document properties. + To work with a blob, you construct a Blob object with that dictionary. */ + class Blob : protected RefCounted { + public: + /** Returns true if a dictionary in a document is a blob reference. + @note This method tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + static bool isBlob(fleece::Dict d) {return FLDict_IsBlob(d);} + + /** Creates a new blob, given its contents as a single block of data. + @note The memory pointed to by `contents` is no longer needed after this call completes + (it will have been written to the database.) + @param contentType The MIME type (optional). + @param contents The data's address and length. */ + Blob(slice contentType, slice contents) { + _ref = (CBLRefCounted*) CBLBlob_CreateWithData(contentType, contents); + } + + /** Creates a new blob from the data written to a \ref CBLBlobWriteStream. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. */ + inline Blob(slice contentType, BlobWriteStream& writer); + + /** Creates a Blob instance on an existing blob reference in a document or query result. + @note If the dict argument is not actually a blob reference, this Blob object will be + invalid; you can check that by calling its `valid` method or testing it with its + `operator bool`. */ + Blob(fleece::Dict d) + :RefCounted((CBLRefCounted*) FLDict_GetBlob(d)) + { } + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t length() const {return CBLBlob_Length(ref());} + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + std::string contentType() const {return asString(CBLBlob_ContentType(ref()));} + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + std::string digest() const {return asString(CBLBlob_Digest(ref()));} + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + fleece::Dict properties() const {return CBLBlob_Properties(ref());} + + // Allows Blob to be assigned to mutable Dict/Array item, e.g. `dict["foo"] = blob` + operator fleece::Dict() const {return properties();} + + /** Reads the blob's content into memory and returns them. */ + alloc_slice loadContent() { + CBLError error; + fleece::alloc_slice content = CBLBlob_Content(ref(), &error); + check(content.buf, error); + return content; + } + + /** Opens a stream for reading a blob's content. */ + inline BlobReadStream* openContentStream(); + + protected: + Blob(CBLRefCounted* r) :RefCounted(r) { } + + CBL_REFCOUNTED_BOILERPLATE(Blob, RefCounted, CBLBlob) + }; + + /** A stream for writing a new blob to the database. */ + class BlobReadStream { + public: + /** Opens a stream for reading a blob's content. */ + BlobReadStream(Blob *blob) { + CBLError error; + _stream = CBLBlob_OpenContentStream(blob->ref(), &error); + if (!_stream) throw error; + } + + ~BlobReadStream() { + CBLBlobReader_Close(_stream); + } + + /** Reads data from a blob. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @return The actual number of bytes read; 0 if at EOF. */ + size_t read(void *dst, size_t maxLength) { + CBLError error; + int bytesRead = CBLBlobReader_Read(_stream, dst, maxLength, &error); + if (bytesRead < 0) + throw error; + return size_t(bytesRead); + } + + private: + CBLBlobReadStream* _cbl_nullable _stream {nullptr}; + }; + + BlobReadStream* Blob::openContentStream() { + return new BlobReadStream(this); + } + + /** A stream for writing a new blob to the database. */ + class BlobWriteStream { + public: + /** Create a stream to write a new blob to the database. */ + BlobWriteStream(Database db) { + CBLError error; + _writer = CBLBlobWriter_Create(db.ref(), &error); + if (!_writer) throw error; + } + + ~BlobWriteStream() { + CBLBlobWriter_Close(_writer); + } + + /** Writes data to a new blob. + @param data The data to write. */ + void write(fleece::slice data) { + write(data.buf, data.size); + } + + /** Writes data to a new blob. + @param src The address of the data to write. + @param length The length of the data to write. */ + void write(const void *src, size_t length) { + CBLError error; + if (!CBLBlobWriter_Write(_writer, src, length, &error)) + throw error; + } + + private: + friend class Blob; + CBLBlobWriteStream* _cbl_nullable _writer {nullptr}; + }; + + inline Blob::Blob(slice contentType, BlobWriteStream& writer) { + _ref = (CBLRefCounted*) CBLBlob_CreateWithStream(contentType, writer._writer); + writer._writer = nullptr; + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/Collection.hh b/libcblite_enterprise/include/cbl++/Collection.hh new file mode 100644 index 0000000..b199bbb --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Collection.hh @@ -0,0 +1,379 @@ +// +// Collection.hh +// +// Copyright (c) 2022 Couchbase, Inc 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 "cbl++/Base.hh" +#include "cbl++/Database.hh" +#include "cbl/CBLCollection.h" +#include "cbl/CBLScope.h" +#include "fleece/Mutable.hh" +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Document; + class MutableDocument; + class CollectionChange; + class DocumentChange; + class QueryIndex; + class VectorIndexConfiguration; + + /** Conflict handler used when saving a document. */ + using CollectionConflictHandler = std::function; + + /** + A Collection class represent a collection which is a container for documents. + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + You may decide to delete the default collection, but noted that the default collection cannot + be re-created. The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. */ + class Collection : private RefCounted { + public: + // Accessors: + + /** The collection's name. */ + std::string name() const {return asString(CBLCollection_Name(ref()));} + + /** The collection's fully qualified name in the '.' format. */ + std::string fullName() const {return asString(CBLCollection_FullName(ref()));} + + /** The scope's name. */ + std::string scopeName() const { + auto scope = CBLCollection_Scope(ref()); + auto scopeName = asString(CBLScope_Name(scope)); + CBLScope_Release(scope); + return scopeName; + } + + /** The collection's database. */ + Database database() const {return Database(CBLCollection_Database(ref()));} + + /** The number of documents in the collection. */ + uint64_t count() const {return CBLCollection_Count(ref());} + + // Documents: + + /** Reads a document from the collection in an immutable form. + @note If you are reading the document in order to make changes to it, call \ref Collection::getMutableDocument() instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline Document getDocument(slice docID) const; + + /** Reads a document from the collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref Collection::getDocument(slice docID).) + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline MutableDocument getMutableDocument(slice docID) const; + + /** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + \ref Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @param doc The mutable document to save. */ + inline void saveDocument(MutableDocument &doc); + + /** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency); + + /** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param doc The mutable document to save. + @param handler The callback to be invoked if there is a conflict. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CollectionConflictHandler handler); + + /** Deletes a document from the collection. Deletions are replicated. + @param doc The document to delete. */ + inline void deleteDocument(Document &doc); + + /** Deletes a document from the collection. Deletions are replicated. + @param doc The document to delete. + @param concurrency Conflict-handling strategy. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool deleteDocument(Document &doc, CBLConcurrencyControl concurrency); + + /** Purges a document from the collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @note If you don't have the document in memory already, \ref purgeDocument(slice docID) is a simpler shortcut. + @param doc The document to purge. */ + inline void purgeDocument(Document &doc); + + /** Purges a document by its ID from the collection. + @param docID The document ID to purge. + @return True if the document was purged, false if it doesn't exist. */ + bool purgeDocument(slice docID) { + CBLError error; + bool purged = CBLCollection_PurgeDocumentByID(ref(), docID, &error); + if (!purged && error.code != 0) + throw error; + return purged; + } + + /** Returns the time, if any, at which a given document in the collection will expire and be purged. + Documents don't normally expire; you have to call \ref Collection::setDocumentExpiration(slice docID, time_t expiration) + to set a document's expiration time. + @param docID The ID of the document. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration */ + time_t getDocumentExpiration(slice docID) const { + CBLError error; + time_t exp = CBLCollection_GetDocumentExpiration(ref(), docID, &error); + check(exp >= 0, error); + return exp; + } + + /** Sets or clears the expiration time of a document in the collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. */ + void setDocumentExpiration(slice docID, time_t expiration) { + CBLError error; + check(CBLCollection_SetDocumentExpiration(ref(), docID, expiration, &error), error); + } + + // Indexes: + + /** Creates a value index in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The value index config. */ + void createValueIndex(slice name, CBLValueIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateValueIndex(ref(), name, config, &error), error); + } + + /** Creates a full-text index in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The full-text index config. */ + void createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateFullTextIndex(ref(), name, config, &error), error); + } + + /** Creates an array index for use with UNNEST queries in the collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The array index config. */ + void createArrayIndex(slice name, CBLArrayIndexConfiguration config) { + CBLError error; + check(CBLCollection_CreateArrayIndex(ref(), name, config, &error), error); + } + +#ifdef COUCHBASE_ENTERPRISE + /** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param name The index name. + @param config The vector index config. */ + inline void createVectorIndex(slice name, const VectorIndexConfiguration &config); +#endif + + /** Deletes an index given its name from the collection. */ + void deleteIndex(slice name) { + CBLError error; + check(CBLCollection_DeleteIndex(ref(), name, &error), error); + } + + /** Returns the names of the indexes in the collection, as a Fleece array of strings. */ + fleece::RetainedArray getIndexNames() { + CBLError error; + FLMutableArray flNames = CBLCollection_GetIndexNames(ref(), &error); + check(flNames, error); + fleece::RetainedArray names(flNames); + FLArray_Release(flNames); + return names; + } + + /** Get an index by name. If the index doesn't exist, the NULL QueryIndex object will be returned. */ + inline QueryIndex getIndex(slice name); + + // Listeners: + + /** Collection Change Listener Token */ + using CollectionChangeListener = cbl::ListenerToken; + + /** Registers a collection change listener callback. It will be called after one or more + documents in the collection are changed on disk. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] CollectionChangeListener addChangeListener(CollectionChangeListener::Callback callback) { + auto l = CollectionChangeListener(callback); + l.setToken( CBLCollection_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + /** Document Change Listener Token */ + using CollectionDocumentChangeListener = cbl::ListenerToken; + + /** Registers a document change listener callback. It will be called after a specific document in the collection + is changed on disk. + @param docID The ID of the document to observe. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] CollectionDocumentChangeListener addDocumentChangeListener(slice docID, + CollectionDocumentChangeListener::Callback callback) + { + auto l = CollectionDocumentChangeListener(callback); + l.setToken( CBLCollection_AddDocumentChangeListener(ref(), docID, &_callDocListener, l.context()) ); + return l; + } + + protected: + + static Collection adopt(const CBLCollection* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + Collection col; + col._ref = (CBLRefCounted*)d; + return col; + } + + friend class Database; + friend class Document; + friend class QueryIndex; + + CBL_REFCOUNTED_BOILERPLATE(Collection, RefCounted, CBLCollection); + + private: + + static void _callListener(void* _cbl_nullable context, const CBLCollectionChange* change) { + Collection col = Collection((CBLCollection*)change->collection); + std::vector docIDs((slice*)&change->docIDs[0], (slice*)&change->docIDs[change->numDocs]); + auto ch = std::make_unique(col, docIDs); + CollectionChangeListener::call(context, ch.get()); + } + + static void _callDocListener(void* _cbl_nullable context, const CBLDocumentChange* change) { + Collection col = Collection((CBLCollection*)change->collection); + slice docID = change->docID; + auto ch = std::make_unique(col, docID); + CollectionDocumentChangeListener::call(context, ch.get()); + } + }; + + /** Collection change info notified to the collection change listener's callback. */ + class CollectionChange { + public: + /** The collection. */ + Collection& collection() {return _collection;} + + /** The IDs of the changed documents. */ + std::vector& docIDs() {return _docIDs;} + + /** Internal API. */ + CollectionChange(Collection collection, std::vector docIDs) + :_collection(std::move(collection)) + ,_docIDs(std::move(docIDs)) + { } + + private: + + Collection _collection; + std::vector _docIDs; + }; + + /** Document change info notified to the document change listener's callback. */ + class DocumentChange { + public: + /** The collection. */ + Collection& collection() {return _collection;} + + /** The ID of the changed document. */ + slice& docID() {return _docID;} + + /** Internal API. */ + DocumentChange(Collection collection, slice docID) + :_collection(std::move(collection)) + ,_docID(std::move(docID)) + { } + + private: + + Collection _collection; + slice _docID; + }; + + // Database method bodies: + + inline Collection Database::getCollection(slice collectionName, slice scopeName) const { + CBLError error {}; + return Collection::adopt(CBLDatabase_Collection(ref(), collectionName, scopeName, &error), &error) ; + } + + inline Collection Database::createCollection(slice collectionName, slice scopeName) { + CBLError error {}; + return Collection::adopt(CBLDatabase_CreateCollection(ref(), collectionName, scopeName, &error), &error) ; + } + + inline Collection Database::getDefaultCollection() const { + CBLError error {}; + return Collection::adopt(CBLDatabase_DefaultCollection(ref(), &error), &error) ; + } +} + +/** Hash function for Collection. */ +template<> struct std::hash { + std::size_t operator() (cbl::Collection const& col) const { + auto name = CBLCollection_Name(col.ref()); + auto scope = CBLCollection_Scope(col.ref()); + std::size_t hash = fleece::slice(name).hash() ^ fleece::slice(CBLScope_Name(scope)).hash(); + CBLScope_Release(scope); + return hash; + } +}; + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/CouchbaseLite.hh b/libcblite_enterprise/include/cbl++/CouchbaseLite.hh new file mode 100644 index 0000000..cd1f635 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/CouchbaseLite.hh @@ -0,0 +1,31 @@ +// +// CouchbaseLite.hh +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#pragma once +#include "Blob.hh" +#include "Collection.hh" +#include "Database.hh" +#include "Document.hh" +#include "Prediction.hh" +#include "Query.hh" +#include "QueryIndex.hh" +#include "Replicator.hh" +#include "VectorIndex.hh" diff --git a/libcblite_enterprise/include/cbl++/Database.hh b/libcblite_enterprise/include/cbl++/Database.hh new file mode 100644 index 0000000..ab0b9f2 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Database.hh @@ -0,0 +1,591 @@ +// +// Database.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Base.hh" +#include "cbl/CBLCollection.h" +#include "cbl/CBLDatabase.h" +#include "cbl/CBLDocument.h" +#include "cbl/CBLQuery.h" +#include "cbl/CBLLog.h" +#include "cbl/CBLScope.h" +#include "fleece/Mutable.hh" +#include +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Collection; + class Document; + class MutableDocument; + class Query; + + /** Conflict handler used when saving a document. */ + using ConflictHandler = std::function; + + +#ifdef COUCHBASE_ENTERPRISE + /** ENTERPRISE EDITION ONLY + + Couchbase Lite Extension. */ + class Extension { + public: + /** Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @note Must be called before opening a database that intends to use the vector search extension. */ + static void enableVectorSearch(slice path) { + CBLError error {}; + RefCounted::check(CBL_EnableVectorSearch(path, &error), error); + } + }; +#endif + + /** Couchbase Lite Database. */ + class Database : private RefCounted { + public: + // Static database-file operations: + + /** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ + static bool exists(slice name, + slice inDirectory) + { + return CBL_DatabaseExists(name, inDirectory); + } + + /** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) */ + static void copyDatabase(slice fromPath, + slice toName) + { + CBLError error; + check( CBL_CopyDatabase(fromPath, toName, + nullptr, &error), error ); + } + + /** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) */ + static void copyDatabase(slice fromPath, + slice toName, + const CBLDatabaseConfiguration& config) + { + CBLError error; + check( CBL_CopyDatabase(fromPath, toName, + &config, &error), error ); + } + + /** Deletes a database file. If the database file is open, an error will be thrown. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ + static void deleteDatabase(slice name, + slice inDirectory) + { + CBLError error; + if (!CBL_DeleteDatabase(name, + inDirectory, + &error) && error.code != 0) + check(false, error); + } + + // Lifecycle: + + /** Opens a database, or creates it if it doesn't exist yet, returning a new \ref Database instance. + It's OK to open the same database file multiple times. Each \ref Database instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) */ + Database(slice name) { + open(name, nullptr); + } + + /** Opens a database, or creates it if it doesn't exist yet, returning a new \ref Database instance. + It's OK to open the same database file multiple times. Each \ref Database instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) */ + Database(slice name, + const CBLDatabaseConfiguration& config) + { + open(name, &config); + } + + /** Closes an open database. */ + void close() { + CBLError error; + check(CBLDatabase_Close(ref(), &error), error); + } + + /** Closes and deletes a database. */ + void deleteDatabase() { + CBLError error; + check(CBLDatabase_Delete(ref(), &error), error); + } + + /** Performs database maintenance. + @param type The database maintenance type. */ + void performMaintenance(CBLMaintenanceType type) { + CBLError error; + check(CBLDatabase_PerformMaintenance(ref(), type, &error), error); + } + + // Accessors: + + /** Returns the database's name. */ + std::string name() const {return asString(CBLDatabase_Name(ref()));} + + /** Returns the database's full filesystem path, or an empty string if the database is closed or deleted. */ + std::string path() const {return asString(CBLDatabase_Path(ref()));} + + /** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use Collection's count() on the default collection instead. */ + uint64_t count() const {return CBLDatabase_Count(ref());} + + /** Returns the database's configuration, as given when it was opened. */ + CBLDatabaseConfiguration config() const {return CBLDatabase_Config(ref());} + + // Collections: + + /** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @return The names of all existing scopes in the database, or throws if an error occurred. */ + fleece::MutableArray getScopeNames() const { + CBLError error {}; + FLMutableArray flNames = CBLDatabase_ScopeNames(ref(), &error); + check(flNames, error); + fleece::MutableArray names(flNames); + FLMutableArray_Release(flNames); + return names; + } + + /** Returns the names of all collections in the scope. + @param scopeName The name of the scope. + @return The names of all collections in the scope, or throws if an error occurred. */ + fleece::MutableArray getCollectionNames(slice scopeName =kCBLDefaultScopeName) const { + CBLError error {}; + FLMutableArray flNames = CBLDatabase_CollectionNames(ref(), scopeName, &error); + check(flNames, error); + fleece::MutableArray names(flNames); + FLMutableArray_Release(flNames); + return names; + } + + /** Returns the existing collection with the given name and scope. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @return A \ref Collection instance, or NULL if the collection doesn't exist, or throws if an error occurred. */ + inline Collection getCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName) const; + + /** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @return A \ref Collection instance, or throws if an error occurred. */ + inline Collection createCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName); + + /** Delete an existing collection. + @note The default collection cannot be deleted. + @param collectionName The name of the collection. + @param scopeName The name of the scope. */ + inline void deleteCollection(slice collectionName, slice scopeName =kCBLDefaultScopeName) { + CBLError error {}; + check(CBLDatabase_DeleteCollection(ref(), collectionName, scopeName, &error), error); + } + + /** Returns the default collection. */ + inline Collection getDefaultCollection() const; + + // Documents: + + /** Reads a document from the default collection in an immutable form. + @note If you are reading the document in order to make changes to it, call \ref Database::getMutableDocument() instead. + @warning Deprecated : Use Collection::getDocument(slice docID) on the default collection instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline Document getDocument(slice docID) const; + + /** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref Database::getDocument(slice docID).) + @warning Deprecated : Use Collection::getMutableDocument(slice docID) on the default collection instead. + @param docID The ID of the document. + @return A new \ref Document instance, or NULL if the doc doesn't exist, or throws if an error occurred. */ + inline MutableDocument getMutableDocument(slice docID) const; + + /** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref Database::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + \ref Database::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc) on the default collection instead. + @param doc The mutable document to save. */ + inline void saveDocument(MutableDocument &doc); + + /** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref Database::saveDocument(MutableDocument &doc, ConflictHandler handler) instead. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency) + on the default collection instead. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, CBLConcurrencyControl concurrency); + + /** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use Collection::saveDocument(MutableDocument &doc, ConflictHandler handler) + on the default collection instead. + @param doc The mutable document to save. + @param handler The callback to be invoked if there is a conflict. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool saveDocument(MutableDocument &doc, ConflictHandler handler); + + /** Deletes a document from the default collection. Deletions are replicated. + @warning Deprecated : Use Collection's deleteDocument(Document& doc) on the default collection instead. + @param doc The document to delete. */ + inline void deleteDocument(Document &doc); + + /** Deletes a document from the default collection. Deletions are replicated. + @warning Deprecated : Use Use Collection::deleteDocument(Document& doc, CBLConcurrencyControl concurrency) + on the default collection instead. + @param doc The document to delete. + @param concurrency Conflict-handling strategy. + @return True on success, false on failure. */ + _cbl_warn_unused + inline bool deleteDocument(Document &doc, CBLConcurrencyControl concurrency); + + /** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning Deprecated : Use Collection::purgeDocument(Document& doc) on the default collection instead. + @note If you don't have the document in memory already, \ref purgeDocument(slice docID) is a simpler shortcut. + @param doc The document to purge. */ + inline void purgeDocument(Document &doc); + + /** Purges a document by its ID from the default collection. + @warning Deprecated : Use Collection::purgeDocument(slice docID) on the default collection instead. + @param docID The document ID to purge. + @return True if the document was purged, false if it doesn't exist. */ + bool purgeDocument(slice docID) { + CBLError error; + bool purged = CBLDatabase_PurgeDocumentByID(ref(), docID, &error); + if (!purged && error.code != 0) + throw error; + return purged; + } + + /** Returns the time, if any, at which a given document in the default collection will expire and be purged. + Documents don't normally expire; you have to call \ref Database::setDocumentExpiration(slice docID, time_t expiration) + to set a document's expiration time. + @warning Deprecated : Use Collection::getDocumentExpiration(slice docID) on the default collection instead. + @param docID The ID of the document. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration */ + time_t getDocumentExpiration(slice docID) const { + CBLError error; + time_t exp = CBLDatabase_GetDocumentExpiration(ref(), docID, &error); + check(exp >= 0, error); + return exp; + } + + /** Sets or clears the expiration time of a document in the default collection. + @warning Deprecated : Use Collection::setDocumentExpiration(slice docID, time_t expiration) + on the default collection instead. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. */ + void setDocumentExpiration(slice docID, time_t expiration) { + CBLError error; + check(CBLDatabase_SetDocumentExpiration(ref(), docID, expiration, &error), error); + } + + // Query: + + /** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref Query object around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref Query::setParameters(fleece::Dict parameters) each time you run the query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @return The new query object. */ + inline Query createQuery(CBLQueryLanguage language, slice queryString); + + // Indexes: + + /** Creates a value index in the default collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use Collection::createValueIndex(slice name, CBLValueIndexConfiguration config) + on the default collection instead. + @param name The index name. + @param config The value index config. */ + void createValueIndex(slice name, CBLValueIndexConfiguration config) { + CBLError error; + check(CBLDatabase_CreateValueIndex(ref(), name, config, &error), error); + } + + /** Creates a full-text index in the default collection. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use Collection::createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) + on the default collection instead. + @param name The index name. + @param config The full-text index config. */ + void createFullTextIndex(slice name, CBLFullTextIndexConfiguration config) { + CBLError error; + check(CBLDatabase_CreateFullTextIndex(ref(), name, config, &error), error); + } + + /** Deletes an index given its name from the default collection. + @warning Deprecated : Use Collection::deleteIndex(slice name) on the default collection instead. */ + void deleteIndex(slice name) { + CBLError error; + check(CBLDatabase_DeleteIndex(ref(), name, &error), error); + } + + /** Returns the names of the indexes in the default collection, as a Fleece array of strings. + @warning Deprecated : Use Collection::getIndexNames() on the default collection instead. */ + fleece::RetainedArray getIndexNames() { + FLArray flNames = CBLDatabase_GetIndexNames(ref()); + fleece::RetainedArray names(flNames); + FLArray_Release(flNames); + return names; + } + + // Listeners: + + /** Database (Default Collection) Change Listener Token */ + using ChangeListener = cbl::ListenerToken&>; + + /** Registers a database change listener callback. It will be called after one or more + documents in the default collection are changed on disk. + @warning Deprecated : Use Collection::addChangeListener(ChangeListener::Callback f) + on the default collection instead. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] ChangeListener addChangeListener(ChangeListener::Callback callback) { + auto l = ChangeListener(callback); + l.setToken( CBLDatabase_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + /** Document (in the Default Collection) Change Listener Token */ + using DocumentChangeListener = cbl::ListenerToken; + + /** Registers a document change listener callback. It will be called after a specific document in the default collection + is changed on disk. + @warning Deprecated : Use Collection::addDocumentChangeListener(slice docID, + DocumentChangeListener::Callback listener) on the default collection instead. + @param docID The ID of the document to observe. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] DocumentChangeListener addDocumentChangeListener(slice docID, + DocumentChangeListener::Callback callback) + { + auto l = DocumentChangeListener(callback); + l.setToken( CBLDatabase_AddDocumentChangeListener(ref(), docID, &_callDocListener, l.context()) ); + return l; + } + + // Notifications: + + using NotificationsReadyCallback = std::function; + + /** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref NotificationsReadyCallback will be called instead. + @param callback The function to be called when a notification is available. */ + void bufferNotifications(NotificationsReadyCallback callback) { + _notificationReadyCallbackAccess->setCallback(callback); + CBLDatabase_BufferNotifications(ref(), [](void *context, CBLDatabase *db) { + ((NotificationsReadyCallbackAccess*)context)->call(Database(db)); + }, _notificationReadyCallbackAccess.get()); + } + + /** Immediately issues all pending notifications for this database, by calling their listener callbacks. */ + void sendNotifications() { + CBLDatabase_SendNotifications(ref()); + } + + // Destructors: + + ~Database() { + clear(); + } + + protected: + friend class Collection; + friend class Scope; + + CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(Database, RefCounted, CBLDatabase) + + private: + void open(slice& name, const CBLDatabaseConfiguration* _cbl_nullable config) { + CBLError error {}; + _ref = (CBLRefCounted*)CBLDatabase_Open(name, config, &error); + check(_ref != nullptr, error); + + _notificationReadyCallbackAccess = std::make_shared(); + } + + class NotificationsReadyCallbackAccess { + public: + void setCallback(NotificationsReadyCallback callback) { + std::lock_guard lock(_mutex); + _callback = callback; + } + + void call(Database db) { + NotificationsReadyCallback callback; + { + std::lock_guard lock(_mutex); + callback = _callback; + } + if (callback) + callback(db); + } + private: + std::mutex _mutex; + NotificationsReadyCallback _callback {nullptr}; + }; + + static void _callListener(void* _cbl_nullable context, + const CBLDatabase *db, + unsigned nDocs, FLString *docIDs) + { + std::vector vec((slice*)&docIDs[0], (slice*)&docIDs[nDocs]); + ChangeListener::call(context, Database((CBLDatabase*)db), vec); + } + + static void _callDocListener(void* _cbl_nullable context, + const CBLDatabase *db, FLString docID) { + DocumentChangeListener::call(context, Database((CBLDatabase*)db), docID); + } + + std::shared_ptr _notificationReadyCallbackAccess; + + public: + Database(const Database &other) noexcept + :RefCounted(other) + ,_notificationReadyCallbackAccess(other._notificationReadyCallbackAccess) + { } + + Database(Database &&other) noexcept + :RefCounted((RefCounted&&)other) + ,_notificationReadyCallbackAccess(std::move(other._notificationReadyCallbackAccess)) + { } + + Database& operator=(const Database &other) noexcept { + RefCounted::operator=(other); + _notificationReadyCallbackAccess = other._notificationReadyCallbackAccess; + return *this; + } + + Database& operator=(Database &&other) noexcept { + RefCounted::operator=((RefCounted&&)other); + _notificationReadyCallbackAccess = std::move(other._notificationReadyCallbackAccess); + return *this; + } + + void clear() { + // Reset _notificationReadyCallbackAccess the releasing the _ref to + // ensure that CBLDatabase is deleted before _notificationReadyCallbackAccess. + RefCounted::clear(); + _notificationReadyCallbackAccess.reset(); + } + }; + + + /** A helper object for database transactions. + A Transaction object should be declared as a local (auto) variable. + You must explicitly call \ref commit to commit changes; if you don't, the transaction + will abort when it goes out of scope. */ + class Transaction { + public: + /** Begins a batch operation on the database that will end when the Batch instance + goes out of scope. */ + explicit Transaction(Database db) + :Transaction(db.ref()) + { } + + explicit Transaction (CBLDatabase *db) { + CBLError error; + RefCounted::check(CBLDatabase_BeginTransaction(db, &error), error); + _db = db; + } + + /** Commits changes and ends the transaction. */ + void commit() {end(true);} + + /** Ends the transaction, rolling back changes. */ + void abort() {end(false);} + + ~Transaction() {end(false);} + + private: + void end(bool commit) { + CBLDatabase *db = _db; + if (db) { + _db = nullptr; + CBLError error; + if (!CBLDatabase_EndTransaction(db, commit, &error)) { + // If an exception is thrown while a Batch is in scope, its destructor will + // call end(). If I'm in this situation I cannot throw another exception or + // the C++ runtime will abort the process. Detect this and just warn instead. + if (std::current_exception()) + CBL_Log(kCBLLogDomainDatabase, kCBLLogWarning, + "Transaction::end failed, while handling an exception"); + else + RefCounted::check(false, error); + } + } + } + + CBLDatabase* _cbl_nullable _db = nullptr; + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/Document.hh b/libcblite_enterprise/include/cbl++/Document.hh new file mode 100644 index 0000000..365c7b6 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Document.hh @@ -0,0 +1,286 @@ +// +// Document.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Collection.hh" +#include "cbl++/Database.hh" +#include "cbl/CBLDocument.h" +#include "fleece/Mutable.hh" +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class MutableDocument; + + /** Immutable Document. */ + class Document : protected RefCounted { + public: + // Metadata: + + /** A document's ID */ + std::string id() const {return asString(CBLDocument_ID(ref()));} + + /** A document's revision ID, which is a short opaque string that's guaranteed to be unique to every change made to + the document. If the document doesn't exist yet, this function returns an empty string. */ + std::string revisionID() const {return asString(CBLDocument_RevisionID(ref()));} + + /** A document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ + uint64_t sequence() const {return CBLDocument_Sequence(ref());} + + /** A document's collection or NULL for the new document that hasn't been saved. */ + Collection collection() const {return Collection(CBLDocument_Collection(ref()));} + + // Properties: + + /** A document's properties as an immutable dictionary. */ + fleece::Dict properties() const {return CBLDocument_Properties(ref());} + + /** A document's properties as JSON. */ + alloc_slice propertiesAsJSON() const {return alloc_slice(CBLDocument_CreateJSON(ref()));} + + /** A subscript operator to access a document's property value by key. */ + fleece::Value operator[] (slice key) const {return properties()[key];} + + // Operations: + + /** Creates a new mutable Document instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. */ + inline MutableDocument mutableCopy() const; + + protected: + friend class Collection; + friend class Database; + friend class Replicator; + + Document(CBLRefCounted* r) :RefCounted(r) { } + + static Document adopt(const CBLDocument* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + Document doc; + doc._ref = (CBLRefCounted*)d; + return doc; + } + + static bool checkSave(bool saveResult, CBLError &error) { + if (saveResult) + return true; + else if (error.code == kCBLErrorConflict && error.domain == kCBLDomain) + return false; + else + throw error; + } + + CBL_REFCOUNTED_BOILERPLATE(Document, RefCounted, const CBLDocument) + }; + + + /** Mutable Document. */ + class MutableDocument : public Document { + public: + /** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. */ + explicit MutableDocument(nullptr_t) {_ref = (CBLRefCounted*)CBLDocument_CreateWithID(fleece::nullslice);} + + /** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. */ + explicit MutableDocument(slice docID) {_ref = (CBLRefCounted*)CBLDocument_CreateWithID(docID);} + + /** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref MutableDict::getMutableDict() or \ref MutableDict::getMutableArray() */ + fleece::MutableDict properties() {return CBLDocument_MutableProperties(ref());} + + /** Sets a property key and value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + template + void set(slice key, const V &val) {properties().set(key, val);} + + /** Sets a property key and value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + template + void set(const K &key, const V &val) {properties().set(key, val);} + + /** A subscript operator to access a document's property value by key for either getting or setting the value. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. */ + fleece::keyref operator[] (slice key) + {return properties()[key];} + + /** Sets a mutable document's properties. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param properties The document properties. */ + void setProperties(fleece::MutableDict properties) { + CBLDocument_SetProperties(ref(), properties); + } + + /** Sets a mutable document's properties. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param properties The document properties. */ + void setProperties(fleece::Dict properties) { + CBLDocument_SetProperties(ref(), properties.mutableCopy()); + } + + /** Sets a mutable document's properties from a JSON Dictionary string. + Call \ref Collection::saveDocument(MutableDocument &doc) to persist the changes. + @param json A JSON Dictionaryt string */ + void setPropertiesAsJSON(slice json) { + CBLError error; + if (!CBLDocument_SetJSON(ref(), json, &error)) + throw error; + } + + protected: + static MutableDocument adopt(CBLDocument* _cbl_nullable d, CBLError *error) { + if (!d && error->code != 0) + throw *error; + MutableDocument doc; + doc._ref = (CBLRefCounted*)d; + return doc; + } + + friend class Collection; + friend class Database; + friend class Document; + CBL_REFCOUNTED_BOILERPLATE(MutableDocument, Document, CBLDocument) + }; + + // Document method bodies: + + inline MutableDocument Document::mutableCopy() const { + MutableDocument doc; + doc._ref = (CBLRefCounted*) CBLDocument_MutableCopy(ref()); + return doc; + } + + // Collection method bodies: + + inline Document Collection::getDocument(slice id) const { + CBLError error; + return Document::adopt(CBLCollection_GetDocument(ref(), id, &error), &error); + } + + inline MutableDocument Collection::getMutableDocument(slice id) const { + CBLError error; + return MutableDocument::adopt(CBLCollection_GetMutableDocument(ref(), id, &error), &error); + } + + inline void Collection::saveDocument(MutableDocument &doc) { + (void) saveDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Collection::saveDocument(MutableDocument &doc, CBLConcurrencyControl c) { + CBLError error; + return Document::checkSave( + CBLCollection_SaveDocumentWithConcurrencyControl(ref(), doc.ref(), c, &error), error); + } + + inline bool Collection::saveDocument(MutableDocument &doc, CollectionConflictHandler conflictHandler) { + CBLConflictHandler cHandler = [](void *context, CBLDocument *myDoc, + const CBLDocument *otherDoc) -> bool { + return (*(CollectionConflictHandler*)context)(MutableDocument(myDoc), + Document(otherDoc)); + }; + CBLError error; + return Document::checkSave( + CBLCollection_SaveDocumentWithConflictHandler(ref(), doc.ref(), cHandler, + &conflictHandler, &error), error); + } + + inline void Collection::deleteDocument(Document &doc) { + (void) deleteDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Collection::deleteDocument(Document &doc, CBLConcurrencyControl cc) { + CBLError error; + return Document::checkSave( + CBLCollection_DeleteDocumentWithConcurrencyControl(ref(), doc.ref(), cc, &error), error); + } + + inline void Collection::purgeDocument(Document &doc) { + CBLError error; + check(CBLCollection_PurgeDocument(ref(), doc.ref(), &error), error); + } + + // Database method bodies: + + inline Document Database::getDocument(slice id) const { + CBLError error; + return Document::adopt(CBLDatabase_GetDocument(ref(), id, &error), &error); + } + + inline MutableDocument Database::getMutableDocument(slice id) const { + CBLError error; + return MutableDocument::adopt(CBLDatabase_GetMutableDocument(ref(), id, &error), &error); + } + + inline void Database::saveDocument(MutableDocument &doc) { + (void) saveDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Database::saveDocument(MutableDocument &doc, CBLConcurrencyControl c) { + CBLError error; + return Document::checkSave( + CBLDatabase_SaveDocumentWithConcurrencyControl(ref(), doc.ref(), c, &error), + error); + } + + inline bool Database::saveDocument(MutableDocument &doc, + ConflictHandler conflictHandler) + { + CBLConflictHandler cHandler = [](void *context, CBLDocument *myDoc, + const CBLDocument *otherDoc) -> bool { + return (*(ConflictHandler*)context)(MutableDocument(myDoc), + Document(otherDoc)); + }; + CBLError error; + return Document::checkSave( + CBLDatabase_SaveDocumentWithConflictHandler(ref(), doc.ref(), cHandler, &conflictHandler, &error), + error); + } + + inline void Database::deleteDocument(Document &doc) { + (void) deleteDocument(doc, kCBLConcurrencyControlLastWriteWins); + } + + inline bool Database::deleteDocument(Document &doc, CBLConcurrencyControl cc) { + CBLError error; + return Document::checkSave(CBLDatabase_DeleteDocumentWithConcurrencyControl( + ref(), doc.ref(), cc, &error), + error); + } + + inline void Database::purgeDocument(Document &doc) { + CBLError error; + check(CBLDatabase_PurgeDocument(ref(), doc.ref(), &error), error); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/Prediction.hh b/libcblite_enterprise/include/cbl++/Prediction.hh new file mode 100644 index 0000000..f8d0302 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Prediction.hh @@ -0,0 +1,88 @@ +// +// Prediction.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#ifdef COUCHBASE_ENTERPRISE + +#pragma once +#include "cbl++/Base.hh" +#include "cbl/CBLPrediction.h" +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + /** ENTERPRISE EDITION ONLY + + The PredictiveModel that allows to integrate machine learning model + into queries via invoking query's PREDICTION() function. + + @note The predictive index feature is not supported by Couchbase Lite for C. + The Predictive Model is currently for creating vector indexes using the PREDICTION() function, + which will call the specified predictive model for computing the vectors. */ + class PredictiveModel { + public: + /** Predicts and returns a mutable dictionary based on the input dictionary. + Override this function for the implementation. + @param input The input dictionary corresponding to the input dictionary expression given in the query's PREDICTION() function + @return The output dictionary. + - To create a new dictionary for returning, use fleece::MutableDict::newDict(). + - To create a null result to evaluate as MISSING, use fleece::MutableDict(). */ + virtual fleece::MutableDict prediction(fleece::Dict input) noexcept = 0; + + virtual ~PredictiveModel() = default; + }; + + static std::unordered_map> _sPredictiveModels; + + /** Predictive Model Registation + This class provides static methods to register and unregister predictive models. */ + class Prediction { + public: + /** Registers a predictive model with the given name. */ + static void registerModel(slice name, std::unique_ptr model) { + auto prediction = [](void* context, FLDict input) { + auto m = (PredictiveModel*)context; + return FLMutableDict_Retain((FLMutableDict) m->prediction(input)); + }; + + CBLPredictiveModel config { }; + config.context = model.get(); + config.prediction = prediction; + CBL_RegisterPredictiveModel(name, config); + + _sPredictiveModels[name] = std::move(model); + } + + /** Unregisters the predictive model with the given name. */ + static void unregisterModel(slice name) { + CBL_UnregisterPredictiveModel(name); + _sPredictiveModels.erase(name); + } + }; +} + +CBL_ASSUME_NONNULL_END + +#endif diff --git a/libcblite_enterprise/include/cbl++/Query.hh b/libcblite_enterprise/include/cbl++/Query.hh new file mode 100644 index 0000000..3314bba --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Query.hh @@ -0,0 +1,293 @@ +// +// Query.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Database.hh" +#include "cbl/CBLQuery.h" +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + class Query; + class ResultSet; + class ResultSetIterator; + + /** A database query. */ + class Query : private RefCounted { + public: + /** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref Query object around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref Query::setParameters(fleece::Dict parameters) each time you run the query. + @warning Deprecated : Use Database::createQuery(CBLQueryLanguage language, slice queryString) instead. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. */ + Query(const Database& db, CBLQueryLanguage language, slice queryString) { + CBLError error; + auto q = CBLDatabase_CreateQuery(db.ref(), language, queryString, nullptr, &error); + check(q, error); + _ref = (CBLRefCounted*)q; + } + + /** Returns the column names that will appear in the query results. + The column names are based on their expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ + inline std::vector columnNames() const; + + /** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param parameters The parameters in the form of a Fleece \ref Dict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the fleece::MutableDict) */ + void setParameters(fleece::Dict parameters) {CBLQuery_SetParameters(ref(), parameters);} + + /** Returns the query's current parameter bindings, if any. */ + fleece::Dict parameters() const {return CBLQuery_Parameters(ref());} + + /** Runs the query, returning the results. */ + inline ResultSet execute(); + + /** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. */ + std::string explain() { + return fleece::alloc_slice(CBLQuery_Explain(ref())).asString(); + } + + // Change listener (live query): + + class ChangeListener; + class Change; + + /** Registers a change listener callback to the query, turning it into a "live query" until + the listener is removed (via \ref ListenerToken::remove() ). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] inline ChangeListener addChangeListener(ListenerToken::Callback callback); + + private: + static void _callListener(void *context, CBLQuery*, CBLListenerToken* token); + CBL_REFCOUNTED_BOILERPLATE(Query, RefCounted, CBLQuery) + }; + + + /** A single query result; ResultSet::iterator iterates over these. */ + class Result { + public: + + /** Returns the number of columns in the current result. */ + uint64_t count() const { + return CBLQuery_ColumnCount(CBLResultSet_GetQuery(_ref)); + } + + /** Returns the current result as a JSON dictionary string. */ + alloc_slice toJSON() const { + FLDict dict = CBLResultSet_ResultDict(_ref); + return alloc_slice(FLValue_ToJSON((FLValue)dict)); + } + + /** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL Value, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ + fleece::Value valueAtIndex(unsigned i) const { + return CBLResultSet_ValueAtIndex(_ref, i); + } + + /** Returns the value of a column of the current result, given its column name. + This may return a NULL Value, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) */ + fleece::Value valueForKey(slice key) const { + return CBLResultSet_ValueForKey(_ref, key); + } + + /** A subscript operator that returns value of a column of the current result, given its (zero-based) numeric index. */ + fleece::Value operator[](int i) const {return valueAtIndex(i);} + + /** A subscript operator that returns the value of a column of the current result, given its column name. */ + fleece::Value operator[](slice key) const {return valueForKey(key);} + + protected: + explicit Result(CBLResultSet* _cbl_nullable ref) :_ref(ref) { } + CBLResultSet* _cbl_nullable _ref; + friend class ResultSetIterator; + }; + + /** The results of a query. The only access to the individual Results is to iterate them. */ + class ResultSet : private RefCounted { + public: + using iterator = ResultSetIterator; + inline iterator begin(); + inline iterator end(); + + private: + static ResultSet adopt(const CBLResultSet *d) { + ResultSet rs; + rs._ref = (CBLRefCounted*)d; + return rs; + } + + friend class Query; + CBL_REFCOUNTED_BOILERPLATE(ResultSet, RefCounted, CBLResultSet) + }; + + // Implementation of ResultSet::iterator + class ResultSetIterator { + public: + const Result& operator*() const {return _result;} + const Result& operator->() const {return _result;} + + bool operator== (const ResultSetIterator &i) const {return _rs == i._rs;} + bool operator!= (const ResultSetIterator &i) const {return _rs != i._rs;} + + ResultSetIterator& operator++() { + if (!CBLResultSet_Next(_rs.ref())) + _rs = ResultSet{}; + return *this; + } + protected: + ResultSetIterator() :_rs(), _result(nullptr) { } + explicit ResultSetIterator(ResultSet rs) + :_rs(rs), _result(_rs.ref()) + { + ++*this; // CBLResultSet_Next() has to be called first + } + + ResultSet _rs; + Result _result; + friend class ResultSet; + }; + + // Method implementations: + + inline std::vector Query::columnNames() const { + unsigned n = CBLQuery_ColumnCount(ref()); + std::vector cols; + cols.reserve(n); + for (unsigned i = 0; i < n ; ++i) { + fleece::slice name = CBLQuery_ColumnName(ref(), i); + cols.push_back(name.asString()); + } + return cols; + } + + inline ResultSet Query::execute() { + CBLError error; + auto rs = CBLQuery_Execute(ref(), &error); + check(rs, error); + return ResultSet::adopt(rs); + } + + class Query::ChangeListener : public ListenerToken { + public: + ChangeListener(): ListenerToken() { } + + ChangeListener(Query query, Callback cb) + :ListenerToken(cb) + ,_query(std::move(query)) + { } + + ResultSet results() { + if (!_query) { + throw std::runtime_error("Not allowed to call on uninitialized ChangeListeners"); + } + return getResults(_query, token()); + } + + private: + static ResultSet getResults(Query query, CBLListenerToken* token) { + CBLError error; + auto rs = CBLQuery_CopyCurrentResults(query.ref(), token, &error); + check(rs, error); + return ResultSet::adopt(rs); + } + + Query _query; + friend Change; + }; + + class Query::Change { + public: + Change(const Change& src) : _query(src._query), _token(src._token) {} + + ResultSet results() { + return ChangeListener::getResults(_query, _token); + } + + Query query() { + return _query; + } + + private: + friend class Query; + Change(Query q, CBLListenerToken* token) : _query(q), _token(token) {} + + Query _query; + CBLListenerToken* _token; + }; + + + inline Query::ChangeListener Query::addChangeListener(ChangeListener::Callback f) { + auto l = ChangeListener(*this, f); + l.setToken( CBLQuery_AddChangeListener(ref(), &_callListener, l.context()) ); + return l; + } + + + inline void Query::_callListener(void *context, CBLQuery *q, CBLListenerToken* token) { + ChangeListener::call(context, Change{Query(q), token}); + } + + + inline ResultSet::iterator ResultSet::begin() { + return iterator(*this); + } + + inline ResultSet::iterator ResultSet::end() { + return iterator(); + } + + // Query + + Query Database::createQuery(CBLQueryLanguage language, slice queryString) { + return Query(*this, language, queryString); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/QueryIndex.hh b/libcblite_enterprise/include/cbl++/QueryIndex.hh new file mode 100644 index 0000000..e2dc2d9 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/QueryIndex.hh @@ -0,0 +1,144 @@ +// +// QueryIndex.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#pragma once +#include "cbl++/Base.hh" +#include "cbl++/Collection.hh" +#include "cbl/CBLQueryIndex.h" + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { +#ifdef COUCHBASE_ENTERPRISE + class IndexUpdater; +#endif + + /** QueryIndex object representing an existing index in the collection. */ + class QueryIndex : private RefCounted { + public: + // Accessors: + + /** The index's name. */ + std::string name() const {return asString(CBLQueryIndex_Name(ref()));} + + /** A index's collection. */ + Collection collection() const {return Collection(CBLQueryIndex_Collection(ref()));} + +#ifdef COUCHBASE_ENTERPRISE + // Index Updater: + + /** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref IndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @param limit The maximum number of vectors to be computed. + @return An \ref IndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date. */ + inline IndexUpdater beginUpdate(size_t limit); +#endif + + protected: + friend class Collection; + + static QueryIndex adopt(const CBLQueryIndex* _cbl_nullable i, CBLError *error) { + if (!i && error->code != 0) + throw *error; + QueryIndex index; + index._ref = (CBLRefCounted*)i; + return index; + } + + CBL_REFCOUNTED_BOILERPLATE(QueryIndex, RefCounted, CBLQueryIndex) + }; + +#ifdef COUCHBASE_ENTERPRISE + + /** ENTERPRISE EDITION ONLY + + IndexUpdater is used for updating the index in lazy mode. Currently, the vector index is the only index type + that can be updated lazily. */ + class IndexUpdater : private RefCounted { + public: + /** The total number of vectors to compute and set for updating the index. */ + size_t count() const {return CBLIndexUpdater_Count(ref());} + + /** Get the value at the given index for computing the vector. + @param index The zero-based index. + @return The value. */ + fleece::Value value(size_t index) const { + return CBLIndexUpdater_Value(ref(), index); + } + + /** Sets the vector for the value corresponding to the given index. + Setting NULL vector means that there is no vector for the value, and any existing vector + will be removed when the \ref IndexUpdater::finish is called. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. */ + void setVector(unsigned index, const float* _cbl_nullable vector, size_t dimension) { + CBLError error; + check(CBLIndexUpdater_SetVector(ref(), index, vector, dimension, &error), error); + } + + /** Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the \ref QueryIndex::beginUpdate is later called. + @param index The zero-based index. */ + void skipVector(size_t index) { + CBLIndexUpdater_SkipVector(ref(), index); + } + + /** Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling \ref IndexUpdater::finish, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling \ref IndexUpdater::finish. */ + void finish() { + CBLError error; + check(CBLIndexUpdater_Finish(ref(), &error), error); + } + + protected: + static IndexUpdater adopt(const CBLIndexUpdater* _cbl_nullable i, CBLError *error) { + if (!i && error->code != 0) + throw *error; + IndexUpdater updater; + updater._ref = (CBLRefCounted*)i; + return updater; + } + + friend class QueryIndex; + CBL_REFCOUNTED_BOILERPLATE(IndexUpdater, RefCounted, CBLIndexUpdater) + }; + + IndexUpdater QueryIndex::beginUpdate(size_t limit) { + CBLError error {}; + auto updater = CBLQueryIndex_BeginUpdate(ref(), limit, &error); + return IndexUpdater::adopt(updater, &error); + } +#endif + + QueryIndex Collection::getIndex(slice name) { + CBLError error {}; + return QueryIndex::adopt(CBLCollection_GetIndex(ref(), name, &error), &error); + } +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/Replicator.hh b/libcblite_enterprise/include/cbl++/Replicator.hh new file mode 100644 index 0000000..c37c390 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/Replicator.hh @@ -0,0 +1,585 @@ +// +// Replicator.hh +// +// Copyright (c) 2019 Couchbase, Inc 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 "cbl++/Document.hh" +#include "cbl/CBLReplicator.h" +#include "cbl/CBLDefaults.h" +#include +#include +#include +#include + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + + /** The replication endpoint representing the location of a database to replicate with. */ + class Endpoint { + public: + /** Creates a URL endpoint with a given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + @param url The url. */ + static Endpoint urlEndpoint(slice url) { + CBLError error {}; + auto endpoint = CBLEndpoint_CreateWithURL(url, &error); + if (!endpoint) + throw error; + return Endpoint(endpoint); + } + +#ifdef COUCHBASE_ENTERPRISE + /** Creates a database endpoint with another local database. (Enterprise Edition only.) */ + static Endpoint databaseEndpoint(Database db) { + return Endpoint(CBLEndpoint_CreateWithLocalDB(db.ref())); + } +#endif + + protected: + friend class ReplicatorConfiguration; + + CBLEndpoint* _cbl_nullable ref() const {return _ref.get();} + + private: + Endpoint() = default; + + Endpoint(CBLEndpoint* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLEndpoint_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** Authentication credentials for a remote server. */ + class Authenticator { + public: + /** Creates a basic authenticator authenticator using username/password credentials. */ + static Authenticator basicAuthenticator(slice username, slice password) { + return Authenticator(CBLAuth_CreatePassword(username, password)); + } + + /** Creates a sesssion authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ + static Authenticator sessionAuthenticator(slice sessionId, slice cookieName) { + return Authenticator(CBLAuth_CreateSession(sessionId, cookieName)); + } + + protected: + friend class ReplicatorConfiguration; + + CBLAuthenticator* _cbl_nullable ref() const {return _ref.get();} + + private: + Authenticator() = default; + + Authenticator(CBLAuthenticator* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLAuth_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** Replication Filter Function Callback. */ + using ReplicationFilter = std::function; + + /** Replication Conflict Resolver Function Callback. */ + using ConflictResolver = std::function; + + /** The collection and the configuration that can be configured specifically for the replication. */ + class ReplicationCollection { + public: + /** Creates ReplicationCollection with the collection. */ + ReplicationCollection(Collection collection) + :_collection(collection) + { } + + //-- Accessors: + /** The collection. */ + Collection collection() const {return _collection;} + + //-- Filtering: + /** Optional set of channels to pull from. */ + fleece::MutableArray channels = fleece::MutableArray::newArray(); + + /** Optional set of document IDs to replicate. */ + fleece::MutableArray documentIDs = fleece::MutableArray::newArray(); + + /** Optional callback to filter which docs are pushed. */ + ReplicationFilter pushFilter; + + /** Optional callback to validate incoming docs. */ + ReplicationFilter pullFilter; + + //-- Conflict Resolver: + /** Optional conflict-resolver callback. */ + ConflictResolver conflictResolver; + + private: + Collection _collection; + }; + + /** The configuration of a replicator. */ + class ReplicatorConfiguration { + public: + /** Creates a config using a database to represent the default collection and an endpoint. + @note Only the default collection will be used in the replication. + @warning Deprecated : + Use ReplicatorConfiguration::ReplicatorConfiguration(std::vectorcollections, Endpoint endpoint) + instead. + @param db The database to represent the default collection. + @param endpoint The endpoint to replicate with. */ + ReplicatorConfiguration(Database db, Endpoint endpoint) + :_database(db) + ,_endpoint(endpoint) + { } + + /** Creates a config with a list of collections and per-collection configurations to replicate and an endpoint + @param collections The collections and per-collection configurations. + @param endpoint The endpoint to replicate with. */ + ReplicatorConfiguration(std::vectorcollections, Endpoint endpoint) + :_collections(collections) + ,_endpoint(endpoint) + { } + + //-- Accessors: + /** Returns the configured database. */ + Database database() const {return _database;} + /** Returns the configured endpoint. */ + Endpoint endpoint() const {return _endpoint;} + /** Returns the configured collections. */ + std::vector collections() const {return _collections;} + + //-- Types: + /** Replicator type : Push, pull or both */ + CBLReplicatorType replicatorType = kCBLReplicatorTypePushAndPull; + /** Continuous replication or single-shot replication. */ + bool continuous = false; + + //-- Auto Purge: + /** Enabled auto-purge or not. + If auto purge is enabled, then the replicator will automatically purge any documents + that the replicating user loses access to via the Sync Function on Sync Gateway. */ + bool enableAutoPurge = true; + + //-- Retry Logic: + /** Max retry attempts where the initial connect to replicate counts toward the given value. + Specify 0 to use the default value, 10 times for a non-continuous replicator and max-int time for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts = 0; + /** Max wait time between retry attempts in seconds. + Specify 0 to use the default value of 300 seconds. */ + unsigned maxAttemptWaitTime = 0; + + //-- WebSocket: + /** The heartbeat interval in seconds. + Specify 0 to use the default value of 300 seconds. */ + unsigned heartbeat = 0; + + #ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. */ + std::string networkInterface; + #endif + + //-- HTTP settings: + /** Authentication credentials, if needed. */ + Authenticator authenticator; + /** HTTP client proxy settings. */ + CBLProxySettings* _cbl_nullable proxy = nullptr; + /** Extra HTTP headers to add to the WebSocket request. */ + fleece::MutableDict headers = fleece::MutableDict::newDict(); + + //-- Advance HTTP settings: + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default, which means that the parent-domain cookies are not permitted + to save by default. */ + bool acceptParentDomainCookies = kCBLDefaultReplicatorAcceptParentCookies; + + //-- TLS settings: + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + std::string pinnedServerCertificate; + /** Set of anchor certs (PEM format). */ + std::string trustedRootCertificates; + + //-- Filtering: + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::channels instead. */ + fleece::MutableArray channels = fleece::MutableArray::newArray(); + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::documentIDs instead. */ + fleece::MutableArray documentIDs = fleece::MutableArray::newArray(); + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::pushFilter instead. */ + ReplicationFilter pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::pullFilter instead. */ + ReplicationFilter pullFilter; + + //-- Conflict Resolver: + /** Optional conflict-resolver callback. + @note This property can only be used when creating the config object with the database instead of collections. + @warning Deprecated : Use ReplicationCollection::conflictResolver instead. */ + ConflictResolver conflictResolver; + + protected: + friend class Replicator; + + /** Base config without database, collections, filters, and conflict resolver set. */ + operator CBLReplicatorConfiguration() const { + CBLReplicatorConfiguration conf = {}; + conf.endpoint = _endpoint.ref(); + assert(conf.endpoint); + conf.replicatorType = replicatorType; + conf.continuous = continuous; + conf.disableAutoPurge = !enableAutoPurge; + conf.maxAttempts = maxAttempts; + conf.maxAttemptWaitTime = maxAttemptWaitTime; + conf.heartbeat = heartbeat; + conf.authenticator = authenticator.ref(); + conf.acceptParentDomainCookies = acceptParentDomainCookies; + conf.proxy = proxy; + if (!headers.empty()) + conf.headers = headers; + #ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + if (!networkInterface.empty()) + conf.networkInterface = slice(networkInterface); + #endif + if (!pinnedServerCertificate.empty()) + conf.pinnedServerCertificate = slice(pinnedServerCertificate); + if (!trustedRootCertificates.empty()) + conf.trustedRootCertificates = slice(trustedRootCertificates); + return conf; + } + + private: + Database _database; + Endpoint _endpoint; + std::vector _collections; + }; + + /** Replicator for replicating documents in collections in local database and targeted database. */ + class Replicator : private RefCounted { + public: + /** Creates a new replicator using the specified config. */ + Replicator(const ReplicatorConfiguration& config) + { + // Get the current configured collections and populate one for the + // default collection if the config is configured with the database: + auto collections = config.collections(); + + auto database = config.database(); + if (database) { + assert(collections.empty()); + auto defaultCollection = database.getDefaultCollection(); + if (!defaultCollection) { + throw std::invalid_argument("default collection not exist"); + } + ReplicationCollection col = ReplicationCollection(defaultCollection); + col.channels = config.channels; + col.documentIDs = config.documentIDs; + col.pushFilter = config.pushFilter; + col.pullFilter = config.pullFilter; + col.conflictResolver = config.conflictResolver; + collections.push_back(col); + } + + // Created a shared collection map. The pointer of the collection map will be + // used as a context. + _collectionMap = std::shared_ptr(new CollectionToReplCollectionMap()); + + // Get base C config: + CBLReplicatorConfiguration c_config = config; + + // Construct C replication collections to set to the c_config: + std::vector replCols; + for (int i = 0; i < collections.size(); i++) { + ReplicationCollection& col = collections[i]; + + CBLReplicationCollection replCol {}; + replCol.collection = col.collection().ref(); + + if (!col.channels.empty()) { + replCol.channels = col.channels; + } + + if (!col.documentIDs.empty()) { + replCol.documentIDs = col.documentIDs; + } + + if (col.pushFilter) { + replCol.pushFilter = [](void* context, + CBLDocument* cDoc, + CBLDocumentFlags flags) -> bool { + auto doc = Document(cDoc); + auto map = (CollectionToReplCollectionMap*)context; + return map->find(doc.collection())->second.pushFilter(doc, flags); + }; + } + + if (col.pullFilter) { + replCol.pullFilter = [](void* context, + CBLDocument* cDoc, + CBLDocumentFlags flags) -> bool { + auto doc = Document(cDoc); + auto map = (CollectionToReplCollectionMap*)context; + return map->find(doc.collection())->second.pullFilter(doc, flags); + }; + } + + if (col.conflictResolver) { + replCol.conflictResolver = [](void* context, + FLString docID, + const CBLDocument* cLocalDoc, + const CBLDocument* cRemoteDoc) -> const CBLDocument* + { + auto localDoc = Document(cLocalDoc); + auto remoteDoc = Document(cRemoteDoc); + auto collection = localDoc ? localDoc.collection() : remoteDoc.collection(); + + auto map = (CollectionToReplCollectionMap*)context; + auto resolved = map->find(collection)->second. + conflictResolver(slice(docID), localDoc, remoteDoc); + + auto ref = resolved.ref(); + if (ref && ref != cLocalDoc && ref != cRemoteDoc) { + CBLDocument_Retain(ref); + } + return ref; + }; + } + replCols.push_back(replCol); + _collectionMap->insert({col.collection(), col}); + } + + c_config.collections = replCols.data(); + c_config.collectionCount = replCols.size(); + c_config.context = _collectionMap.get(); + + CBLError error {}; + _ref = (CBLRefCounted*) CBLReplicator_Create(&c_config, &error); + check(_ref, error); + } + + /** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ + void start(bool resetCheckpoint =false) {CBLReplicator_Start(ref(), resetCheckpoint);} + + /** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your replicator change listener if registered with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ + void stop() {CBLReplicator_Stop(ref());} + + /** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry. */ + void setHostReachable(bool r) {CBLReplicator_SetHostReachable(ref(), r);} + + /** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ + void setSuspended(bool s) {CBLReplicator_SetSuspended(ref(), s);} + + /** Returns the replicator's current status. */ + CBLReplicatorStatus status() const {return CBLReplicator_Status(ref());} + + /** Indicates which documents in the default collection have local changes that have not yet + been pushed to the server by this replicator. This is of course a snapshot, that will + go out of date as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + @note This function can be called on a stopped or un-started replicator. + @note Documents that would never be pushed by this replicator, due to its configuration's + `pushFilter` or `docIDs`, are ignored. + @warning If the default collection is not part of the replication, an error will be thrown. + @warning Deprecated : Use Replicator::pendingDocumentIDs(Collection& collection) instead. */ + fleece::Dict pendingDocumentIDs() const { + CBLError error; + fleece::Dict result = CBLReplicator_PendingDocumentIDs(ref(), &error); + check(result != nullptr, error); + return result; + } + + /** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref Replicator::pendingDocumentIDs() and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, an error will be thrown. + @warning Deprecated : Use Replicator::isDocumentPending(fleece::slice docID, Collection& collection) instead. */ + bool isDocumentPending(fleece::slice docID) const { + CBLError error; + bool pending = CBLReplicator_IsDocumentPending(ref(), docID, &error); + check(pending || error.code == 0, error); + return pending; + } + + /** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + @warning If the given collection is not part of the replication, an error will be thrown. */ + fleece::Dict pendingDocumentIDs(Collection& collection) const { + CBLError error; + fleece::Dict result = CBLReplicator_PendingDocumentIDs2(ref(), collection.ref(), &error); + check(result != nullptr, error); + return result; + } + + /** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref Replicator::pendingDocumentIDs(Collection& collection) and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, an error will be thrown. */ + bool isDocumentPending(fleece::slice docID, Collection& collection) const { + CBLError error; + bool pending = CBLReplicator_IsDocumentPending2(ref(), docID, collection.ref(), &error); + check(pending || error.code == 0, error); + return pending; + } + + /** A change listener that notifies you when the replicator's status changes. + @note The listener's callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. */ + using ChangeListener = cbl::ListenerToken; + + /** Registers a listener that will be called when the replicator's status changes. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] ChangeListener addChangeListener(ChangeListener::Callback callback) { + auto l = ChangeListener(callback); + l.setToken( CBLReplicator_AddChangeListener(ref(), &_callChangeListener, l.context()) ); + return l; + } + + /** A document replication listener that notifies you when documents are replicated. + @note The listener's callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. */ + using DocumentReplicationListener = cbl::ListenerToken>; + + /** Registers a listener that will be called when documents are replicated. + @param callback The callback to be invoked. + @return A Change Listener Token. Call \ref ListenerToken::remove() method to remove the listener. */ + [[nodiscard]] DocumentReplicationListener addDocumentReplicationListener(DocumentReplicationListener::Callback callback) { + auto l = DocumentReplicationListener(callback); + l.setToken( CBLReplicator_AddDocumentReplicationListener(ref(), &_callDocListener, l.context()) ); + return l; + } + + private: + static void _callChangeListener(void* _cbl_nullable context, + CBLReplicator *repl, + const CBLReplicatorStatus *status) + { + ChangeListener::call(context, Replicator(repl), *status); + } + + static void _callDocListener(void* _cbl_nullable context, + CBLReplicator *repl, + bool isPush, + unsigned numDocuments, + const CBLReplicatedDocument* documents) + { + std::vector docs(&documents[0], &documents[numDocuments]); + DocumentReplicationListener::call(context, Replicator(repl), isPush, docs); + } + + using CollectionToReplCollectionMap = std::unordered_map; + std::shared_ptr _collectionMap; + + CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(Replicator, RefCounted, CBLReplicator) + + public: + Replicator(const Replicator &other) noexcept + :RefCounted(other) + ,_collectionMap(other._collectionMap) + { } + + Replicator(Replicator &&other) noexcept + :RefCounted((RefCounted&&)other) + ,_collectionMap(std::move(other._collectionMap)) + { } + + Replicator& operator=(const Replicator &other) noexcept { + RefCounted::operator=(other); + _collectionMap = other._collectionMap; + return *this; + } + + Replicator& operator=(Replicator &&other) noexcept { + RefCounted::operator=((RefCounted&&)other); + _collectionMap = std::move(other._collectionMap); + return *this; + } + + void clear() { + RefCounted::clear(); + _collectionMap.reset(); + } + }; +} + +CBL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/cbl++/VectorIndex.hh b/libcblite_enterprise/include/cbl++/VectorIndex.hh new file mode 100644 index 0000000..6f32110 --- /dev/null +++ b/libcblite_enterprise/include/cbl++/VectorIndex.hh @@ -0,0 +1,189 @@ +// +// VectorIndex.hh +// +// Copyright (c) 2024 Couchbase, Inc 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. +// + +// VOLATILE API: Couchbase Lite C++ API is not finalized, and may change in +// future releases. + +#ifdef COUCHBASE_ENTERPRISE + +#pragma once +#include "cbl++/Base.hh" +#include "cbl++/Collection.hh" +#include "cbl/CBLQueryIndexTypes.h" + +CBL_ASSUME_NONNULL_BEGIN + +namespace cbl { + /** ENTERPRISE EDITION ONLY + + Vector Encoding Type*/ + class VectorEncoding { + public: + /** Creates a no-encoding type to use in VectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ + static VectorEncoding none() { + return VectorEncoding(CBLVectorEncoding_CreateNone()); + } + + /** Creates a Scalar Quantizer encoding type to use in VectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ + static VectorEncoding scalarQuantizer(CBLScalarQuantizerType type) { + return VectorEncoding(CBLVectorEncoding_CreateScalarQuantizer(type)); + } + + /** Creates a Product Quantizer encoding type to use in VectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ + static VectorEncoding productQuantizer(unsigned int subquantizers, unsigned int bits) { + return VectorEncoding(CBLVectorEncoding_CreateProductQuantizer(subquantizers, bits)); + } + + VectorEncoding() = delete; + + protected: + friend class VectorIndexConfiguration; + + CBLVectorEncoding* ref() const {return _ref.get();} + + private: + VectorEncoding(CBLVectorEncoding* ref) { + _ref = std::shared_ptr(ref, [](auto r) { + CBLVectorEncoding_Free(r); + }); + } + + std::shared_ptr _ref; + }; + + /** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ + class VectorIndexConfiguration { + public: + /** Creates the VectorIndexConfiguration. + @param expressionLanguage The language used in the expressions. + @param expression The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. + - For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + - For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref IndexUpdater to add or update the vector into the index. + @param dimensions The number of vector dimensions. + @note The maximum number of vector dimensions supported is 4096. + @param centroids The number of centroids which is the number buckets to partition the vectors in the index. + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000. */ + VectorIndexConfiguration(CBLQueryLanguage expressionLanguage, slice expression, + unsigned dimensions, unsigned centroids) + :_exprLang(expressionLanguage) + ,_expr(expression) + ,_dimensions(dimensions) + ,_centroids(centroids) + { } + + //-- Accessors: + + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage() const {return _exprLang;} + + /** The expression. */ + slice expression() const {return _expr;} + + /** The number of vector dimensions. */ + unsigned dimensions() const {return _dimensions;} + + /** The number of centroids. */ + unsigned centroids() const {return _centroids;} + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a \ref QueryIndex object. To get a \ref QueryIndex object, call \ref Collection::getIndex. */ + bool isLazy = false; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + VectorEncoding encoding = VectorEncoding::scalarQuantizer(kCBLSQ8); + + /** Distance Metric type. The default value is squared euclidean distance. */ + CBLDistanceMetric metric = kCBLDistanceMetricEuclideanSquared; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize = 0; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize = 0; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes = 0; + + protected: + friend Collection; + + /** To CBLVectorIndexConfiguration */ + operator CBLVectorIndexConfiguration() const { + CBLVectorIndexConfiguration config { _exprLang, _expr, _dimensions, _centroids }; + config.isLazy = isLazy; + config.encoding = encoding.ref(); + config.metric = metric; + config.minTrainingSize = minTrainingSize; + config.maxTrainingSize = maxTrainingSize; + config.numProbes = numProbes; + return config; + } + + private: + CBLQueryLanguage _exprLang; + slice _expr; + unsigned _dimensions; + unsigned _centroids; + }; + + void Collection::createVectorIndex(slice name, const VectorIndexConfiguration &config) { + CBLError error {}; + check(CBLCollection_CreateVectorIndex(ref(), name, config, &error), error); + } +} + +CBL_ASSUME_NONNULL_END + +#endif diff --git a/libcblite_enterprise/include/cbl/CBLBase.h b/libcblite_enterprise/include/cbl/CBLBase.h new file mode 100644 index 0000000..4590ad7 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include "CBL_Edition.h" +#include "CBL_Compat.h" +#include "fleece/Fleece.h" +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLBlob.h b/libcblite_enterprise/include/cbl/CBLBlob.h new file mode 100644 index 0000000..06daf8a --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLCollection.h b/libcblite_enterprise/include/cbl/CBLCollection.h new file mode 100644 index 0000000..de90101 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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" +#include "CBLDocument.h" +#include "CBLQueryIndexTypes.h" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; ///Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLDefaults.h b/libcblite_enterprise/include/cbl/CBLDefaults.h new file mode 100644 index 0000000..696e648 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include "CBL_Compat.h" +#include "CBLReplicator.h" +#include "CBLQueryIndexTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLDocument.h b/libcblite_enterprise/include/cbl/CBLDocument.h new file mode 100644 index 0000000..6f7c3a8 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLEncryptable.h b/libcblite_enterprise/include/cbl/CBLEncryptable.h new file mode 100644 index 0000000..a3142ec --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/include/cbl/CBLLog.h b/libcblite_enterprise/include/cbl/CBLLog.h new file mode 100644 index 0000000..25b53f9 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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" + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLPlatform.h b/libcblite_enterprise/include/cbl/CBLPlatform.h new file mode 100644 index 0000000..5f532a2 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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" + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLPrediction.h b/libcblite_enterprise/include/cbl/CBLPrediction.h new file mode 100644 index 0000000..cba35ce --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/include/cbl/CBLQuery.h b/libcblite_enterprise/include/cbl/CBLQuery.h new file mode 100644 index 0000000..ad6f602 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLQueryIndex.h b/libcblite_enterprise/include/cbl/CBLQueryIndex.h new file mode 100644 index 0000000..2779f6a --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLQueryIndexTypes.h b/libcblite_enterprise/include/cbl/CBLQueryIndexTypes.h new file mode 100644 index 0000000..48d6e66 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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" +#include "CBLQueryTypes.h" + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLQueryTypes.h b/libcblite_enterprise/include/cbl/CBLQueryTypes.h new file mode 100644 index 0000000..4082451 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/include/cbl/CBLReplicator.h b/libcblite_enterprise/include/cbl/CBLReplicator.h new file mode 100644 index 0000000..bffcb64 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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" + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_enterprise/include/cbl/CBL_Edition.h b/libcblite_enterprise/include/cbl/CBL_Edition.h new file mode 100644 index 0000000..065cb31 --- /dev/null +++ b/libcblite_enterprise/include/cbl/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +#define COUCHBASE_ENTERPRISE +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "6728898+e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:20:02Z" diff --git a/libcblite_enterprise/include/cbl/CouchbaseLite.h b/libcblite_enterprise/include/cbl/CouchbaseLite.h new file mode 100644 index 0000000..180e5fb --- /dev/null +++ b/libcblite_enterprise/include/cbl/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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" +#include "CBLBlob.h" +#include "CBLCollection.h" +#include "CBLDatabase.h" +#include "CBLDefaults.h" +#include "CBLDocument.h" +#include "CBLEncryptable.h" +#include "CBLLog.h" +#include "CBLPlatform.h" +#include "CBLPrediction.h" +#include "CBLQuery.h" +#include "CBLQueryIndex.h" +#include "CBLQueryIndexTypes.h" +#include "CBLQueryTypes.h" +#include "CBLReplicator.h" +#include "CBLScope.h" diff --git a/libcblite_enterprise/include/fleece/CompilerSupport.h b/libcblite_enterprise/include/fleece/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_enterprise/include/fleece/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_enterprise/include/fleece/Expert.hh b/libcblite_enterprise/include/fleece/Expert.hh new file mode 100644 index 0000000..14109b8 --- /dev/null +++ b/libcblite_enterprise/include/fleece/Expert.hh @@ -0,0 +1,207 @@ +// +// Expert.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_OBSCURE_HH +#define _FLEECE_OBSCURE_HH +#ifndef _FLEECE_HH +#include "Fleece.hh" +#endif + +#include "FLExpert.h" + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + + // VOLATILE API: These methods are meant for internal use, and will be removed + // in a future release + + // Rarely-needed or advanced functionality; a C++ wrapper around fleece/FLExpert.h + // For documentation, see the comments above the C functions these wrap. + + + /** Just a simple wrapper around \ref FLValue_FromData. + You should generally use a \ref Doc instead; it's safer.*/ + static inline Value ValueFromData(slice data, FLTrust t =kFLUntrusted) { + return FLValue_FromData(data,t); + } + + + //====== ENCODER: + + + /** Encoder subclass that exposes more bells and whistles, most of which are experimental. + You don't actually instantiate this, you call `expert(enc)` (below) to make a reference. */ + class Encoder_ExpertAPI : public Encoder { + public: + Encoder_ExpertAPI() = delete; + + /// Creates an Encoder that writes directly to a file. + static inline Encoder encodeToFile(FILE *file, bool uniqueStrings =true); + + inline void amend(slice base, bool reuseStrings =false, bool externPointers =false); + + slice base() const {return FLEncoder_GetBase(_enc);} + + void suppressTrailer() {FLEncoder_SuppressTrailer(_enc);} + + inline void writeRaw(slice data) {FLEncoder_WriteRaw(_enc, data);} + + size_t bytesWritten() const {return FLEncoder_BytesWritten(_enc);} + size_t nextWritePos() const {return FLEncoder_GetNextWritePos(_enc);} + + inline size_t finishItem() {return FLEncoder_FinishItem(_enc);} + }; + + // use this to call one of the above methods; e.g. `expert(e).suppressTrailer()`. + static inline auto& expert(Encoder &enc) {return (Encoder_ExpertAPI&)enc;} + static inline auto& expert(const Encoder &enc) {return (const Encoder_ExpertAPI&)(enc);} + + + //====== DELTAS: + + + /** Generates and applyies JSON-format deltas/diffs between two Fleece values. + See */ + class JSONDelta { + public: + static inline alloc_slice create(Value old, Value nuu); + static inline bool create(Value old, Value nuu, Encoder &jsonEncoder); + + [[nodiscard]] static inline alloc_slice apply(Value old, + slice jsonDelta, + FLError* FL_NULLABLE error); + /// Writes patched Fleece to the Encoder. + /// On failure, returns false and sets the Encoder's error property. + static inline bool apply(Value old, + slice jsonDelta, + Encoder &encoder); + }; + + + //====== SHARED KEYS: + + + /** Keeps track of a set of dictionary keys that are stored in abbreviated (small integer) form. + + Encoders can be configured to use an instance of this, and will use it to abbreviate keys + that are given to them as strings. (Note: This class is not thread-safe!) + + See */ + class SharedKeys { + public: + SharedKeys() :_sk(nullptr) { } + SharedKeys(FLSharedKeys FL_NULLABLE sk) :_sk(FLSharedKeys_Retain(sk)) { } + ~SharedKeys() {FLSharedKeys_Release(_sk);} + + static SharedKeys create() {return SharedKeys(FLSharedKeys_New(), 1);} + static inline SharedKeys create(slice state); + bool loadState(slice data) {return FLSharedKeys_LoadStateData(_sk, data);} + [[nodiscard]] bool loadState(Value state) {return FLSharedKeys_LoadState(_sk, state);} + alloc_slice stateData() const {return FLSharedKeys_GetStateData(_sk);} + inline void writeState(const Encoder &enc); + unsigned count() const {return FLSharedKeys_Count(_sk);} + void revertToCount(unsigned count) {FLSharedKeys_RevertToCount(_sk, count);} + void disableCaching() {if (_sk) FLSharedKeys_DisableCaching(_sk);} + + operator FLSharedKeys FL_NULLABLE () const {return _sk;} + bool operator== (SharedKeys other) const {return _sk == other._sk;} + + SharedKeys(const SharedKeys &other) noexcept :_sk(FLSharedKeys_Retain(other._sk)) { } + SharedKeys(SharedKeys &&other) noexcept :_sk(other._sk) {other._sk = nullptr;} + inline SharedKeys& operator= (const SharedKeys &other); + inline SharedKeys& operator= (SharedKeys &&other) noexcept; + + private: + SharedKeys(FLSharedKeys sk, int) :_sk(sk) { } + FLSharedKeys FL_NULLABLE _sk {nullptr}; + }; + + + //====== DEPRECATED: + + + /** A Dict that manages its own storage. This has been superseded by \ref Doc. */ + class AllocedDict : public Dict, alloc_slice { + public: + AllocedDict() + =default; + + explicit AllocedDict(alloc_slice s) + :Dict(FLValue_AsDict(FLValue_FromData(s, kFLUntrusted))) + ,alloc_slice(std::move(s)) + { } + + explicit AllocedDict(slice s) + :AllocedDict(alloc_slice(s)) { } + + const alloc_slice& data() const {return *this;} + explicit operator bool () const {return Dict::operator bool();} + + // MI disambiguation: + inline Value operator[] (slice key) const {return Dict::get(key);} + inline Value operator[] (const char *key) const {return Dict::get(key);} + }; + + + //====== IMPLEMENTATION GUNK: + + inline Encoder Encoder_ExpertAPI::encodeToFile(FILE *file, bool uniqueStrings) { + return Encoder(FLEncoder_NewWritingToFile(file, uniqueStrings)); + } + inline void Encoder_ExpertAPI::amend(slice base, bool reuseStrings, bool externPointers) { + FLEncoder_Amend(_enc, base, reuseStrings, externPointers); + } + + inline alloc_slice JSONDelta::create(Value old, Value nuu) { + return FLCreateJSONDelta(old, nuu); + } + inline bool JSONDelta::create(Value old, Value nuu, Encoder &jsonEncoder) { + return FLEncodeJSONDelta(old, nuu, jsonEncoder); + } + inline alloc_slice JSONDelta::apply(Value old, slice jsonDelta, FLError * FL_NULLABLE error) { + return FLApplyJSONDelta(old, jsonDelta, error); + } + inline bool JSONDelta::apply(Value old, + slice jsonDelta, + Encoder &encoder) + { + return FLEncodeApplyingJSONDelta(old, jsonDelta, encoder); + } + + inline void SharedKeys::writeState(const Encoder &enc) { + FLSharedKeys_WriteState(_sk, enc); + } + inline SharedKeys SharedKeys::create(slice state) { + auto sk = create(); + sk.loadState(state); + return sk; + } + inline SharedKeys& SharedKeys::operator= (const SharedKeys &other) { + auto sk = FLSharedKeys_Retain(other._sk); + FLSharedKeys_Release(_sk); + _sk = sk; + return *this; + } + inline SharedKeys& SharedKeys::operator= (SharedKeys &&other) noexcept { + FLSharedKeys_Release(_sk); + _sk = other._sk; + other._sk = nullptr; + return *this; + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_OBSCURE_HH diff --git a/libcblite_enterprise/include/fleece/FLBase.h b/libcblite_enterprise/include/fleece/FLBase.h new file mode 100644 index 0000000..d968f71 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include "CompilerSupport.h" +#include "FLSlice.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_enterprise/include/fleece/FLCollections.h b/libcblite_enterprise/include/fleece/FLCollections.h new file mode 100644 index 0000000..146e94e --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_enterprise/include/fleece/FLDeepIterator.h b/libcblite_enterprise/include/fleece/FLDeepIterator.h new file mode 100644 index 0000000..2e57999 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_enterprise/include/fleece/FLDoc.h b/libcblite_enterprise/include/fleece/FLDoc.h new file mode 100644 index 0000000..b62d8f3 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_enterprise/include/fleece/FLEncoder.h b/libcblite_enterprise/include/fleece/FLEncoder.h new file mode 100644 index 0000000..b92d17d --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include "FLBase.h" +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_enterprise/include/fleece/FLExpert.h b/libcblite_enterprise/include/fleece/FLExpert.h new file mode 100644 index 0000000..5536f2c --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include "FLValue.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_enterprise/include/fleece/FLJSON.h b/libcblite_enterprise/include/fleece/FLJSON.h new file mode 100644 index 0000000..67c5e93 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_enterprise/include/fleece/FLKeyPath.h b/libcblite_enterprise/include/fleece/FLKeyPath.h new file mode 100644 index 0000000..cd91877 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_enterprise/include/fleece/FLMutable.h b/libcblite_enterprise/include/fleece/FLMutable.h new file mode 100644 index 0000000..d2f1d93 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include "FLValue.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_enterprise/include/fleece/FLSlice.h b/libcblite_enterprise/include/fleece/FLSlice.h new file mode 100644 index 0000000..04e9720 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include "CompilerSupport.h" +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_enterprise/include/fleece/FLValue.h b/libcblite_enterprise/include/fleece/FLValue.h new file mode 100644 index 0000000..9de1662 --- /dev/null +++ b/libcblite_enterprise/include/fleece/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include "FLBase.h" + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_enterprise/include/fleece/Fleece+CoreFoundation.h b/libcblite_enterprise/include/fleece/Fleece+CoreFoundation.h new file mode 100644 index 0000000..216c47b --- /dev/null +++ b/libcblite_enterprise/include/fleece/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include "fleece/FLCollections.h" + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/include/fleece/Fleece.h b/libcblite_enterprise/include/fleece/Fleece.h new file mode 100644 index 0000000..86ffc9f --- /dev/null +++ b/libcblite_enterprise/include/fleece/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include "FLBase.h" +#include "FLCollections.h" +#include "FLDeepIterator.h" +#include "FLDoc.h" +#include "FLEncoder.h" +#include "FLJSON.h" +#include "FLKeyPath.h" +#include "FLMutable.h" +#include "FLValue.h" + +// #include "FLExpert.h" -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +# include "Fleece+CoreFoundation.h" +#endif + +#endif // _FLEECE_H diff --git a/libcblite_enterprise/include/fleece/Fleece.hh b/libcblite_enterprise/include/fleece/Fleece.hh new file mode 100644 index 0000000..5a0cffd --- /dev/null +++ b/libcblite_enterprise/include/fleece/Fleece.hh @@ -0,0 +1,624 @@ +// +// Fleece.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_HH +#define _FLEECE_HH +#ifndef _FLEECE_H +#include "Fleece.h" +#endif +#include "slice.hh" +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + class Array; + class Dict; + class MutableArray; + class MutableDict; + class KeyPath; + class SharedKeys; + class Doc; + class Encoder; + + + /** A Fleece data value. Its subclasses are Array and Dict; Value itself is for scalars. */ + class Value { + public: + Value() =default; + Value(const Value &) noexcept =default; + Value(FLValue FL_NULLABLE v) :_val(v) { } + operator FLValue FL_NULLABLE () const {return _val;} + + static Value null() {return Value(kFLNullValue);} + static Value undefined() {return Value(kFLUndefinedValue);} + + inline FLValueType type() const; + inline bool isInteger() const; + inline bool isUnsigned() const; + inline bool isDouble() const; + inline bool isMutable() const; + + inline bool asBool() const; + inline int64_t asInt() const; + inline uint64_t asUnsigned() const; + inline float asFloat() const; + inline double asDouble() const; + inline slice asString() const; + inline FLTimestamp asTimestamp() const; + inline slice asData() const; + inline Array asArray() const; + inline Dict asDict() const; + + inline std::string asstring() const {return asString().asString();} + + inline alloc_slice toString() const; + inline alloc_slice toJSON(bool json5 =false, bool canonical =false) const; + inline std::string toJSONString() const {return std::string(toJSON());} + inline alloc_slice toJSON5() const {return toJSON(true);} + + explicit operator bool() const {return _val != nullptr;} + bool operator! () const {return _val == nullptr;} + bool operator== (Value v) const {return _val == v._val;} + bool operator== (FLValue FL_NULLABLE v) const {return _val == v;} + bool operator!= (Value v) const {return _val != v._val;} + bool operator!= (FLValue FL_NULLABLE v) const {return _val != v;} + + bool isEqual(Value v) const {return FLValue_IsEqual(_val, v);} + + Value& operator= (Value v) {_val = v._val; return *this;} + Value& operator= (std::nullptr_t) {_val = nullptr; return *this;} + + inline Value operator[] (const KeyPath &kp) const; + + inline Doc findDoc() const; + +#ifdef __OBJC__ + inline id asNSObject(NSMapTable* FL_NULLABLE sharedStrings =nil) const { + return FLValue_GetNSObject(_val, sharedStrings); + } +#endif + + // Disallowed because the mutable value would be released, which might free it: + Value(MutableArray&&) =delete; + Value& operator= (MutableArray&&) =delete; + Value(MutableDict&&) =delete; + Value& operator= (MutableDict&&) =delete; + + protected: + ::FLValue FL_NULLABLE _val {nullptr}; + }; + + + class valueptr { // A bit of ugly glue used to make Array/Dict iterator's operator-> work + public: + explicit valueptr(Value v) :_value(v) { } + Value* operator-> () {return &_value;} + private: + Value _value; + }; + + + /** An array of Fleece values. */ + class Array : public Value { + public: + Array() :Value() { } + Array(FLArray FL_NULLABLE a) :Value((FLValue)a) { } + Array(const Array&) noexcept = default; + operator FLArray FL_NULLABLE () const {return (FLArray)_val;} + + static Array emptyArray() {return Array(kFLEmptyArray);} + + inline uint32_t count() const; + [[nodiscard]] inline bool empty() const; + inline Value get(uint32_t index) const; + + inline Value operator[] (int index) const {return get(index);} + inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);} + + Array& operator= (Array a) {_val = a._val; return *this;} + Array& operator= (std::nullptr_t) {_val = nullptr; return *this;} + Value& operator= (Value v) =delete; + + [[nodiscard]] inline MutableArray asMutable() const; + + [[nodiscard]] inline MutableArray mutableCopy(FLCopyFlags =kFLDefaultCopy) const; + + + class iterator : private FLArrayIterator { + public: + inline iterator(Array); + inline iterator(const FLArrayIterator &i) :FLArrayIterator(i) { } + inline Value value() const; + inline uint32_t count() const {return FLArrayIterator_GetCount(this);} + inline bool next(); + inline valueptr operator -> () const {return valueptr(value());} + inline Value operator * () const {return value();} + inline explicit operator bool() const {return (bool)value();} + inline iterator& operator++ () {next(); return *this;} + inline bool operator!= (const iterator&) {return value() != nullptr;} + inline Value operator[] (unsigned n) const {return FLArrayIterator_GetValueAt(this,n);} + private: + iterator() =default; + friend class Array; + }; + + // begin/end are just provided so you can use the C++11 "for (Value v : array)" syntax. + inline iterator begin() const {return iterator(*this);} + inline iterator end() const {return iterator();} + + // Disallowed because the MutableArray would be released, which might free it: + Array(MutableArray&&) =delete; + Array& operator= (MutableArray&&) =delete; + }; + + + /** A mapping of strings to values. */ + class Dict : public Value { + public: + Dict() :Value() { } + Dict(FLDict FL_NULLABLE d) :Value((FLValue)d) { } + Dict(const Dict&) noexcept = default; + operator FLDict FL_NULLABLE () const {return (FLDict)_val;} + + static Dict emptyDict() {return Dict(kFLEmptyDict);} + + inline uint32_t count() const; + [[nodiscard]] inline bool empty() const; + + inline Value get(slice_NONNULL key) const; + + inline Value get(const char* key) const {return get(slice(key));} + + inline Value operator[] (slice_NONNULL key) const {return get(key);} + inline Value operator[] (const char *key) const {return get(key);} + inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);} + + Dict& operator= (Dict d) {_val = d._val; return *this;} + Dict& operator= (std::nullptr_t) {_val = nullptr; return *this;} + Value& operator= (Value v) =delete; + + [[nodiscard]] inline MutableDict asMutable() const; + + [[nodiscard]] inline MutableDict mutableCopy(FLCopyFlags =kFLDefaultCopy) const; + + /** An efficient key for a Dict. */ + class Key { + public: + explicit Key(slice_NONNULL string); + explicit Key(alloc_slice string); + inline const alloc_slice& string() const {return _str;} + operator const alloc_slice&() const {return _str;} + operator slice_NONNULL() const {return _str;} + private: + alloc_slice _str; + FLDictKey _key; + friend class Dict; + }; + + inline Value get(Key &key) const; + inline Value operator[] (Key &key) const {return get(key);} + + class iterator : private FLDictIterator { + public: + inline iterator(Dict); + inline iterator(const FLDictIterator &i) :FLDictIterator(i) { } + inline uint32_t count() const {return FLDictIterator_GetCount(this);} + inline Value key() const; + inline slice keyString() const; + inline Value value() const; + inline bool next(); + + inline valueptr operator -> () const {return valueptr(value());} + inline Value operator * () const {return value();} + inline explicit operator bool() const {return (bool)value();} + inline iterator& operator++ () {next(); return *this;} + inline bool operator!= (const iterator&) const {return value() != nullptr;} + +#ifdef __OBJC__ + inline NSString* keyAsNSString(NSMapTable *sharedStrings) const + {return FLDictIterator_GetKeyAsNSString(this, sharedStrings);} +#endif + private: + iterator() =default; + friend class Dict; + }; + + // begin/end are just provided so you can use the C++11 "for (Value v : dict)" syntax. + inline iterator begin() const {return iterator(*this);} + inline iterator end() const {return iterator();} + + // Disallowed because the MutableDict would be released, which might free it: + Dict(MutableDict&&) =delete; + Dict& operator= (MutableDict&&) =delete; + }; + + + /** Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + Similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + It looks like "foo.bar[2][-3].baz" -- that is, properties prefixed with a ".", and array + indexes in brackets. (Negative indexes count from the end of the array.) + A leading JSONPath-like "$." is allowed but ignored. + A '\' can be used to escape a special character ('.', '[' or '$') at the start of a + property name (but not yet in the middle of a name.) */ + class KeyPath { + public: + KeyPath(slice_NONNULL spec, FLError* FL_NULLABLE err) :_path(FLKeyPath_New(spec, err)) { } + ~KeyPath() {FLKeyPath_Free(_path);} + + KeyPath(KeyPath &&kp) :_path(kp._path) {kp._path = nullptr;} + KeyPath& operator=(KeyPath &&kp) {FLKeyPath_Free(_path); _path = kp._path; + kp._path = nullptr; return *this;} + + KeyPath(const KeyPath &kp) :KeyPath(std::string(kp), nullptr) { } + + explicit operator bool() const {return _path != nullptr;} + operator FLKeyPath FL_NONNULL () const {return _path;} + + Value eval(Value root) const { + return FLKeyPath_Eval(_path, root); + } + + static Value eval(slice_NONNULL specifier, Value root, FLError* FL_NULLABLE error) { + return FLKeyPath_EvalOnce(specifier, root, error); + } + + explicit operator std::string() const { + return std::string(alloc_slice(FLKeyPath_ToString(_path))); + } + + bool operator== (const KeyPath &kp) const {return FLKeyPath_Equals(_path, kp._path);} + private: + KeyPath& operator=(const KeyPath&) =delete; + friend class Value; + + FLKeyPath _path; + }; + + + /** An iterator that traverses an entire value hierarchy, descending into Arrays and Dicts. */ + class DeepIterator { + public: + DeepIterator(Value v) :_i(FLDeepIterator_New(v)) { } + ~DeepIterator() {FLDeepIterator_Free(_i);} + + Value value() const {return FLDeepIterator_GetValue(_i);} + slice key() const {return FLDeepIterator_GetKey(_i);} + uint32_t index() const {return FLDeepIterator_GetIndex(_i);} + Value parent() const {return FLDeepIterator_GetParent(_i);} + + size_t depth() const {return FLDeepIterator_GetDepth(_i);} + alloc_slice pathString() const {return FLDeepIterator_GetPathString(_i);} + alloc_slice JSONPointer() const {return FLDeepIterator_GetJSONPointer(_i);} + + void skipChildren() {FLDeepIterator_SkipChildren(_i);} + bool next() {return FLDeepIterator_Next(_i);} + + explicit operator bool() const {return value() != nullptr;} + DeepIterator& operator++() {next(); return *this;} + + private: + DeepIterator(const DeepIterator&) =delete; + + FLDeepIterator _i; + }; + + + /** A container for Fleece data in memory. Every Value belongs to the Doc whose memory range + contains it. The Doc keeps track of the SharedKeys used by its Dicts, and where to resolve + external pointers to. */ + class Doc { + public: + Doc(alloc_slice fleeceData, + FLTrust trust =kFLUntrusted, + FLSharedKeys FL_NULLABLE sk =nullptr, + slice externDest =nullslice) noexcept + { + // We construct FLSliceResult the following way to avoid unnecessary + // retain. (alloc_slice::operator FLSliceResult()& will apply a retain, which, + // if not matched by a release, will lead to memory leak.) + FLSliceResult sliceResult {fleeceData.buf, fleeceData.size}; + _doc = FLDoc_FromResultData(sliceResult, trust, sk, externDest); + } + + static inline Doc fromJSON(slice_NONNULL json, FLError* FL_NULLABLE outError = nullptr); + + Doc() :_doc(nullptr) { } + Doc(FLDoc FL_NULLABLE d, bool retain = true) :_doc(d) {if (retain) FLDoc_Retain(_doc);} + Doc(const Doc &other) noexcept :_doc(FLDoc_Retain(other._doc)) { } + Doc(Doc &&other) noexcept :_doc(other._doc) {other._doc=nullptr; } + Doc& operator=(const Doc &other); + Doc& operator=(Doc &&other) noexcept; + ~Doc() {FLDoc_Release(_doc);} + + slice data() const {return FLDoc_GetData(_doc);} + alloc_slice allocedData() const {return FLDoc_GetAllocedData(_doc);} + FLSharedKeys sharedKeys() const {return FLDoc_GetSharedKeys(_doc);} + + Value root() const {return FLDoc_GetRoot(_doc);} + explicit operator bool () const {return root() != nullptr;} + Array asArray() const {return root().asArray();} + Dict asDict() const {return root().asDict();} + + operator Value () const {return root();} + operator Dict () const {return asDict();} + operator FLDict FL_NULLABLE () const {return asDict();} + + Value operator[] (int index) const {return asArray().get(index);} + Value operator[] (slice key) const {return asDict().get(key);} + Value operator[] (const char *key) const {return asDict().get(key);} + Value operator[] (const KeyPath &kp) const {return root().operator[](kp);} + + bool operator== (const Doc &d) const {return _doc == d._doc;} + + operator FLDoc FL_NULLABLE () const {return _doc;} + FLDoc detach() {auto d = _doc; _doc = nullptr; return d;} + + static Doc containing(Value v) {return Doc(FLValue_FindDoc(v), false);} + bool setAssociated(void * FL_NULLABLE p, const char *t) {return FLDoc_SetAssociated(_doc, p, t);} + void* FL_NULLABLE associated(const char *type) const {return FLDoc_GetAssociated(_doc, type);} + + private: + friend class Value; + explicit Doc(FLValue v) :_doc(FLValue_FindDoc(v)) { } + + FLDoc FL_NULLABLE _doc; + }; + + + class Null { }; + /** A convenient way to specify (JSON) null when writing to an Encoder or mutable cllection */ + constexpr Null nullValue; + + + /** Generates Fleece-encoded data. */ + class Encoder { + public: + Encoder() :_enc(FLEncoder_New()) { } + + explicit Encoder(FLEncoderFormat format, + size_t reserveSize =0, + bool uniqueStrings =true) + :_enc(FLEncoder_NewWithOptions(format, reserveSize, uniqueStrings)) + { } + + explicit Encoder(FILE *file, + bool uniqueStrings =true) + :_enc(FLEncoder_NewWritingToFile(file, uniqueStrings)) + { } + + explicit Encoder(FLSharedKeys FL_NULLABLE sk) :Encoder() {setSharedKeys(sk);} + + explicit Encoder(FLEncoder enc) :_enc(enc) { } + Encoder(Encoder&& enc) :_enc(enc._enc) {enc._enc = nullptr;} + + void detach() {_enc = nullptr;} + + ~Encoder() {FLEncoder_Free(_enc);} + + void setSharedKeys(FLSharedKeys FL_NULLABLE sk) {FLEncoder_SetSharedKeys(_enc, sk);} + + operator ::FLEncoder FL_NONNULL () const {return _enc;} + + inline bool writeNull(); + inline bool writeUndefined(); + inline bool writeBool(bool); + inline bool writeInt(int64_t); + inline bool writeUInt(uint64_t); + inline bool writeFloat(float); + inline bool writeDouble(double); + inline bool writeString(slice); + inline bool writeString(const char *s) {return writeString(slice(s));} + inline bool writeString(std::string s) {return writeString(slice(s));} + inline bool writeDateString(FLTimestamp, bool asUTC =true); + inline bool writeData(slice); + inline bool writeValue(Value); + inline bool convertJSON(slice_NONNULL); + + inline bool beginArray(size_t reserveCount =0); + inline bool endArray(); + inline bool beginDict(size_t reserveCount =0); + inline bool writeKey(slice_NONNULL); + inline bool writeKey(Value); + inline bool endDict(); + + template + inline void write(slice_NONNULL key, T value) {writeKey(key); *this << value;} + + [[nodiscard]] inline Doc finishDoc(FLError* FL_NULLABLE =nullptr); + [[nodiscard]] inline alloc_slice finish(FLError* FL_NULLABLE =nullptr); + inline void reset(); + + inline FLError error() const; + inline const char* FL_NULLABLE errorMessage() const; + + //====== "<<" convenience operators; + + // Note: overriding <<(bool) would be dangerous due to implicit conversion + Encoder& operator<< (Null) {writeNull(); return *this;} + Encoder& operator<< (long long i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned long long i) {writeUInt(i); return *this;} + Encoder& operator<< (long i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned long i) {writeUInt(i); return *this;} + Encoder& operator<< (int i) {writeInt(i); return *this;} + Encoder& operator<< (unsigned int i) {writeUInt(i); return *this;} + Encoder& operator<< (double d) {writeDouble(d); return *this;} + Encoder& operator<< (float f) {writeFloat(f); return *this;} + Encoder& operator<< (slice s) {writeString(s); return *this;} + Encoder& operator<< (const char *str) {writeString(str); return *this;} + Encoder& operator<< (const std::string &s) {writeString(s); return *this;} + Encoder& operator<< (Value v) {writeValue(v); return *this;} + + class keyref { + public: + keyref(Encoder &enc, slice key) :_enc(enc), _key(key) { } + template + inline void operator= (T value) {_enc.writeKey(_key); _enc << value;} + private: + Encoder &_enc; + slice _key; + }; + + // This enables e.g. `enc["key"_sl] = 17` + inline keyref operator[] (slice_NONNULL key) {return keyref(*this, key);} + +#ifdef __OBJC__ + bool writeNSObject(id obj) {return FLEncoder_WriteNSObject(_enc, obj);} + Encoder& operator<< (id obj) {writeNSObject(obj); return *this;} + NSData* finish(NSError **err) {return FLEncoder_FinishWithNSData(_enc, err);} +#endif + + protected: + Encoder(const Encoder&) =delete; + Encoder& operator=(const Encoder&) =delete; + + FLEncoder FL_NULLABLE _enc; + }; + + + /** Subclass of Encoder that generates JSON, not Fleece. */ + class JSONEncoder : public Encoder { + public: + JSONEncoder() :Encoder(kFLEncodeJSON) { } + inline void writeRaw(slice data) {FLEncoder_WriteRaw(_enc, data);} + }; + + /** Subclass of Encoder that generates JSON5 (an variant of JSON with cleaner syntax.) */ + class JSON5Encoder : public Encoder { + public: + JSON5Encoder() :Encoder(kFLEncodeJSON5) { } + }; + + + /** Use this instead of Encoder if you don't own the FLEncoder. Its destructor does not + free the underlying encoder object. */ + class SharedEncoder : public Encoder { + public: + explicit SharedEncoder(FLEncoder enc) :Encoder(enc) { } + + ~SharedEncoder() { + detach(); // prevents Encoder from freeing the FLEncoder + } + }; + + + //====== IMPLEMENTATION GUNK: + + inline FLValueType Value::type() const {return FLValue_GetType(_val);} + inline bool Value::isInteger() const {return FLValue_IsInteger(_val);} + inline bool Value::isUnsigned() const {return FLValue_IsUnsigned(_val);} + inline bool Value::isDouble() const {return FLValue_IsDouble(_val);} + inline bool Value::isMutable() const {return FLValue_IsMutable(_val);} + + inline bool Value::asBool() const {return FLValue_AsBool(_val);} + inline int64_t Value::asInt() const {return FLValue_AsInt(_val);} + inline uint64_t Value::asUnsigned() const {return FLValue_AsUnsigned(_val);} + inline float Value::asFloat() const {return FLValue_AsFloat(_val);} + inline double Value::asDouble() const {return FLValue_AsDouble(_val);} + inline FLTimestamp Value::asTimestamp() const {return FLValue_AsTimestamp(_val);} + inline slice Value::asString() const {return FLValue_AsString(_val);} + inline slice Value::asData() const {return FLValue_AsData(_val);} + inline Array Value::asArray() const {return FLValue_AsArray(_val);} + inline Dict Value::asDict() const {return FLValue_AsDict(_val);} + + inline alloc_slice Value::toString() const {return FLValue_ToString(_val);} + + inline alloc_slice Value::toJSON(bool json5, bool canonical) const { + return FLValue_ToJSONX(_val, json5, canonical); + } + + inline Value Value::operator[] (const KeyPath &kp) const + {return FLKeyPath_Eval(kp._path, _val);} + inline Doc Value::findDoc() const {return Doc(_val);} + + + + inline uint32_t Array::count() const {return FLArray_Count(*this);} + inline bool Array::empty() const {return FLArray_IsEmpty(*this);} + inline Value Array::get(uint32_t i) const {return FLArray_Get(*this, i);} + + inline Array::iterator::iterator(Array a) {FLArrayIterator_Begin(a, this);} + inline Value Array::iterator::value() const {return FLArrayIterator_GetValue(this);} + inline bool Array::iterator::next() {return FLArrayIterator_Next(this);} + + inline uint32_t Dict::count() const {return FLDict_Count(*this);} + inline bool Dict::empty() const {return FLDict_IsEmpty(*this);} + inline Value Dict::get(slice_NONNULL key) const {return FLDict_Get(*this, key);} + inline Value Dict::get(Dict::Key &key) const{return FLDict_GetWithKey(*this, &key._key);} + + inline Dict::Key::Key(alloc_slice s) :_str(std::move(s)), _key(FLDictKey_Init(_str)) { } + inline Dict::Key::Key(slice_NONNULL s) :Key(alloc_slice(s)) { } + + inline Dict::iterator::iterator(Dict d) {FLDictIterator_Begin(d, this);} + inline Value Dict::iterator::key() const {return FLDictIterator_GetKey(this);} + inline slice Dict::iterator::keyString() const {return FLDictIterator_GetKeyString(this);} + inline Value Dict::iterator::value() const {return FLDictIterator_GetValue(this);} + inline bool Dict::iterator::next() {return FLDictIterator_Next(this);} + + inline bool Encoder::writeNull() {return FLEncoder_WriteNull(_enc);} + inline bool Encoder::writeUndefined() {return FLEncoder_WriteUndefined(_enc);} + inline bool Encoder::writeBool(bool b) {return FLEncoder_WriteBool(_enc, b);} + inline bool Encoder::writeInt(int64_t n) {return FLEncoder_WriteInt(_enc, n);} + inline bool Encoder::writeUInt(uint64_t n) {return FLEncoder_WriteUInt(_enc, n);} + inline bool Encoder::writeFloat(float n) {return FLEncoder_WriteFloat(_enc, n);} + inline bool Encoder::writeDouble(double n) {return FLEncoder_WriteDouble(_enc, n);} + inline bool Encoder::writeString(slice s) {return FLEncoder_WriteString(_enc, s);} + inline bool Encoder::writeDateString(FLTimestamp ts, bool asUTC) + {return FLEncoder_WriteDateString(_enc, ts, asUTC);} + inline bool Encoder::writeData(slice data){return FLEncoder_WriteData(_enc, data);} + inline bool Encoder::writeValue(Value v) {return FLEncoder_WriteValue(_enc, v);} + inline bool Encoder::convertJSON(slice_NONNULL j) {return FLEncoder_ConvertJSON(_enc, j);} + inline bool Encoder::beginArray(size_t rsv) {return FLEncoder_BeginArray(_enc, rsv);} + inline bool Encoder::endArray() {return FLEncoder_EndArray(_enc);} + inline bool Encoder::beginDict(size_t rsv) {return FLEncoder_BeginDict(_enc, rsv);} + inline bool Encoder::writeKey(slice_NONNULL key) {return FLEncoder_WriteKey(_enc, key);} + inline bool Encoder::writeKey(Value key) {return FLEncoder_WriteKeyValue(_enc, key);} + inline bool Encoder::endDict() {return FLEncoder_EndDict(_enc);} + inline Doc Encoder::finishDoc(FLError* FL_NULLABLE err) {return Doc(FLEncoder_FinishDoc(_enc, err), false);} + inline alloc_slice Encoder::finish(FLError* FL_NULLABLE err) {return FLEncoder_Finish(_enc, err);} + inline void Encoder::reset() {return FLEncoder_Reset(_enc);} + inline FLError Encoder::error() const {return FLEncoder_GetError(_enc);} + inline const char* Encoder::errorMessage() const {return FLEncoder_GetErrorMessage(_enc);} + + // specialization for assigning bool value since there is no Encoder< + inline void Encoder::keyref::operator= (bool value) {_enc.writeKey(_key); _enc.writeBool(value);} + + inline Doc Doc::fromJSON(slice_NONNULL json, FLError * FL_NULLABLE outError) { + return Doc(FLDoc_FromJSON(json, outError), false); + } + + inline Doc& Doc::operator=(const Doc &other) { + if (other._doc != _doc) { + FLDoc_Release(_doc); + _doc = FLDoc_Retain(other._doc); + } + return *this; + } + + inline Doc& Doc::operator=(Doc &&other) noexcept { + if (other._doc != _doc) { + FLDoc_Release(_doc); + _doc = other._doc; + other._doc = nullptr; + } + return *this; + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_HH diff --git a/libcblite_enterprise/include/fleece/InstanceCounted.hh b/libcblite_enterprise/include/fleece/InstanceCounted.hh new file mode 100644 index 0000000..56c04a5 --- /dev/null +++ b/libcblite_enterprise/include/fleece/InstanceCounted.hh @@ -0,0 +1,97 @@ +// +// InstanceCounted.hh +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/function_ref.hh" +#include //for size_t +#include +#include + +#ifndef INSTANCECOUNTED_TRACK + // TODO: Add this guard back in + //#if DEBUG + #define INSTANCECOUNTED_TRACK 1 + //#endif +#endif + +namespace fleece { + + /** Base class that keeps track of the total instance count of it and all subclasses. + This is useful for leak detection. + In debug builds or if INSTANCECOUNTED_TRACK is defined, the class will also track the + individual instance addresses, which can be logged by calling `dumpInstances`. */ + class InstanceCounted { + public: + + /** Total number of live objects that implement InstanceCounted. */ + static int liveInstanceCount() {return gInstanceCount;} + +#if INSTANCECOUNTED_TRACK + InstanceCounted() {track();} + InstanceCounted(const InstanceCounted&) {track();} + InstanceCounted(InstanceCounted &&old) {track(); old.untrack();} + virtual ~InstanceCounted() {untrack();} // must be virtual for RTTI + + /** Logs information to stderr about all live objects. */ + static void dumpInstances() {dumpInstances(nullptr);} + static void dumpInstances(function_ref f) {dumpInstances(&f);} + + protected: + InstanceCounted(size_t offset) {track(offset);} + private: + void track(size_t offset =0) const; + void untrack() const; + static void dumpInstances(function_ref*); + +#else + InstanceCounted() {++gInstanceCount;} + InstanceCounted(const InstanceCounted&) {++gInstanceCount;} + InstanceCounted(InstanceCounted &&old) {} // Do nothing, the old and new should balance + ~InstanceCounted() {--gInstanceCount;} +#endif + + private: + static std::atomic gInstanceCount; + }; + + + /** Alternative to InstanceCounted that must be used in cases where + - you're using multiple inheritance, + - InstanceCounted is not the first parent class listed, + - _and_ an earlier parent class has virtual methods. + In that situation, InstanceCounted won't be able to determine the exact address of the + object (due to the weird way C++ MI works), so instead you should use + InstanceCountedIn, where MyClass is the class you're declaring. For example: + class MyClass : public BaseClassWithVirtual, InstanceCountedIn { ... }; + */ + template + class InstanceCountedIn : public InstanceCounted { + public: +#if INSTANCECOUNTED_TRACK + InstanceCountedIn() + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { } + + InstanceCountedIn(const InstanceCountedIn&) + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { } + + InstanceCountedIn(InstanceCountedIn &&old) + :InstanceCounted((size_t)this - (size_t)(BASE*)this) + { + old.untrack(); + } +#endif + }; + + +} diff --git a/libcblite_enterprise/include/fleece/Mutable.hh b/libcblite_enterprise/include/fleece/Mutable.hh new file mode 100644 index 0000000..036aa55 --- /dev/null +++ b/libcblite_enterprise/include/fleece/Mutable.hh @@ -0,0 +1,365 @@ +// +// Mutable.hh +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_MUTABLE_HH +#define _FLEECE_MUTABLE_HH +#include "Fleece.hh" + +FL_ASSUME_NONNULL_BEGIN + +namespace fleece { + + // (this is a mostly-internal type that acts as a reference to an item of a MutableArray or + // MutableDict, and allows a value to be stored in it. It decouples dereferencing the collection + // from setting the value, which simplifies the code.) + class [[nodiscard]] Slot { + public: + void setNull() {FLSlot_SetNull(_slot);} + void operator= (Null) {FLSlot_SetNull(_slot);} + void operator= (bool v) {FLSlot_SetBool(_slot, v);} + void operator= (int v) {FLSlot_SetInt(_slot, v);} + void operator= (unsigned v) {FLSlot_SetUInt(_slot, v);} + void operator= (int64_t v) {FLSlot_SetInt(_slot, v);} + void operator= (uint64_t v) {FLSlot_SetUInt(_slot, v);} + void operator= (float v) {FLSlot_SetFloat(_slot, v);} + void operator= (double v) {FLSlot_SetDouble(_slot, v);} + void operator= (slice v) {FLSlot_SetString(_slot, v);} + void operator= (const char *v) {FLSlot_SetString(_slot, slice(v));} + void operator= (const std::string &v) {FLSlot_SetString(_slot, slice(v));} + void setData(slice v) {FLSlot_SetData(_slot, v);} + void operator= (Value v) {FLSlot_SetValue(_slot, v);} + + operator FLSlot FL_NONNULL() {return _slot;} + + private: + friend class MutableArray; + friend class MutableDict; + + Slot(FLSlot FL_NONNULL slot) :_slot(slot) { } + Slot(Slot&& slot) noexcept :_slot(slot._slot) { } + Slot(const Slot&) =delete; + Slot& operator=(const Slot&) =delete; + Slot& operator=(Slot&&) =delete; + + void operator= (const void*) = delete; // Explicitly disallow other pointer types! + + FLSlot const _slot; + }; + + + // (this is an internal type used to make `MutableArray` and `MutableDict`'s `operator[]` + // act idiomatically, supporting assignment. It's not used directly.) + template + class [[nodiscard]] keyref : public Value { + public: + keyref(Collection &coll, Key key) :Value(coll.get(key)), _coll(coll), _key(key) { } + template + void operator= (const keyref &ref) {_coll.set(_key, ref);} + template + void operator= (const T &value) {_coll.set(_key, value);} + + void setNull() {_coll.set(_key).setNull();} + void setData(slice value) {_coll.set(_key).setData(value);} + void remove() {_coll.remove(_key);} + + private: + Collection _coll; + Key _key; + }; + + + /** A mutable form of Array. Its storage lives in the heap, not in the (immutable) Fleece + document. It can be used to make a changed form of a document, which can then be + encoded to a new Fleece document. */ + class MutableArray : public Array { + public: + /** Creates a new, empty mutable array. */ + static MutableArray newArray() {return MutableArray(FLMutableArray_New(), false);} + + MutableArray() :Array() { } + MutableArray(FLMutableArray FL_NULLABLE a) :Array((FLArray)FLMutableArray_Retain(a)) { } + MutableArray(const MutableArray &a) :Array((FLArray)FLMutableArray_Retain(a)) { } + MutableArray(MutableArray &&a) noexcept :Array((FLArray)a) {a._val = nullptr;} + ~MutableArray() {FLMutableArray_Release(*this);} + + operator FLMutableArray FL_NULLABLE () const {return (FLMutableArray)_val;} + + MutableArray& operator= (const MutableArray &a) { + FLMutableArray_Retain(a); + FLMutableArray_Release(*this); + _val = a._val; + return *this; + } + + MutableArray& operator= (MutableArray &&a) noexcept { + if (a._val != _val) { + FLMutableArray_Release(*this); + _val = a._val; + a._val = nullptr; + } + return *this; + } + + /** The immutable Array this instance was constructed from (if any). */ + Array source() const {return FLMutableArray_GetSource(*this);} + + /** True if this array has been modified since it was created. */ + bool isChanged() const {return FLMutableArray_IsChanged(*this);} + + /** Removes a range of values from the array. */ + void remove(uint32_t first, uint32_t n =1) {FLMutableArray_Remove(*this, first, n);} + + /** Sets the array's size. If the array grows, new values begin as nulls. */ + void resize(uint32_t size) {FLMutableArray_Resize(*this, size);} + + Slot set(uint32_t i) {return Slot(FLMutableArray_Set(*this, i));} + void setNull(uint32_t i) {set(i).setNull();} + + template + void set(uint32_t i, T v) {set(i) = v;} + + Slot append() {return FLMutableArray_Append(*this);} + void appendNull() {append().setNull();} + + template + void append(T v) {append() = v;} + + void insertNulls(uint32_t i, uint32_t n) {FLMutableArray_Insert(*this, i, n);} + + // This enables e.g. `array[10] = 17` + inline keyref operator[] (int i) { + return keyref(*this, i); + } + + inline Value operator[] (int index) const {return get(index);} // const version + + + inline MutableArray getMutableArray(uint32_t i); + inline MutableDict getMutableDict(uint32_t i); + + private: + MutableArray(FLMutableArray FL_NULLABLE a, bool) :Array((FLArray)a) {} + friend class RetainedValue; + friend class RetainedArray; + friend class Array; + }; + + + /** A mutable form of Dict. Its storage lives in the heap, not in the (immutable) Fleece + document. It can be used to make a changed form of a document, which can then be + encoded to a new Fleece document. */ + class MutableDict : public Dict { + public: + static MutableDict newDict() {return MutableDict(FLMutableDict_New(), false);} + + MutableDict() :Dict() { } + MutableDict(FLMutableDict FL_NULLABLE d):Dict((FLDict)d) {FLMutableDict_Retain(*this);} + MutableDict(const MutableDict &d) :Dict((FLDict)d) {FLMutableDict_Retain(*this);} + MutableDict(MutableDict &&d) noexcept :Dict((FLDict)d) {d._val = nullptr;} + ~MutableDict() {FLMutableDict_Release(*this);} + + operator FLMutableDict FL_NULLABLE () const {return (FLMutableDict)_val;} + + MutableDict& operator= (const MutableDict &d) { + FLMutableDict_Retain(d); + FLMutableDict_Release(*this); + _val = d._val; + return *this; + } + + MutableDict& operator= (MutableDict &&d) noexcept { + if (d._val != _val) { + FLMutableDict_Release(*this); + _val = d._val; + d._val = nullptr; + } + return *this; + } + + Dict source() const {return FLMutableDict_GetSource(*this);} + bool isChanged() const {return FLMutableDict_IsChanged(*this);} + + void remove(slice key) {FLMutableDict_Remove(*this, key);} + + Slot set(slice key) {return FLMutableDict_Set(*this, key);} + void setNull(slice key) {set(key) = nullValue;} + + template + void set(slice key, T v) {set(key) = v;} + + + // This enables e.g. `dict["key"_sl] = 17` + inline keyref operator[] (slice key) + {return keyref(*this, key);} + inline keyref operator[] (const char *key) + {return keyref(*this, slice(key));} + inline keyref operator[] (Key &key) + {return keyref(*this, key);} + + inline Value operator[] (slice key) const {return Dict::get(key);} + inline Value operator[] (const char *key) const {return Dict::get(key);} + + inline MutableArray getMutableArray(slice key); + inline MutableDict getMutableDict(slice key); + + private: + MutableDict(FLMutableDict FL_NULLABLE d, bool) :Dict((FLDict)d) {} + friend class RetainedValue; + friend class RetainedDict; + friend class Dict; + }; + + + /** Equivalent to Value except that it retains (and releases) its contents. + This makes it safe for holding mutable arrays/dicts. It can also protect regular immutable + Values owned by a Doc from being freed, since retaining such a value causes its Doc to be + retained. */ + class RetainedValue : public Value { + public: + RetainedValue() =default; + RetainedValue(FLValue FL_NULLABLE v) :Value(FLValue_Retain(v)) { } + RetainedValue(const Value &v) :Value(FLValue_Retain(v)) { } + RetainedValue(RetainedValue &&v) noexcept :Value(v) {v._val = nullptr;} + RetainedValue(const RetainedValue &v) noexcept :RetainedValue(Value(v)) { } + RetainedValue(MutableArray &&v) noexcept :Value(v) {v._val = nullptr;} + RetainedValue(MutableDict &&v) noexcept :Value(v) {v._val = nullptr;} + ~RetainedValue() {FLValue_Release(_val);} + + RetainedValue& operator= (const Value &v) { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedValue& operator= (RetainedValue &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedValue& operator= (std::nullptr_t) { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + // NOTE: The RetainedArray and RetainedDict classes are copycats of the RetainedValue class + // above. Any future changes or bug fixes to the three classes should go together. + + /** Equivalent to Array except that it retains (and releases) its contents. + This makes it safe for holding a heap-allocated mutable array. */ + class RetainedArray : public Array { + public: + RetainedArray() =default; + RetainedArray(FLArray FL_NULLABLE v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(const Array &v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(RetainedArray &&v) noexcept :Array(v) {v._val = nullptr;} + RetainedArray(const RetainedArray &v) noexcept :Array(FLArray_Retain(v)) { } + RetainedArray(MutableArray &&v) noexcept :Array(v) {v._val = nullptr;} + ~RetainedArray() {FLValue_Release(_val);} + + RetainedArray& operator= (const Array &v) noexcept { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedArray& operator= (RetainedArray &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedArray& operator= (std::nullptr_t) noexcept { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + /** Equivalent to Dict except that it retains (and releases) its contents. + This makes it safe for holding a heap-allocated mutable dict. */ + class RetainedDict : public Dict { + public: + RetainedDict() =default; + RetainedDict(FLDict FL_NULLABLE v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(const Dict &v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(RetainedDict &&v) noexcept :Dict(v) {v._val = nullptr;} + RetainedDict(const RetainedDict &v) noexcept :Dict(FLDict_Retain(v)) { } + RetainedDict(MutableDict &&v) noexcept :Dict(v) {v._val = nullptr;} + ~RetainedDict() {FLValue_Release(_val);} + + RetainedDict& operator= (const Dict &v) noexcept { + FLValue_Retain(v); + FLValue_Release(_val); + _val = v; + return *this; + } + + RetainedDict& operator= (RetainedDict &&v) noexcept { + if (v._val != _val) { + FLValue_Release(_val); + _val = v._val; + v._val = nullptr; + } + return *this; + } + + RetainedDict& operator= (std::nullptr_t) noexcept { // disambiguation + FLValue_Release(_val); + _val = nullptr; + return *this; + } + }; + + + //====== IMPLEMENTATION GUNK: + + inline MutableArray Array::mutableCopy(FLCopyFlags flags) const { + return MutableArray(FLArray_MutableCopy(*this, flags), false); + } + inline MutableDict Dict::mutableCopy(FLCopyFlags flags) const { + return MutableDict(FLDict_MutableCopy(*this, flags), false); + } + + inline MutableArray MutableArray::getMutableArray(uint32_t i) + {return FLMutableArray_GetMutableArray(*this, i);} + inline MutableDict MutableArray::getMutableDict(uint32_t i) + {return FLMutableArray_GetMutableDict(*this, i);} + inline MutableArray MutableDict::getMutableArray(slice key) + {return FLMutableDict_GetMutableArray(*this, key);} + inline MutableDict MutableDict::getMutableDict(slice key) + {return FLMutableDict_GetMutableDict(*this, key);} + + inline MutableArray Array::asMutable() const { + return MutableArray(FLArray_AsMutable(*this)); + } + + inline MutableDict Dict::asMutable() const { + return MutableDict(FLDict_AsMutable(*this)); + } + +} + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_MUTABLE_HH diff --git a/libcblite_enterprise/include/fleece/PlatformCompat.hh b/libcblite_enterprise/include/fleece/PlatformCompat.hh new file mode 100644 index 0000000..477f9f6 --- /dev/null +++ b/libcblite_enterprise/include/fleece/PlatformCompat.hh @@ -0,0 +1,90 @@ +// +// PlatformCompat.hh +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/CompilerSupport.h" +#ifdef __APPLE__ + #include + #include "TargetConditionals.h" +#endif + +#ifdef _MSC_VER + #define NOINLINE __declspec(noinline) + #define ALWAYS_INLINE inline + #define ASSUME(cond) __assume(cond) + #define LITECORE_UNUSED + #define __typeof decltype + + #define __func__ __FUNCTION__ + + #include + typedef SSIZE_T ssize_t; + + #define MAXFLOAT FLT_MAX + + #define __printflike(A, B) + + #define cbl_strdup _strdup + #define cbl_getcwd _getcwd + + #include + +#else + + // Suppresses "unused function" warnings + #if __has_attribute(unused) + # define LITECORE_UNUSED __attribute__((unused)) + #endif + + // Disables inlining a function. Use when the space savings are worth more than speed. + #if __has_attribute(noinline) + # define NOINLINE __attribute((noinline)) + #else + # define NOINLINE + #endif + + // Forces function to be inlined. Use with care for speed-critical code. + #if __has_attribute(always_inline) + #define ALWAYS_INLINE __attribute__((always_inline)) inline + #else + #define ALWAYS_INLINE inline + #endif + + // Tells the optimizer it may assume `cond` is true (but does not generate code to evaluate it.) + // A typical use cases is like `ASSUME(x != nullptr)`. + // Note: Avoid putting function calls inside it; I've seen cases where those functions appear + // inlined at the call site in the optimized code, even though they're not supposed to.) + #if __has_builtin(__builtin_assume) + #define ASSUME(cond) __builtin_assume(cond) + #else + #define ASSUME(cond) (void(0)) + #endif + + // Declares this function takes a printf-like format string, and the subsequent args should + // be type-checked against it. + #if __has_attribute(__format__) && !defined(__printflike) + # define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif + + // Windows has underscore prefixes before these function names, so define a common name + #define cbl_strdup strdup + #define cbl_getcwd getcwd + +#endif + +// Platform independent string substitutions +#if defined(__linux__) +#define PRIms "ld" +#else +#define PRIms "lld" +#endif diff --git a/libcblite_enterprise/include/fleece/RefCounted.hh b/libcblite_enterprise/include/fleece/RefCounted.hh new file mode 100644 index 0000000..a719575 --- /dev/null +++ b/libcblite_enterprise/include/fleece/RefCounted.hh @@ -0,0 +1,288 @@ +// +// RefCounted.hh +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include "fleece/PlatformCompat.hh" +#include +#include +#include + +namespace fleece { + + /** Simple thread-safe ref-counting implementation. + `RefCounted` objects should be managed by \ref Retained smart-pointers: + `Retained foo = new Foo(...)` or `auto foo = make_retained(...)`. + \note The ref-count starts at 0, so you must call retain() on an instance, or assign it + to a Retained, right after constructing it. */ + class RefCounted { + public: + RefCounted() =default; + + int refCount() const FLPURE {return _refCount;} + + protected: + RefCounted(const RefCounted &) { } + + /** Destructor is accessible only so that it can be overridden. + **Never call `delete`**, only `release`! Overrides should be made protected or private. */ + virtual ~RefCounted(); + + private: + template + friend T* retain(T*) noexcept; + friend void release(const RefCounted*) noexcept; + friend void assignRef(RefCounted* &dst, RefCounted *src) noexcept; + +#if DEBUG + void _retain() const noexcept {_careful_retain();} + void _release() const noexcept {_careful_release();} +#else + ALWAYS_INLINE void _retain() const noexcept { ++_refCount; } + void _release() const noexcept; +#endif + + static constexpr int32_t kCarefulInitialRefCount = -6666666; + void _careful_retain() const noexcept; + void _careful_release() const noexcept; + + mutable std::atomic _refCount +#if DEBUG + {kCarefulInitialRefCount}; +#else + {0}; +#endif + }; + + + /** Retains a RefCounted object and returns the object. Does nothing given a null pointer. + (See also `retain(Retained&&)`, below.) + \warning Manual retain/release is error prone. This function is intended mostly for interfacing + with C code that can't use \ref Retained. */ + template + ALWAYS_INLINE REFCOUNTED* retain(REFCOUNTED *r) noexcept { + if (r) r->_retain(); + return r; + } + + /** Releases a RefCounted object. Does nothing given a null pointer. + \warning Manual retain/release is error prone. This function is intended mostly for interfacing + with C code that can't use \ref Retained. */ + NOINLINE void release(const RefCounted *r) noexcept; + + + // Used internally by Retained's operator=. Marked noinline to prevent code bloat. + NOINLINE void assignRef(RefCounted* &holder, RefCounted *newValue) noexcept; + + // Makes `assignRef` polymorphic with RefCounted subclasses. + template + static inline void assignRef(T* &holder, RefCounted *newValue) noexcept { + assignRef((RefCounted*&)holder, newValue); + } + + + + /** A smart pointer that retains the RefCounted instance it holds. */ + template + class Retained { + public: + Retained() noexcept :_ref(nullptr) { } + Retained(T *t) noexcept :_ref(retain(t)) { } + + Retained(const Retained &r) noexcept :_ref(retain(r._ref)) { } + Retained(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + + template + Retained(const Retained &r) noexcept :_ref(retain(r._ref)) { } + + template + Retained(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + + ~Retained() {release(_ref);} + + operator T* () const & noexcept FLPURE STEPOVER {return _ref;} + T* operator-> () const noexcept FLPURE STEPOVER {return _ref;} + T* get() const noexcept FLPURE STEPOVER {return _ref;} + + explicit operator bool () const FLPURE {return (_ref != nullptr);} + + Retained& operator=(T *t) noexcept {assignRef(_ref, t); return *this;} + + Retained& operator=(const Retained &r) noexcept {return *this = r._ref;} + + template + Retained& operator=(const Retained &r) noexcept {return *this = r._ref;} + + Retained& operator= (Retained &&r) noexcept { + // Unexpectedly, the simplest & most efficient way to implement this is by simply + // swapping the refs, instead of the commented-out code below. + // The reason this works is that `r` is going to get destructed anyway when it goes + // out of scope in the caller's stack frame, and at that point it will contain my + // previous `_ref`, ensuring it gets cleaned up. + std::swap(_ref, r._ref); + // Older code: + // auto oldRef = _ref; + // _ref = std::move(r).detach(); + // release(oldRef); + return *this; + } + + template + Retained& operator= (Retained &&r) noexcept { + auto oldRef = _ref; + if (oldRef != r._ref) { // necessary to avoid premature release + _ref = std::move(r).detach(); + release(oldRef); + } + return *this; + } + + /// Converts a Retained into a raw pointer with a +1 reference that must be released. + /// Used in C++ functions that bridge to C and return C references. + [[nodiscard]] + T* detach() && noexcept {auto r = _ref; _ref = nullptr; return r;} + + // The operator below is often a dangerous mistake, so it's deliberately made impossible. + // It happens in these sorts of contexts, where it can produce a dangling pointer to a + // deleted object: + // Retained createFoo(); + // ... + // Foo *foo = createFoo(); // ☠️ + // or: + // return createFoo(); // ☠️ + // + // However, it _is_ valid if you're passing the Retained r-value as a function parameter, + // since it will not be released until after the function returns: + // void handleFoo(Foo*); + // ... + // handleFoo( createFoo() ); // Would be OK, but prohibited due to the above + // In this case you can use an explicit `get()` to work around the prohibition: + // handleFoo( createFoo().get() ); // OK! + // ...or promote it to an l-value: + // Retained foo = createFoo(); + // handleFoo(foo); // OK! + // ...or change `handleFoo`s parameter to Retained: + // void handleFoo(Retained); + // ... + // handleFoo( createFoo() ); // OK! + operator T* () const && =delete; // see above^ + + private: + template friend class Retained; + template friend class RetainedConst; + template friend Retained adopt(U*) noexcept; + + Retained(T *t, bool) noexcept :_ref(t) { } // private no-retain ctor + + T *_ref; + }; + + + /** Same as Retained, but when you only have a const pointer to the object. */ + template + class RetainedConst { + public: + RetainedConst() noexcept :_ref(nullptr) { } + RetainedConst(const T *t) noexcept :_ref(retain(t)) { } + RetainedConst(const RetainedConst &r) noexcept :_ref(retain(r._ref)) { } + RetainedConst(RetainedConst &&r) noexcept :_ref(std::move(r).detach()) { } + RetainedConst(const Retained &r) noexcept :_ref(retain(r._ref)) { } + RetainedConst(Retained &&r) noexcept :_ref(std::move(r).detach()) { } + ALWAYS_INLINE ~RetainedConst() {release(_ref);} + + operator const T* () const & noexcept FLPURE STEPOVER {return _ref;} + const T* operator-> () const noexcept FLPURE STEPOVER {return _ref;} + const T* get() const noexcept FLPURE STEPOVER {return _ref;} + + RetainedConst& operator=(const T *t) noexcept { + auto oldRef = _ref; + _ref = retain(t); + release(oldRef); + return *this; + } + + RetainedConst& operator=(const RetainedConst &r) noexcept { + return *this = r._ref; + } + + RetainedConst& operator= (RetainedConst &&r) noexcept { + std::swap(_ref, r._ref); + return *this; + } + + template + RetainedConst& operator=(const Retained &r) noexcept { + return *this = r._ref; + } + + template + RetainedConst& operator= (Retained &&r) noexcept { + std::swap(_ref, r._ref); + return *this; + } + + [[nodiscard]] + const T* detach() && noexcept {auto r = _ref; _ref = nullptr; return r;} + + operator const T* () const && =delete; // Usually a mistake; see above under Retained + + private: + const T *_ref; + }; + + + /** Easy instantiation of a ref-counted object: `auto f = retained(new Foo());`*/ + template + [[nodiscard]] inline Retained retained(REFCOUNTED *r) noexcept { + return Retained(r); + } + + /** Easy instantiation of a const ref-counted object: `auto f = retained(new Foo());`*/ + template + [[nodiscard]] inline RetainedConst retained(const REFCOUNTED *r) noexcept { + return RetainedConst(r); + } + + /** Converts a raw pointer with a +1 reference into a Retained object. + This has no effect on the object's ref-count; the existing +1 ref will be released when the + Retained destructs. */ + template + [[nodiscard]] inline Retained adopt(REFCOUNTED *r) noexcept { + return Retained(r, false); + } + + + + /** make_retained(...) is equivalent to `std::make_unique` and `std::make_shared`. + It constructs a new RefCounted object, passing params to the constructor, returning a `Retained`. */ + template + [[nodiscard]] static inline Retained + make_retained(_Args&&... __args) { + return Retained(new T(std::forward<_Args>(__args)...)); + } + + + /** Extracts the pointer from a Retained. It must later be released via `release`. + This is used in bridging functions that return a direct pointer for a C API. */ + template + [[nodiscard]] ALWAYS_INLINE REFCOUNTED* retain(Retained &&retained) noexcept { + return std::move(retained).detach(); + } + + /** Extracts the pointer from a RetainedConst. It must later be released via `release`. + This is used in bridging functions that return a direct pointer for a C API. */ + template + [[nodiscard]] + ALWAYS_INLINE const REFCOUNTED* retain(RetainedConst &&retained) noexcept { + return std::move(retained).detach(); + } + +} diff --git a/libcblite_enterprise/include/fleece/function_ref.hh b/libcblite_enterprise/include/fleece/function_ref.hh new file mode 100644 index 0000000..feea300 --- /dev/null +++ b/libcblite_enterprise/include/fleece/function_ref.hh @@ -0,0 +1,73 @@ +// +// function_ref.hh +// +// Copyright 2017-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// +// +// Extracted from LLVM source code retrieved from +// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/ADT/STLExtras.h + +//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some templates that are useful if you are working with the +// STL at all. +// +// No library is required when using these functions. +// +//===----------------------------------------------------------------------===// + +#pragma once +#include +#include +#include + +namespace fleece { + + +/// An efficient, type-erasing, non-owning reference to a callable. This is +/// intended for use as the type of a function parameter that is not used +/// after the function in question returns. +/// +/// This class does not own the callable, so it is not in general safe to store +/// a function_ref. +template class function_ref; + +template +class function_ref { + Ret (*callback)(intptr_t callable, Params ...params); + intptr_t callable; + + template + static Ret callback_fn(intptr_t callable, Params ...params) { + return (*reinterpret_cast(callable))( + std::forward(params)...); + } + +public: + template + function_ref(Callable &&callabl, + typename std::enable_if< + !std::is_same::type, + function_ref>::value>::type * = nullptr) + : callback(callback_fn::type>), + callable(reinterpret_cast(&callabl)) {} + Ret operator()(Params ...params) const { + return callback(callable, std::forward(params)...); + } +}; + + +} diff --git a/libcblite_enterprise/include/fleece/slice.hh b/libcblite_enterprise/include/fleece/slice.hh new file mode 100644 index 0000000..88d5d5c --- /dev/null +++ b/libcblite_enterprise/include/fleece/slice.hh @@ -0,0 +1,901 @@ +// +// slice.hh +// +// Copyright 2014-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_SLICE_HH +#define _FLEECE_SLICE_HH + +#include "FLSlice.h" +#include // for std::min() +#include +#include +#include // for fputs() +#include // for memcpy(), memcmp() +#include + +#ifndef assert +# include +#endif +# ifndef assert_precondition +# define assert_precondition(e) assert(e) +#endif + +#ifdef __APPLE__ + struct __CFString; + struct __CFData; +# ifdef __OBJC__ + @class NSData; + @class NSString; + @class NSMapTable; +# endif +#endif + +// Figure out whether and how string_view is available +#ifdef __has_include +# if __has_include() +# include +# define SLICE_SUPPORTS_STRING_VIEW +# endif +#endif + + +// Utility for using slice with printf-style formatting. +// Use "%.*" in the format string; then for the corresponding argument put FMTSLICE(theslice). +// NOTE: The argument S will be evaluated twice. +#define FMTSLICE(S) (int)(S).size, (const char*)(S).buf + + +FL_ASSUME_NONNULL_BEGIN + + +namespace fleece { + struct slice; + struct alloc_slice; + struct nullslice_t; + +#ifdef SLICE_SUPPORTS_STRING_VIEW + using string_view = std::string_view; // create typedef with correct namespace +#endif + +#ifdef __APPLE__ + using CFStringRef = const struct ::__CFString *; + using CFDataRef = const struct ::__CFData *; +#endif + + /** Adds a byte offset to a pointer. */ + template + FLCONST constexpr14 inline const T* FL_NONNULL offsetby(const T * FL_NONNULL t, ptrdiff_t offset) noexcept { + return (const T*)((uint8_t*)t + offset); + } + + /** Adds a byte offset to a pointer. */ + template + FLCONST constexpr14 inline T* FL_NONNULL offsetby(T * FL_NONNULL t, ptrdiff_t offset) noexcept { + return (T*)((uint8_t*)t + offset); + } + + /** Subtracts the 2nd pointer from the 1st, returning the difference in addresses. */ + FLCONST constexpr inline ptrdiff_t _pointerDiff(const void* FL_NULLABLE a, const void* FL_NULLABLE b) noexcept { + return (uint8_t*)a - (uint8_t*)b; + } + + /** Subtracts the 2nd pointer from the 1st, returning the difference in addresses. */ + FLCONST constexpr inline ptrdiff_t pointerDiff(const void* a, const void* b) noexcept { + return _pointerDiff(a, b); + } + + +#pragma mark - PURE_SLICE: + + + /** Abstract superclass of `slice` and `alloc_slice`. + A simple pointer to a range of memory: `size` bytes starting at address `buf`. + + \note Not generally used directly; instead, use subclasses \ref slice and \ref alloc_slice. + `pure_slice` mostly serves to factor out their common API. + + * `buf` may be NULL, but only if `size` is zero; this is called `nullslice`. + * `size` may be zero with a non-NULL `buf`; that's called an "empty slice". + * **No ownership is implied!** Just like a regular pointer, it's the client's responsibility + to ensure the memory buffer remains valid. The `alloc_slice` subclass does provide + ownership: it manages a ref-counted heap-allocated buffer. + * Instances are immutable: `buf` and `size` cannot be changed. The `slice` subclass + changes this. + * The memory pointed to cannot be modified through this class. `slice` has some + methods that allow writes. */ + struct pure_slice { + const void* FL_NULLABLE const buf; + size_t const size; + + pure_slice(const pure_slice &) noexcept = default; + /// True if the slice's length is zero. + bool empty() const noexcept FLPURE {return size == 0;} + + /// Testing a slice as a bool results in false for nullslice, true for anything else. + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + + // These methods allow iterating a slice's bytes with a `for(:)` loop: + constexpr const uint8_t* FL_NULLABLE begin() const noexcept FLPURE {return (uint8_t*)buf;} + constexpr const uint8_t* FL_NULLABLE end() const noexcept FLPURE {return begin() + size;} + + /// Returns true if the address is within this slice or equal to its \ref end. + inline bool validAddress(const void * FL_NULLABLE addr) const noexcept FLPURE; + + /// Returns true if the byte at this address is in this slice; does _not_ include \ref end. + inline bool containsAddress(const void * FL_NULLABLE addr) const noexcept FLPURE; + + /// Returns true if the given slice is a subset of me. + inline bool containsAddressRange(pure_slice) const noexcept FLPURE; + + const void* offset(size_t o) const noexcept FLPURE; + size_t offsetOf(const void* ptr) const noexcept FLPURE; + + inline const uint8_t& operator[](size_t i) const noexcept FLPURE; + inline slice operator()(size_t i, size_t n) const noexcept FLPURE; + + inline slice upTo(const void* pos) const noexcept FLPURE; + inline slice from(const void* pos) const noexcept FLPURE; + inline slice upTo(size_t offset) const noexcept FLPURE; + inline slice from(size_t offset) const noexcept FLPURE; + + inline bool containsBytes(pure_slice bytes) const noexcept FLPURE; + inline slice find(pure_slice target) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findByte(uint8_t b) const FLPURE; + inline const uint8_t* FL_NULLABLE findByteOrEnd(uint8_t byte) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findAnyByteOf(pure_slice targetBytes) const noexcept FLPURE; + inline const uint8_t* FL_NULLABLE findByteNotIn(pure_slice targetBytes) const noexcept FLPURE; + + inline int compare(pure_slice s) const noexcept FLPURE {return FLSlice_Compare(*this,s);} + inline int caseEquivalentCompare(pure_slice) const noexcept FLPURE; + inline bool caseEquivalent(pure_slice) const noexcept FLPURE; + + // Relational operators, implemented with FLSlice_Equal and compare(): + + bool operator==(const pure_slice &s) const noexcept FLPURE {return FLSlice_Equal(*this,s);} + bool operator!=(const pure_slice &s) const noexcept FLPURE {return !(*this == s);} + bool operator<(pure_slice s) const noexcept FLPURE {return compare(s) < 0;} + bool operator>(pure_slice s) const noexcept FLPURE {return compare(s) > 0;} + bool operator<=(pure_slice s) const noexcept FLPURE {return compare(s) <= 0;} + bool operator>=(pure_slice s) const noexcept FLPURE {return compare(s) >= 0;} + + inline bool hasPrefix(pure_slice) const noexcept FLPURE; + inline bool hasSuffix(pure_slice) const noexcept FLPURE; + bool hasPrefix(uint8_t b) const noexcept FLPURE {return size > 0 && (*this)[0] == b;} + bool hasSuffix(uint8_t b) const noexcept FLPURE {return size > 0 && (*this)[size-1] == b;} + + /** Computes a 32-bit non-cryptographic hash of the slice's contents. */ + uint32_t hash() const noexcept FLPURE {return FLSlice_Hash(*this);} + + /// Copies my contents to memory starting at `dst`, using `memcpy`. + void copyTo(void *dst) const noexcept {FLMemCpy(dst, buf, size);} + + /// Returns new malloc'ed slice containing same data. Call free() on it when done. + inline slice copy() const; + + // String conversions: + + explicit operator std::string() const {return std::string((const char*)buf, size);} + std::string asString() const {return (std::string)*this;} + + std::string hexString() const; + + /** Copies into a C string buffer of the given size. Result is always NUL-terminated and + will not overflow the buffer. Returns false if the slice was truncated. */ + inline bool toCString(char *buf, size_t bufSize) const noexcept; + + // FLSlice interoperability: + constexpr operator FLSlice () const noexcept {return {buf, size};} + +#ifdef SLICE_SUPPORTS_STRING_VIEW + // std::string_view interoperability: + constexpr pure_slice(string_view str) noexcept :pure_slice(str.data(), str.length()) {} + operator string_view() const noexcept STEPOVER {return string_view((const char*)buf, size);} +#endif + +#ifdef __APPLE__ + // Implementations in slice+CoreFoundation.cc and slice+ObjC.mm + explicit pure_slice(CFDataRef FL_NULLABLE data) noexcept; + CFStringRef createCFString() const; + CFDataRef createCFData() const; +# ifdef __OBJC__ + explicit pure_slice(NSData* FL_NULLABLE data) noexcept; + NSData* copiedNSData() const; + /** Creates an NSData using initWithBytesNoCopy and freeWhenDone:NO. + The data is not copied and does not belong to the NSData object, so make sure it + remains valid for the lifespan of that object!. */ + NSData* uncopiedNSData() const; + NSString* asNSString() const; + NSString* asNSString(NSMapTable* FL_NULLABLE sharedStrings) const; +# endif +#endif + + constexpr pure_slice(std::nullptr_t) noexcept :pure_slice() {} + constexpr pure_slice(const char* FL_NULLABLE str) noexcept :buf(str), size(_strlen(str)) {} + pure_slice(const std::string& str) noexcept :buf(&str[0]), size(str.size()) {} + + // Raw memory allocation. These throw std::bad_alloc on failure. + RETURNS_NONNULL inline static void* newBytes(size_t sz); + template RETURNS_NONNULL + static inline T* FL_NONNULL reallocBytes(T* FL_NULLABLE bytes, size_t newSz); + + protected: + constexpr pure_slice() noexcept :buf(nullptr), size(0) {} + inline constexpr pure_slice(const void* FL_NULLABLE b, size_t s) noexcept; + + inline void setBuf(const void *b) noexcept; + inline void setSize(size_t s) noexcept; + inline void set(const void * FL_NULLABLE, size_t) noexcept; + + // (Assignment must be custom because `buf` is declared as const/immutable.) + pure_slice& operator=(const pure_slice &s) noexcept {set(s.buf, s.size); return *this;} + static inline constexpr size_t _strlen(const char* FL_NULLABLE str) noexcept FLPURE; + // Throws std::bad_alloc, or if exceptions are disabled calls std::terminate() + [[noreturn]] static void failBadAlloc(); + // Sanity-checks `buf` and `size` + inline constexpr void checkValidSlice() const; + // Calls `assert_precondition(validAddress(addr))`, then returns `addr` + inline const void* check(const void *addr) const; + // Calls `assert_precondition(offset <= size)`, then returns `addr` + inline size_t check(size_t offset) const; + }; + + +#pragma mark - SLICE: + + + /** A simple pointer to a range of memory: `size` bytes starting at address `buf`. + \warning **No ownership is implied!** Just like a regular pointer, it's the client's + responsibility to ensure the memory buffer remains valid. + Some invariants: + * `buf` may be NULL, but only if `size` is zero; this is called `nullslice`. + * `size` may be zero with a non-NULL `buf`; that's called an "empty slice". */ + struct slice : public pure_slice { + constexpr slice() noexcept STEPOVER :pure_slice() {} + constexpr slice(std::nullptr_t) noexcept STEPOVER :pure_slice() {} + inline constexpr slice(nullslice_t) noexcept STEPOVER; + constexpr slice(const void* FL_NULLABLE b, size_t s) noexcept STEPOVER :pure_slice(b, s) {} + inline constexpr slice(const void* start, const void* end) noexcept STEPOVER; + inline constexpr slice(const alloc_slice&) noexcept STEPOVER; + + slice(const std::string& str) noexcept STEPOVER :pure_slice(str) {} + constexpr slice(const char* FL_NULLABLE str) noexcept STEPOVER :pure_slice(str) {} + + slice& operator= (alloc_slice&&) =delete; // Disallowed: might lead to ptr to freed buf + slice& operator= (const alloc_slice &s) noexcept {return *this = slice(s);} + slice& operator= (std::nullptr_t) noexcept {set(nullptr, 0); return *this;} + inline slice& operator= (nullslice_t) noexcept; + + /// Sets `size`. + void setSize(size_t s) noexcept {pure_slice::setSize(s);} + /// Sets `size`; asserts that the new size is not larger. + inline void shorten(size_t s); + + /// Adjusts `size` so that \ref end returns the given value. + void setEnd(const void* e) noexcept {setSize(pointerDiff(e, buf));} + /// Sets `buf` without moving the end, adjusting `size` accordingly. + inline void setStart(const void* s) noexcept; + /// Moves `buf` without moving the end, adjusting `size` accordingly. + void moveStart(ptrdiff_t delta) noexcept {set(offsetby(buf, delta), size - delta);} + /// Like \ref moveStart but returns false if the move is illegal. + bool checkedMoveStart(size_t delta) noexcept {if (size(static_cast(s)).retain();} + static void release(slice s) noexcept {static_cast(static_cast(s)).release();} + + private: + void assignFrom(pure_slice s) {set(s.buf, s.size);} + }; + + + + /** A slice whose `buf` may not be NULL. For use as a parameter type. */ + struct slice_NONNULL : public slice { + constexpr slice_NONNULL(const void* b, size_t s) :slice(b, s) {} + constexpr slice_NONNULL(slice s) :slice_NONNULL(s.buf, s.size) {} + constexpr slice_NONNULL(FLSlice s) :slice_NONNULL(s.buf,s.size) {} + constexpr slice_NONNULL(const char *str NONNULL) :slice(str) {} + slice_NONNULL(alloc_slice s) :slice_NONNULL(s.buf,s.size) {} + slice_NONNULL(const std::string &str) :slice_NONNULL(str.data(),str.size()) {} +#ifdef SLICE_SUPPORTS_STRING_VIEW + slice_NONNULL(string_view str) :slice_NONNULL(str.data(),str.size()) {} +#endif + slice_NONNULL(std::nullptr_t) =delete; + slice_NONNULL(nullslice_t) =delete; + }; + + + +#ifdef __APPLE__ + /** A slice holding the UTF-8 data of an NSString. If possible, it gets a pointer directly into + the NSString in O(1) time -- so don't modify or release the NSString while this is in scope. + Alternatively it will copy the string's UTF-8 into a small internal buffer, or allocate + a larger buffer on the heap (and free it in its destructor.) */ + struct nsstring_slice : public slice { + nsstring_slice(CFStringRef FL_NULLABLE); +# ifdef __OBJC__ + nsstring_slice(NSString* FL_NULLABLE str) :nsstring_slice((__bridge CFStringRef)str) { } +# endif + ~nsstring_slice(); + private: + long getBytes(CFStringRef, long lengthInChars); + char _local[127]; + bool _needsFree; + }; +#endif + + + /** Functor class for hashing the contents of a slice. + \note The below declarations of `std::hash` usually make it unnecessary to use this. */ + struct sliceHash { + std::size_t operator() (pure_slice const& s) const {return s.hash();} + }; + + + +#pragma mark - PURE_SLICE METHOD BODIES: + + + // like strlen but can run at compile time +#if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + inline constexpr size_t pure_slice::_strlen(const char* FL_NULLABLE str) noexcept { + if (!str) + return 0; + auto c = str; + while (*c) ++c; + return c - str; + } +#else + // (In C++11, constexpr functions couldn't contain loops; use (tail-)recursion instead) + inline constexpr size_t pure_slice::_strlen(const char* FL_NULLABLE str) noexcept { + return str ? _strlen(str, 0) : 0; + } + inline constexpr size_t pure_slice::_strlen(const char *str, size_t n) noexcept { + return *str ? _strlen(str + 1, n + 1) : n; + } +#endif + + + inline constexpr pure_slice::pure_slice(const void* FL_NULLABLE b, size_t s) noexcept + :buf(b), size(s) + { + checkValidSlice(); + } + + + inline void pure_slice::setBuf(const void *b) noexcept { + const_cast(buf) = b; + checkValidSlice(); + } + + inline void pure_slice::setSize(size_t s) noexcept { + const_cast(size) = s; + checkValidSlice(); + } + + inline void pure_slice::set(const void * FL_NULLABLE b, size_t s) noexcept { + const_cast(buf) = b; + const_cast(size) = s; + checkValidSlice(); + } + + + inline bool pure_slice::validAddress(const void * FL_NULLABLE addr) const noexcept { + // Note: unsigned comparison handles case when addr < buf + return size_t(_pointerDiff(addr, buf)) <= size; + } + + + inline bool pure_slice::containsAddress(const void * FL_NULLABLE addr) const noexcept { + return size_t(_pointerDiff(addr, buf)) < size; + } + + + inline bool pure_slice::containsAddressRange(pure_slice s) const noexcept { + return s.buf >= buf && s.end() <= end(); + } + + + inline constexpr void pure_slice::checkValidSlice() const { + assert_precondition(buf != nullptr || size == 0); + assert_precondition(size < (1ull << (8*sizeof(void*)-1))); // check accidental negative size + } + + + inline const void* pure_slice::check(const void *addr) const { + assert_precondition(validAddress(addr)); + return addr; + } + + inline size_t pure_slice::check(size_t offset) const { + assert_precondition(offset <= size); + return offset; + } + + + inline const void* pure_slice::offset(size_t o) const noexcept { + return (uint8_t*)buf + check(o); + } + + inline size_t pure_slice::offsetOf(const void* ptr NONNULL) const noexcept { + return pointerDiff(check(ptr), buf); + } + + + inline slice pure_slice::upTo(const void* pos) const noexcept { + return slice(buf, check(pos)); + } + + inline slice pure_slice::from(const void* pos) const noexcept { + return slice(check(pos), end()); + } + + inline slice pure_slice::upTo(size_t off) const noexcept { + return slice(buf, check(off)); + } + + inline slice pure_slice::from(size_t off) const noexcept { + return slice(offset(check(off)), end()); + } + + inline const uint8_t& pure_slice::operator[](size_t off) const noexcept { + assert_precondition(off < size); + return ((const uint8_t*)buf)[off]; + } + + inline slice pure_slice::operator()(size_t off, size_t nBytes) const noexcept { + assert_precondition(off + nBytes <= size); + return slice(offset(off), nBytes); + } + + + inline bool pure_slice::toCString(char *str, size_t bufSize) const noexcept { + size_t n = std::min(size, bufSize-1); + FLMemCpy(str, buf, n); + str[n] = 0; + return n == size; + } + + + inline std::string pure_slice::hexString() const { + static const char kDigits[17] = "0123456789abcdef"; + std::string result; + result.reserve(2 * size); + for (size_t i = 0; i < size; i++) { + uint8_t byte = (*this)[(unsigned)i]; + result += kDigits[byte >> 4]; + result += kDigits[byte & 0xF]; + } + return result; + } + + +#pragma mark COMPARISON & FIND: + + + __hot + inline int pure_slice::caseEquivalentCompare(pure_slice b) const noexcept { + size_t minSize = std::min(size, b.size); + for (size_t i = 0; i < minSize; i++) { + if ((*this)[i] != b[i]) { + int cmp = ::tolower((*this)[i]) - ::tolower(b[i]); + if (cmp != 0) + return cmp; + } + } + return (int)size - (int)b.size; + } + + + __hot + inline bool pure_slice::caseEquivalent(pure_slice b) const noexcept { + if (size != b.size) + return false; + for (size_t i = 0; i < size; i++) + if (::tolower((*this)[i]) != ::tolower(b[i])) + return false; + return true; + } + + + __hot + inline slice pure_slice::find(pure_slice target) const noexcept { + char* src = (char *)buf; + char* search = (char *)target.buf; + char* found = std::search(src, src + size, search, search + target.size); + if(found == src + size) { + return nullslice; + } + + return {found, target.size}; + } + + + inline bool pure_slice::containsBytes(pure_slice bytes) const noexcept { + return bool(find(bytes)); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByte(uint8_t b) const { + if (_usuallyFalse(size == 0)) + return nullptr; + return (const uint8_t*)::memchr(buf, b, size); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByteOrEnd(uint8_t byte) const noexcept { + auto result = findByte(byte); + return result ? result : (const uint8_t*)end(); + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findAnyByteOf(pure_slice targetBytes) const noexcept { + // this could totally be optimized, if it turns out to matter... + const void* result = nullptr; + for (size_t i = 0; i < targetBytes.size; ++i) { + auto r = findByte(targetBytes[i]); + if (r && (!result || r < result)) + result = r; + } + return (const uint8_t*)result; + } + + + __hot + inline const uint8_t* FL_NULLABLE pure_slice::findByteNotIn(pure_slice targetBytes) const noexcept { + for (auto c = (const uint8_t*)buf; c != end(); ++c) { + if (!targetBytes.findByte(*c)) + return c; + } + return nullptr; + } + + + inline bool pure_slice::hasPrefix(pure_slice s) const noexcept { + return s.size > 0 && size >= s.size && ::memcmp(buf, s.buf, s.size) == 0; + } + + + inline bool pure_slice::hasSuffix(pure_slice s) const noexcept { + return s.size > 0 && size >= s.size + && ::memcmp(offsetby(buf, size - s.size), s.buf, s.size) == 0; + } + + +#pragma mark MEMORY ALLOCATION + + + /** Raw memory allocation. Just like malloc but throws/terminates on failure. */ + RETURNS_NONNULL + inline void* pure_slice::newBytes(size_t sz) { + void* result = ::malloc(sz); + if (_usuallyFalse(!result)) failBadAlloc(); + return result; + } + + + /** Like realloc but throws/terminates on failure. */ + template + RETURNS_NONNULL + inline T* FL_NONNULL pure_slice::reallocBytes(T* FL_NULLABLE bytes, size_t newSz) { + T* newBytes = (T*)::realloc(bytes, newSz); + if (_usuallyFalse(!newBytes)) failBadAlloc(); + return newBytes; + } + + inline slice pure_slice::copy() const { + if (buf == nullptr) + return nullslice; + void* copied = newBytes(size); + FLMemCpy(copied, buf, size); + return slice(copied, size); + } + + + [[noreturn]] + inline void pure_slice::failBadAlloc() { +#ifdef __cpp_exceptions + throw std::bad_alloc(); +#else + ::fputs("*** FATAL ERROR: heap allocation failed (fleece/slice.cc) ***\n", stderr); + std::terminate(); +#endif + } + + +#pragma mark - SLICE METHOD BODIES: + + + inline constexpr slice::slice(nullslice_t) noexcept :pure_slice() {} + inline constexpr slice::slice(const alloc_slice &s) noexcept :pure_slice(s) { } + + + inline constexpr slice::slice(const void* start, const void* end) noexcept + :slice(start, pointerDiff(end, start)) + { + assert_precondition(end >= start); + } + + + inline slice& slice::operator= (nullslice_t) noexcept { + set(nullptr, 0); + return *this; + } + + + inline slice::operator FLSliceResult () const noexcept { + return FLSliceResult(alloc_slice(*this)); + } + + + inline void slice::shorten(size_t s) { + setSize(check(s)); + } + + + inline void slice::setStart(const void *s) noexcept { + check(s); + set(s, pointerDiff(end(), s)); + } + + +#pragma mark - ALLOC_SLICE METHOD BODIES: + + + __hot + inline alloc_slice::alloc_slice(size_t sz) + :alloc_slice(FLSliceResult_New(sz)) + { + if (_usuallyFalse(!buf)) + failBadAlloc(); + } + + + __hot + inline alloc_slice::alloc_slice(pure_slice s) + :alloc_slice(FLSlice_Copy(s)) + { + if (_usuallyFalse(!buf) && s.buf) + failBadAlloc(); + } + + + inline alloc_slice alloc_slice::nullPaddedString(pure_slice str) { + // Leave a trailing null byte after the end, so it can be used as a C string + alloc_slice a(str.size + 1); + str.copyTo((void*)a.buf); + ((char*)a.buf)[str.size] = '\0'; + a.shorten(str.size); // the null byte is not part of the slice + return a; + } + + + __hot + inline alloc_slice& alloc_slice::operator=(const alloc_slice& s) noexcept { + if (_usuallyTrue(s.buf != buf)) { + release(); + assignFrom(s); + retain(); + } + return *this; + } + + + __hot + inline alloc_slice& alloc_slice::operator=(FLHeapSlice s) noexcept { + if (_usuallyTrue(s.buf != buf)) { + release(); + assignFrom(slice(s)); + retain(); + } + return *this; + } + + + inline void alloc_slice::resize(size_t newSize) { + if (newSize == size) { + return; + } else if (buf == nullptr) { + reset(newSize); + } else { + // We don't realloc the current buffer; that would affect other alloc_slice objects + // sharing the buffer, and possibly confuse them. Instead, alloc a new buffer & copy. + alloc_slice newSlice(newSize); + FLMemCpy((void*)newSlice.buf, buf, std::min(size, newSize)); + *this = std::move(newSlice); + } + } + + + inline void alloc_slice::append(pure_slice source) { + if (_usuallyFalse(source.size == 0)) + return; + const void *src = source.buf; + size_t oldSize = size; + if (_usuallyFalse(containsAddress(src))) { + // Edge case, where I contain the source bytes: update source address after realloc + size_t srcOff = size_t(pointerDiff(src, buf)); + resize(oldSize + source.size); + src = offset(srcOff); + } else { + resize(oldSize + source.size); + } + ::memcpy((void*)offset(oldSize), src, source.size); // already checked source.size > 0 + } + + + inline void alloc_slice::shorten(size_t s) { + pure_slice::setSize(check(s)); + } + +} + + +namespace std { + // Declare the default hash function for `slice` and `alloc_slice`. This allows them to be + // used in hashed collections like `std::unordered_map` and `std::unordered_set`. + template<> struct hash { + std::size_t operator() (fleece::pure_slice const& s) const {return s.hash();} + }; + template<> struct hash { + std::size_t operator() (fleece::pure_slice const& s) const {return s.hash();} + }; +} + + +FL_ASSUME_NONNULL_END + +#endif // _FLEECE_SLICE_HH diff --git a/libcblite_enterprise/lib/aarch64-linux-android/libcblite.so b/libcblite_enterprise/lib/aarch64-linux-android/libcblite.so new file mode 100644 index 0000000..ce78937 Binary files /dev/null and b/libcblite_enterprise/lib/aarch64-linux-android/libcblite.so differ diff --git a/libcblite_enterprise/lib/aarch64-linux-android/libcblite.stripped.so b/libcblite_enterprise/lib/aarch64-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..8793334 Binary files /dev/null and b/libcblite_enterprise/lib/aarch64-linux-android/libcblite.stripped.so differ diff --git a/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.so b/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.so new file mode 100644 index 0000000..02a6ed1 Binary files /dev/null and b/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.so differ diff --git a/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.stripped.so b/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.stripped.so new file mode 100755 index 0000000..fed0fdb Binary files /dev/null and b/libcblite_enterprise/lib/arm-linux-androideabi/libcblite.stripped.so differ diff --git a/libcblite_enterprise/lib/i686-linux-android/libcblite.so b/libcblite_enterprise/lib/i686-linux-android/libcblite.so new file mode 100644 index 0000000..2c0f6e9 Binary files /dev/null and b/libcblite_enterprise/lib/i686-linux-android/libcblite.so differ diff --git a/libcblite_enterprise/lib/i686-linux-android/libcblite.stripped.so b/libcblite_enterprise/lib/i686-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..11a351e Binary files /dev/null and b/libcblite_enterprise/lib/i686-linux-android/libcblite.stripped.so differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/Info.plist b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/Info.plist new file mode 100644 index 0000000..6079b74 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/Info.plist @@ -0,0 +1,44 @@ + + + + + AvailableLibraries + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64 + LibraryPath + CouchbaseLite.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + CouchbaseLite.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite new file mode 100755 index 0000000..16f85da Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h new file mode 100644 index 0000000..d7866eb --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include +#include +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h new file mode 100644 index 0000000..a2d6eaa --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..35941b5 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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 +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; /// +#include + +CBL_CAPI_BEGIN + +/** \defgroup database Database + @{ + A \ref CBLDatabase is both a filesystem object and a container for documents. + */ + +#ifdef COUCHBASE_ENTERPRISE + +#ifdef __APPLE__ +#pragma mark - Database Extension +#endif + +/** \name Database Extension + @{ */ + +/** ENTERPRISE EDITION ONLY + + Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @param outError On return, will be set to the error that occurred. + @return True on success, false if there was an error. + @note Must be called before opening a database that intends to use the vector search extension. */ +bool CBL_EnableVectorSearch(FLString path, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +#ifdef __APPLE__ +#pragma mark - CONFIGURATION +#endif + +/** \name Database configuration + @{ */ + +#ifdef COUCHBASE_ENTERPRISE +/** Database encryption algorithms (available only in the Enterprise Edition). */ +typedef CBL_ENUM(uint32_t, CBLEncryptionAlgorithm) { + kCBLEncryptionNone = 0, ///< No encryption (default) + kCBLEncryptionAES256 ///< AES with 256-bit key +}; + +/** Encryption key sizes (in bytes). */ +typedef CBL_ENUM(uint64_t, CBLEncryptionKeySize) { + kCBLEncryptionKeySizeAES256 = 32, ///< Key size for \ref kCBLEncryptionAES256 +}; + +/** Encryption key specified in a \ref CBLDatabaseConfiguration. */ +typedef struct { + CBLEncryptionAlgorithm algorithm; ///< Encryption algorithm + uint8_t bytes[32]; ///< Raw key data +} CBLEncryptionKey; +#endif + +/** Database configuration options. */ +typedef struct { + FLString directory; ///< The parent directory of the database +#ifdef COUCHBASE_ENTERPRISE + CBLEncryptionKey encryptionKey; ///< The database's encryption key (if any) +#endif + /** As Couchbase Lite normally configures its databases, There is a very + small (though non-zero) chance that a power failure at just the wrong + time could cause the most recently committed transaction's changes to + be lost. This would cause the database to appear as it did immediately + before that transaction. + + Setting this mode true ensures that an operating system crash or + power failure will not cause the loss of any data. FULL synchronous + is very safe but it is also dramatically slower. */ + bool fullSync; + + /** + Disable memory-mapped I/O. By default, memory-mapped I/O is enabled. + Disabling it may affect database performance. Typically, there is no need to modify this setting. + @note Memory-mapped I/O is always disabled on macOS to prevent database corruption, + so setting mmapDisabled value has no effect on the macOS platform. */ + bool mmapDisabled; +} CBLDatabaseConfiguration; + +/** Returns the default database configuration. */ +CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Derives an encryption key from a password. If your UI uses passwords, call this function to + create the key used to encrypt the database. It is designed for security, and deliberately + runs slowly to make brute-force attacks impractical. + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPassword(CBLEncryptionKey *key, FLString password) CBLAPI; + +/** VOLATILE API: Derives an encryption key from a password in a way that is + compatible with certain variants of Couchbase Lite in which a slightly different + hashing algorithm is used. The same notes apply as in CBLEncryptionKey_FromPassword + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPasswordOld(CBLEncryptionKey *key, FLString password) CBLAPI; +#endif + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - FILE OPERATIONS +#endif +/** \name Database file operations + @{ + These functions operate on database files without opening them. + */ + +/** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ +bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; + +/** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On return, will be set to the error that occurred, if applicable. + @note While a database is open, one or more of its files may be in use. Attempting to copy a file, while it is in use, will fail. We recommend that you close a database before attempting to copy it. */ +bool CBL_CopyDatabase(FLString fromPath, + FLString toName, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a database file. If the database file is open, an error is returned. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. + @param outError On return, will be set to the error that occurred, or a 0 code if no error. + @return True if the database was deleted, false if it doesn't exist or deletion failed. + (You can tell the last two cases apart by looking at \p outError.)*/ +bool CBL_DeleteDatabase(FLString name, + FLString inDirectory, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - LIFECYCLE +#endif +/** \name Database lifecycle + @{ + Opening, closing, and managing open databases. + */ + +/** Opens a database, or creates it if it doesn't exist yet, returning a new \ref CBLDatabase + instance. + It's OK to open the same database file multiple times. Each \ref CBLDatabase instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On failure, the error will be written here. + @return The new database object, or NULL on failure. */ +_cbl_warn_unused +CBLDatabase* _cbl_nullable CBLDatabase_Open(FLSlice name, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Closes an open database. */ +bool CBLDatabase_Close(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDatabase*, Database); + +/** Closes and deletes a database. If there are any other connections to the database, + an error is returned. */ +bool CBLDatabase_Delete(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Begins a transaction. You **must** later call \ref + CBLDatabase_EndTransaction to commit or abort the transaction. + @note Multiple writes are much faster when grouped in a transaction. + @note Changes will not be visible to other CBLDatabase instances on the same database until + the transaction ends. + @note Transactions can nest. Changes are not committed until the outer transaction ends. */ +bool CBLDatabase_BeginTransaction(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Ends a transaction, either committing or aborting. */ +bool CBLDatabase_EndTransaction(CBLDatabase*, + bool commit, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Encrypts or decrypts a database, or changes its encryption key. + + If \p newKey is NULL, or its \p algorithm is \ref kCBLEncryptionNone, the database will be decrypted. + Otherwise the database will be encrypted with that key; if it was already encrypted, it will be + re-encrypted with the new key.*/ +bool CBLDatabase_ChangeEncryptionKey(CBLDatabase*, + const CBLEncryptionKey* _cbl_nullable newKey, + CBLError* outError) CBLAPI; +#endif + +/** Maintenance Type used when performing database maintenance. */ +typedef CBL_ENUM(uint32_t, CBLMaintenanceType) { + /// Compact the database file and delete unused attachments + kCBLMaintenanceTypeCompact = 0, + + /// Rebuild the entire database's indexes. + kCBLMaintenanceTypeReindex, + + /// Check for the database’s corruption. If found, an error will be returned + kCBLMaintenanceTypeIntegrityCheck, + + /// Partially scan indexes to gather database statistics that help optimize queries. + /// This operation is also performed automatically when closing the database. + kCBLMaintenanceTypeOptimize, + + /// Fully scans all indexes to gather database statistics that help optimize queries. + /// This may take some time, depending on the size of the indexes, but it doesn't have to + /// be redone unless the database changes drastically, or new indexes are created. + kCBLMaintenanceTypeFullOptimize +}; + +/** Performs database maintenance. */ +bool CBLDatabase_PerformMaintenance(CBLDatabase* db, + CBLMaintenanceType type, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - ACCESSORS +#endif +/** \name Database accessors + @{ + Getting information about a database. + */ + +/** Returns the database's name. */ +FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; + +/** Returns the database's full filesystem path, or null slice if the database is closed or deleted. */ +_cbl_warn_unused +FLStringResult CBLDatabase_Path(const CBLDatabase*) CBLAPI; + +/** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d1c39a9 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h new file mode 100644 index 0000000..c42809b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h new file mode 100644 index 0000000..4665b9a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h new file mode 100644 index 0000000..2c2c1b9 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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 + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h new file mode 100644 index 0000000..8032b5a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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 + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h new file mode 100644 index 0000000..625e736 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h new file mode 100644 index 0000000..321b424 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h new file mode 100644 index 0000000..79bed5a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h new file mode 100644 index 0000000..b26350e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h new file mode 100644 index 0000000..25ad9aa --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h new file mode 100644 index 0000000..1c61c87 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + +CBL_CAPI_BEGIN + +/** \defgroup scope Scope + @{ + A \ref CBLScope represents a scope or namespace of the collections. + + The scope implicitly exists when there is at least one collection created under the scope. + The default scope is exceptional in that it will always exists even there are no collections + under it. + + ## `CBLScope` Lifespan + `CBLScope` is ref-counted. Same as the CBLCollection, the CBLScope objects + retrieved from the database must be released after you are done using them. + When the database is closed or released, the scope objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with + \ref kCBLErrorNotOpen error result. */ + +CBL_REFCOUNTED(CBLScope*, Scope); + +/** \name Default Scope Name + @{ + The default scope name constant. + */ + +/** The default scope's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultScopeName; + +/** @} */ + +/** \name Scope Accessors + @{ + Getting information about a scope. + */ + +/** Returns the name of the scope. + @param scope The scope. + @return The name of the scope. */ +FLString CBLScope_Name(const CBLScope* scope) CBLAPI; + +/** Returns the scope's database. + @note The database object is owned by the scope object; you do not need to release it. + @param scope The scope. + @return The database of the scope. */ +CBLDatabase* CBLScope_Database(const CBLScope* scope) CBLAPI; + +/** @} */ + +/** \name Collections + @{ + Accessing the collections under the scope. + */ + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param scope The scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLScope_CollectionNames(const CBLScope* scope, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing collection in the scope with the given name. + @note You are responsible for releasing the returned collection. + @param scope The scope. + @param collectionName The name of the collection. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLScope_Collection(const CBLScope* scope, + FLString collectionName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h new file mode 100644 index 0000000..0612778 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -0,0 +1,134 @@ +// +// CBL_Compat.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +#ifdef _MSC_VER + #include + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h new file mode 100644 index 0000000..7c5c504 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +#define COUCHBASE_ENTERPRISE +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "6728898+e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:23:54Z" diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h new file mode 100644 index 0000000..bce263b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h new file mode 100644 index 0000000..5b57154 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..5e2489e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h new file mode 100644 index 0000000..d1699bf --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..49f4747 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7ce213e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..9dd697f --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..677d3e4 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..9ed12e3 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..1072e64 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h new file mode 100644 index 0000000..9713584 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h new file mode 100644 index 0000000..874172f --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h new file mode 100644 index 0000000..ce14e29 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h new file mode 100644 index 0000000..6476347 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include +#endif + +#endif // _FLEECE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist new file mode 100644 index 0000000..9ae8222 Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap new file mode 100644 index 0000000..42fd88e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap @@ -0,0 +1,38 @@ +framework module CouchbaseLite { + header "CouchbaseLite.h" + header "CBL_Compat.h" + header "CBL_Edition.h" + header "CBLBase.h" + header "CBLBlob.h" + header "CBLCollection.h" + header "CBLDatabase.h" + header "CBLDefaults.h" + header "CBLDocument.h" + header "CBLEncryptable.h" + header "CBLLog.h" + header "CBLPlatform.h" + header "CBLPrediction.h" + header "CBLQuery.h" + header "CBLQueryIndex.h" + header "CBLQueryIndexTypes.h" + header "CBLQueryTypes.h" + header "CBLReplicator.h" + header "CBLScope.h" + + module Fleece { + header "Fleece.h" + header "FLBase.h" + header "FLCollections.h" + header "FLDeepIterator.h" + header "FLDoc.h" + header "Fleece+CoreFoundation.h" + header "FLEncoder.h" + header "FLExpert.h" + header "FLJSON.h" + header "FLKeyPath.h" + header "FLMutable.h" + header "FLSlice.h" + header "FLValue.h" + header "CompilerSupport.h" + } +} diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..6cb5e91 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist new file mode 100644 index 0000000..dedf43b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.com.couchbase.CouchbaseLite-C + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 3.2.1 + CFBundleVersion + 9 + + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite new file mode 100644 index 0000000..473e588 Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite new file mode 100755 index 0000000..578fb25 Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h new file mode 100644 index 0000000..d7866eb --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h @@ -0,0 +1,289 @@ +// +// CBLBase.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#ifdef CMAKE +#include "cbl_config.h" +#endif + +#include +#include +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup errors Errors + @{ + Types and constants for communicating errors from API calls. */ + +/** Error domains, serving as namespaces for numeric error codes. */ +typedef CBL_ENUM(uint8_t, CBLErrorDomain) { + kCBLDomain = 1, ///< code is a Couchbase Lite error code; see \ref CBLErrorCode + kCBLPOSIXDomain, ///< code is a POSIX `errno`; see "errno.h" + kCBLSQLiteDomain, ///< code is a SQLite error; see "sqlite3.h" + kCBLFleeceDomain, ///< code is a Fleece error; see "FleeceException.h" + kCBLNetworkDomain, ///< code is a network error; see \ref CBLNetworkErrorCode + kCBLWebSocketDomain, ///< code is a WebSocket close code (1000...1015) or HTTP error (300..599) +}; + +/** Couchbase Lite error codes, in the CBLDomain. */ +typedef CBL_ENUM(int32_t, CBLErrorCode) { + kCBLErrorAssertionFailed = 1, ///< Internal assertion failure + kCBLErrorUnimplemented, ///< Oops, an unimplemented API call + kCBLErrorUnsupportedEncryption, ///< Unsupported encryption algorithm + kCBLErrorBadRevisionID, ///< Invalid revision ID syntax + kCBLErrorCorruptRevisionData, ///< Revision contains corrupted/unreadable data + kCBLErrorNotOpen, ///< Database/KeyStore/index is not open + kCBLErrorNotFound, ///< Document not found + kCBLErrorConflict, ///< Document update conflict + kCBLErrorInvalidParameter, ///< Invalid function parameter or struct value + kCBLErrorUnexpectedError, /*10*/ ///< Internal unexpected C++ exception + kCBLErrorCantOpenFile, ///< Database file can't be opened; may not exist + kCBLErrorIOError, ///< File I/O error + kCBLErrorMemoryError, ///< Memory allocation failed (out of memory?) + kCBLErrorNotWriteable, ///< File is not writeable + kCBLErrorCorruptData, ///< Data is corrupted + kCBLErrorBusy, ///< Database is busy/locked + kCBLErrorNotInTransaction, ///< Function must be called while in a transaction + kCBLErrorTransactionNotClosed, ///< Database can't be closed while a transaction is open + kCBLErrorUnsupported, ///< Operation not supported in this database + kCBLErrorNotADatabaseFile,/*20*/ ///< File is not a database, or encryption key is wrong + kCBLErrorWrongFormat, ///< Database exists but not in the format/storage requested + kCBLErrorCrypto, ///< Encryption/decryption error + kCBLErrorInvalidQuery, ///< Invalid query + kCBLErrorMissingIndex, ///< No such index, or query requires a nonexistent index + kCBLErrorInvalidQueryParam, ///< Unknown query param name, or param number out of range + kCBLErrorRemoteError, ///< Unknown error from remote server + kCBLErrorDatabaseTooOld, ///< Database file format is older than what I can open + kCBLErrorDatabaseTooNew, ///< Database file format is newer than what I can open + kCBLErrorBadDocID, ///< Invalid document ID + kCBLErrorCantUpgradeDatabase,/*30*/ ///< DB can't be upgraded (might be unsupported dev version) +}; + +/** Network error codes, in the CBLNetworkDomain. */ +typedef CBL_ENUM(int32_t, CBLNetworkErrorCode) { + kCBLNetErrDNSFailure = 1, ///< DNS lookup failed + kCBLNetErrUnknownHost, ///< DNS server doesn't know the hostname + kCBLNetErrTimeout, ///< No response received before timeout + kCBLNetErrInvalidURL, ///< Invalid URL + kCBLNetErrTooManyRedirects, ///< HTTP redirect loop + kCBLNetErrTLSHandshakeFailed, ///< Low-level error establishing TLS + kCBLNetErrTLSCertExpired, ///< Server's TLS certificate has expired + kCBLNetErrTLSCertUntrusted, ///< Cert isn't trusted for other reason + kCBLNetErrTLSClientCertRequired, ///< Server requires client to have a TLS certificate + kCBLNetErrTLSClientCertRejected, ///< Server rejected my TLS client certificate + kCBLNetErrTLSCertUnknownRoot, ///< Self-signed cert, or unknown anchor cert + kCBLNetErrInvalidRedirect, ///< Attempted redirect to invalid URL + kCBLNetErrUnknown, ///< Unknown networking error + kCBLNetErrTLSCertRevoked, ///< Server's cert has been revoked + kCBLNetErrTLSCertNameMismatch, ///< Server cert's name does not match DNS name +}; + + +/** A struct holding information about an error. It's declared on the stack by a caller, and + its address is passed to an API function. If the function's return value indicates that + there was an error (usually by returning NULL or false), then the CBLError will have been + filled in with the details. */ +typedef struct { + CBLErrorDomain domain; ///< Domain of errors; a namespace for the `code`. + int code; ///< Error code, specific to the domain. 0 always means no error. + unsigned internal_info; // do not use or modify +} CBLError; + +/** Returns a message describing an error. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +FLSliceResult CBLError_Message(const CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \defgroup other_types Other Types + @{ */ + +/** A date/time representation used for document expiration (and in date/time queries.) + Measured in milliseconds since the Unix epoch (1/1/1970, midnight UTC.) */ +typedef int64_t CBLTimestamp; + + +/** Returns the current time, in milliseconds since 1/1/1970. */ +CBLTimestamp CBL_Now(void) CBLAPI; + +/** @} */ + + + +/** \defgroup refcounting Reference Counting + @{ + Couchbase Lite "objects" are reference-counted; the functions below are the shared + _retain_ and _release_ operations. (But there are type-safe equivalents defined for each + class, so you can call \ref CBLDatabase_Release() on a database, for instance, without having to + type-cast.) + + API functions that **create** a ref-counted object (typically named `..._New()` or `..._Create()`) + return the object with a ref-count of 1; you are responsible for releasing the reference + when you're done with it, or the object will be leaked. + + Other functions that return an **existing** ref-counted object do not modify its ref-count. + You do _not_ need to release such a reference. But if you're keeping a reference to the object + for a while, you should retain the reference to ensure it stays alive, and then release it when + finished (to balance the retain.) + */ + +typedef struct CBLRefCounted CBLRefCounted; + +/** Increments an object's reference-count. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Retain` */ +CBLRefCounted* CBL_Retain(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Decrements an object's reference-count, freeing the object if the count hits zero. + Usually you'll call one of the type-safe synonyms specific to the object type, + like \ref CBLDatabase_Release. */ +void CBL_Release(CBLRefCounted* _cbl_nullable) CBLAPI; + +/** Returns the total number of Couchbase Lite objects. Useful for leak checking. */ +unsigned CBL_InstanceCount(void) CBLAPI; + +/** Logs the class and address of each Couchbase Lite object. Useful for leak checking. + @note May only be functional in debug builds of Couchbase Lite. */ +void CBL_DumpInstances(void) CBLAPI; + +// Declares retain/release functions for TYPE. For internal use only. +#define CBL_REFCOUNTED(TYPE, NAME) \ + static inline const TYPE CBL##NAME##_Retain(const TYPE _cbl_nullable t) \ + {return (const TYPE)CBL_Retain((CBLRefCounted*)t);} \ + static inline void CBL##NAME##_Release(const TYPE _cbl_nullable t) {CBL_Release((CBLRefCounted*)t);} + +/** @} */ + + + +/** \defgroup database Database + @{ */ +/** A connection to an open database. */ +typedef struct CBLDatabase CBLDatabase; +/** @} */ + +/** \defgroup scope Scope + @{ */ +/** A collection's scope. */ +typedef struct CBLScope CBLScope; +/** @} */ + +/** \defgroup collection Collection + @{ */ +/** A collection, a document container. */ +typedef struct CBLCollection CBLCollection; +/** @} */ + +/** \defgroup documents Documents + @{ */ +/** An in-memory copy of a document. + CBLDocument objects can be mutable or immutable. Immutable objects are referenced by _const_ + pointers; mutable ones by _non-const_ pointers. This prevents you from accidentally calling + a mutable-document function on an immutable document. */ +typedef struct CBLDocument CBLDocument; +/** @} */ + +/** \defgroup blobs Blobs + @{ */ +/** A binary data value associated with a \ref CBLDocument. */ +typedef struct CBLBlob CBLBlob; +/** @} */ + +/** \defgroup query Query + @{ */ +/** A compiled database query. */ +typedef struct CBLQuery CBLQuery; + +/** An iterator over the rows resulting from running a query. */ +typedef struct CBLResultSet CBLResultSet; +/** @} */ + +/** \defgroup index Index + @{ */ +/** A query index. */ +typedef struct CBLQueryIndex CBLQueryIndex; + +#ifdef COUCHBASE_ENTERPRISE +typedef struct CBLIndexUpdater CBLIndexUpdater; +#endif +/** @} */ + +/** \defgroup replication Replication + @{ */ +/** A background task that syncs a \ref CBLDatabase with a remote server or peer. */ +typedef struct CBLReplicator CBLReplicator; +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \defgroup encryptables Encryptables + @{ */ +/** An encryptable value. The encryptable values will be encrypted by a push replicator via the + specified property encryptor callback when the document is push to the remote server. + Likewise, the encryptable values will be decrypted by a pull replicator via the specified + property decryptor callback when the document is pulled from the remote server. */ +typedef struct CBLEncryptable CBLEncryptable; +/** @} */ +#endif + +/** \defgroup listeners Listeners + @{ + Every API function that registers a listener callback returns an opaque token representing + the registered callback. To unregister any type of listener, call \ref CBLListener_Remove. + + The steps to creating a listener are: + 1. Define the type of contextual information the callback needs. This is usually one of + your objects, or a custom struct. + 2. Implement the listener function: + - The parameters and return value must match the callback defined in the API. + - The first parameter is always a `void*` that points to your contextual + information, so cast that to the actual pointer type. + - **The function may be called on a background thread!** And since the CBL API is not itself + thread-safe, you'll need to take special precautions if you want to call the API + from your listener, such as protecting all of your calls (inside and outside the + listener) with a mutex. It's safer to use \ref CBLDatabase_BufferNotifications to + schedule listener callbacks to a time of your own choosing, such as your thread's + event loop; see that function's docs for details. + 3. To register the listener, call the relevant `AddListener` function. + - The parameters will include the CBL object to observe, the address of your listener + function, and a pointer to the contextual information. (That pointer needs to remain + valid for as long as the listener is registered, so it can't be a pointer to a local + variable.) + - The return value is a \ref CBLListenerToken pointer; save that. + 4. To unregister the listener, pass the \ref CBLListenerToken to \ref CBLListener_Remove. + - You **must** unregister the listener before the contextual information pointer is + invalidated, e.g. before freeing the object it points to. + */ + +/** An opaque 'cookie' representing a registered listener callback. + It's returned from functions that register listeners, and used to remove a listener by + calling \ref CBLListener_Remove. */ +typedef struct CBLListenerToken CBLListenerToken; + +/** Removes a listener callback, given the token that was returned when it was added. */ +void CBLListener_Remove(CBLListenerToken* _cbl_nullable) CBLAPI; + + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h new file mode 100644 index 0000000..a2d6eaa --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h @@ -0,0 +1,289 @@ +// +// CBLBlob.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup blobs Blobs + @{ + A \ref CBLBlob is a binary data blob associated with a document. + + The content of the blob is not stored in the document, but externally in the database. + It is loaded only on demand, and can be streamed. Blobs can be arbitrarily large, although + Sync Gateway will only accept blobs under 20MB. + + The document contains only a blob reference: a dictionary with the special marker property + `"@type":"blob"`, and another property `digest` whose value is a hex SHA-1 digest of the + blob's data. This digest is used as the key to retrieve the blob data. + The dictionary usually also has the property `length`, containing the blob's length in bytes, + and it may have the property `content_type`, containing a MIME type. + + A \ref CBLBlob object acts as a proxy for such a dictionary in a \ref CBLDocument. Once + you've loaded a document and located the \ref FLDict holding the blob reference, call + \ref FLDict_GetBlob on it to create a \ref CBLBlob object you can call. + The object has accessors for the blob's metadata and for loading the data itself. + + To create a new blob from in-memory data, call \ref CBLBlob_CreateWithData, then call + \ref FLSlot_SetBlob to add the \ref CBLBlob to a mutable array or dictionary in the + document. For example: + + FLSlot_SetBlob(FLMutableDict_Set(properties, key), blob); + + To create a new blob from a stream, call \ref CBLBlobWriter_Create to create a + \ref CBLBlobWriteStream, then make one or more calls to \ref CBLBlobWriter_Write to write + data to the blob, then finally call \ref CBLBlob_CreateWithStream to create the blob. + To store the blob into a document, do as in the previous paragraph. + + */ + + + CBL_PUBLIC extern const FLSlice kCBLBlobType; ///< `"blob"` + CBL_PUBLIC extern const FLSlice kCBLBlobDigestProperty; ///< `"digest"` + CBL_PUBLIC extern const FLSlice kCBLBlobLengthProperty; ///< `"length"` + CBL_PUBLIC extern const FLSlice kCBLBlobContentTypeProperty; ///< `"content_type"` + + + CBL_REFCOUNTED(CBLBlob*, Blob); + + + /** Returns true if a dictionary in a document is a blob reference. + If so, you can call \ref FLDict_GetBlob to access it. + @note This function tests whether the dictionary has a `@type` property, + whose value is `"blob"`. */ + bool FLDict_IsBlob(FLDict _cbl_nullable) CBLAPI; + + /** Returns a CBLBlob object corresponding to a blob dictionary in a document. + @param blobDict A dictionary in a document. + @return A CBLBlob instance for this blob, or NULL if the dictionary is not a blob. */ + const CBLBlob* _cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - BLOB METADATA: +#endif + + /** Returns the length in bytes of a blob's content (from its `length` property). */ + uint64_t CBLBlob_Length(const CBLBlob*) CBLAPI; + + /** Returns a blob's MIME type, if its metadata has a `content_type` property. */ + FLString CBLBlob_ContentType(const CBLBlob*) CBLAPI; + + /** Returns the cryptographic digest of a blob's content (from its `digest` property). */ + FLString CBLBlob_Digest(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata. This includes the `digest`, `length`, `content_type`, + and `@type` properties, as well as any custom ones that may have been added. */ + FLDict CBLBlob_Properties(const CBLBlob*) CBLAPI; + + /** Returns a blob's metadata as JSON. */ + _cbl_warn_unused + FLStringResult CBLBlob_CreateJSON(const CBLBlob* blob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + + /** Reads the blob's content into memory and returns them. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ + _cbl_warn_unused + FLSliceResult CBLBlob_Content(const CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + + /** A stream for reading a blob's content. */ + typedef struct CBLBlobReadStream CBLBlobReadStream; + + /** Opens a stream for reading a blob's content. */ + _cbl_warn_unused + CBLBlobReadStream* _cbl_nullable CBLBlob_OpenContentStream(const CBLBlob* blob, + CBLError* _cbl_nullable) CBLAPI; + + /** Reads data from a blob. + @param stream The stream to read from. + @param dst The address to copy the read data to. + @param maxLength The maximum number of bytes to read. + @param outError On failure, an error will be stored here if non-NULL. + @return The actual number of bytes read; 0 if at EOF, -1 on error. */ + int CBLBlobReader_Read(CBLBlobReadStream* stream, + void *dst, + size_t maxLength, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Defines the interpretation of `offset` in \ref CBLBlobReader_Seek. */ + typedef CBL_ENUM(uint8_t, CBLSeekBase) { + kCBLSeekModeFromStart, ///< Offset is an absolute position starting from 0 + kCBLSeekModeRelative, ///< Offset is relative to the current stream position + kCBLSeekModeFromEnd ///< Offset is relative to the end of the blob + }; + + /** Sets the position of a CBLBlobReadStream. + @param stream The stream to reposition. + @param offset The byte offset in the stream (relative to the `mode`). + @param base The base position from which the offset is calculated. + @param outError On failure, an error will be stored here if non-NULL. + @return The new absolute position, or -1 on failure. */ + int64_t CBLBlobReader_Seek(CBLBlobReadStream* stream, + int64_t offset, + CBLSeekBase base, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the current position of a CBLBlobReadStream. */ + uint64_t CBLBlobReader_Position(CBLBlobReadStream* stream) CBLAPI; + + /** Closes a CBLBlobReadStream. */ + void CBLBlobReader_Close(CBLBlobReadStream* _cbl_nullable) CBLAPI; + + /** Compares whether the two given blobs are equal based on their content. */ + bool CBLBlob_Equals(CBLBlob* blob, CBLBlob* anotherBlob) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + + /** Creates a new blob given its contents as a single block of data. + @note You are responsible for releasing the \ref CBLBlob, but not until after its document + has been saved. + @param contentType The MIME type (optional). + @param contents The data's address and length. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithData(FLString contentType, FLSlice contents) CBLAPI; + + /** A stream for writing a new blob to the database. */ + typedef struct CBLBlobWriteStream CBLBlobWriteStream; + + /** Opens a stream for writing a new blob. + You should next call \ref CBLBlobWriter_Write one or more times to write the data, + then \ref CBLBlob_CreateWithStream to create the blob. + + If for some reason you need to abort, just call \ref CBLBlobWriter_Close. */ + _cbl_warn_unused + CBLBlobWriteStream* _cbl_nullable CBLBlobWriter_Create(CBLDatabase* db, + CBLError* _cbl_nullable) CBLAPI; + + /** Closes a blob-writing stream, if you need to give up without creating a \ref CBLBlob. */ + void CBLBlobWriter_Close(CBLBlobWriteStream* _cbl_nullable) CBLAPI; + + /** Writes data to a new blob. + @param writer The stream to write to. + @param data The address of the data to write. + @param length The length of the data to write. + @param outError On failure, error info will be written here. + @return True on success, false on failure. */ + bool CBLBlobWriter_Write(CBLBlobWriteStream* writer, + const void *data, + size_t length, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Creates a new blob after its data has been written to a \ref CBLBlobWriteStream. + You should then add the blob to a mutable document as a property -- see + \ref FLSlot_SetBlob. + @note You are responsible for releasing the CBLBlob reference. + @note Do not free the stream; the blob will do that. + @param contentType The MIME type (optional). + @param writer The blob-writing stream the data was written to. + @return A new CBLBlob instance. */ + _cbl_warn_unused + CBLBlob* CBLBlob_CreateWithStream(FLString contentType, + CBLBlobWriteStream* writer) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE UTILITIES: +#endif + + /** Returns true if a value in a document is a blob reference. + If so, you can call \ref FLValue_GetBlob to access it. */ + static inline bool FLValue_IsBlob(FLValue _cbl_nullable v) { + return FLDict_IsBlob(FLValue_AsDict(v)); + } + + /** Instantiates a \ref CBLBlob object corresponding to a blob dictionary in a document. + @param value The value (dictionary) in the document. + @return A \ref CBLBlob instance for this blob, or `NULL` if the value is not a blob. + \note The returned CBLBlob object will be released when its document is released. */ + static inline const CBLBlob* _cbl_nullable FLValue_GetBlob(FLValue _cbl_nullable value) { + return FLDict_GetBlob(FLValue_AsDict(value)); + } + + void FLSlot_SetBlob(FLSlot slot, CBLBlob* blob) CBLAPI; + + /** Stores a blob reference into an array. + @param array The array to store into. + @param index The position in the array at which to store the blob reference. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_SetBlob(FLMutableArray array, uint32_t index, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Set(array, index), blob); + } + + /** Appends a blob reference to an array. + @param array The array to store into. + @param blob The blob reference to be stored. */ + static inline void FLMutableArray_AppendBlob(FLMutableArray array, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableArray_Append(array), blob); + } + + /** Stores a blob reference into a Dict. + @param dict The Dict to store into. + @param key The key to associate the blob reference with. + @param blob The blob reference to be stored. */ + static inline void FLMutableDict_SetBlob(FLMutableDict dict, FLString key, CBLBlob *blob) { + FLSlot_SetBlob(FLMutableDict_Set(dict, key), blob); + } + + +#ifdef __APPLE__ +#pragma mark - BINDING DEV SUPPORT FOR BLOB: +#endif + + /** Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + + The \ref CBLBlob properties is a blob's metadata containing two required fields + which are a special marker property `"@type":"blob"`, and property `digest` whose value + is a hex SHA-1 digest of the blob's data. The other optional properties are `length` and + `content_type`. To obtain the \ref CBLBlob properties from a \ref CBLBlob, + call \ref CBLBlob_Properties function. + + @note You must release the \ref CBLBlob when you're finished with it. + @param db The database. + @param properties The properties for getting the \ref CBLBlob object. + @param outError On failure, error info will be written here if specified. A nonexistent blob + is not considered a failure; in that event the error code will be zero. + @return A \ref CBLBlob instance, or NULL if the doc doesn't exist or an error occurred. */ + const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Save a new \ref CBLBlob object into the database without associating it with + any documents. The properties of the saved \ref CBLBlob object will include + information necessary for referencing the \ref CBLBlob object in the properties + of the document to be saved into the database. + + Normally you do not need to use this function unless you are in the situation + (e.g. developing javascript binding) that you cannot retain the \ref CBLBlob + object until the document containing the \ref CBLBlob object is successfully + saved into the database. + \note The saved \ref CBLBlob objects that are not associated with any documents + will be removed from the database when compacting the database. + @param db The database. + @param blob The The CBLBlob to save. + @param outError On failure, error info will be written here. */ + bool CBLDatabase_SaveBlob(CBLDatabase* db, CBLBlob* blob, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..35941b5 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,514 @@ +// +// CBLCollection.h +// +// Copyright (c) 2022 Couchbase, Inc 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 +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup collection Collection + @{ + A \ref CBLCollection represent a collection which is a container for documents. + + A collection can be thought as a table in the relational database. Each collection belongs to + a scope which is simply a namespce, and has a name which is unique within its scope. + + When a new database is created, a default collection named "_default" will be automatically + created. The default collection is created under the default scope named "_default". + The name of the default collection and scope can be referenced by using + \ref kCBLDefaultCollectionName and \ref kCBLDefaultScopeName constant. + + @note The default collection cannot be deleted. + + When creating a new collection, the collection name, and the scope name are required. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + + ## `CBLCollection` Lifespan + `CBLCollection` is ref-counted. Same as the CBLDocument, the CBLCollection objects + created or retrieved from the database must be released after you are done using them. + When the database is closed or released, the collection objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with either the + \ref kCBLErrorNotOpen error or null/zero/empty result. + + ##Legacy Database and API + When using the legacy database, the existing documents and indexes in the database will be + automatically migrated to the default collection. + + Any pre-existing database functions that refer to documents, listeners, and indexes without + specifying a collection such as \ref CBLDatabase_GetDocument will implicitly operate on + the default collection. In other words, they behave exactly the way they used to, but + collection-aware code should avoid them and use the new Collection API instead. + These legacy functions are deprecated and will be removed eventually. + */ + +CBL_REFCOUNTED(CBLCollection*, Collection); + +/** \name Collection Management + @{ + */ + +/** The default collection's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultCollectionName; + +/** Returns the names of all existing scopes in the database. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned array. + @param db The database. + @param outError On failure, the error will be written here. + @return The names of all existing scopes in the database, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + @note The default scope will always exist, containing at least the default collection. + @note You are responsible for releasing the returned scope. + @param db The database. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if the scope doesn't exist or an error occurred. */ +CBLScope* _cbl_nullable CBLDatabase_Scope(const CBLDatabase* db, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + + /** Returns the existing collection with the given name and scope. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_Collection(const CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Create a new collection. + The naming rules of the collections and scopes are as follows: + - Must be between 1 and 251 characters in length. + - Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %. + - Cannot start with _ or %. + - Both scope and collection names are case sensitive. + @note If the collection already exists, the existing collection will be returned. + @note You are responsible for releasing the returned collection. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_CreateCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Delete an existing collection. + @note The default collection cannot be deleted. + @param db The database. + @param collectionName The name of the collection. + @param scopeName The name of the scope. + @param outError On failure, the error will be written here. + @return True if success, or False if an error occurred. */ +bool CBLDatabase_DeleteCollection(CBLDatabase* db, + FLString collectionName, + FLString scopeName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default scope. + @note You are responsible for releasing the returned scope. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLScope instance, or NULL if an error occurred. */ +CBLScope* CBLDatabase_DefaultScope(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the default collection. + @note You are responsible for releasing the returned collection. + @param db The database. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if an error occurred. */ +CBLCollection* _cbl_nullable CBLDatabase_DefaultCollection(const CBLDatabase* db, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Collection Accessors + @{ + Getting information about a collection. + */ + +/** Returns the collection's scope. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return The scope of the collection. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's fully qualified name in the '.' format. + @param collection The collection. + @return The fully qualified name of the collection. */ +FLString CBLCollection_FullName(const CBLCollection* collection) CBLAPI; + +/** Returns the collection's database. + @note The database object is owned by the collection object; you do not need to release it. + @param collection The collection. + @return The database of the collection. */ +CBLDatabase* CBLCollection_Database(const CBLCollection* collection) CBLAPI; + +/** Returns the number of documents in the collection. + @param collection The collection. + @return the number of documents in the collection. */ +uint64_t CBLCollection_Count(const CBLCollection* collection) CBLAPI; + +/** @} */ + +/** \name Document lifecycle + @{ */ + +/** Reads a document from the collection, creating a new (immutable) \ref CBLDocument object. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + CBLCollection_GetMutableDocument instead. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLCollection_GetDocument(const CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + @warning If a newer revision has been saved since the doc was loaded, it will be + overwritten by this one. This can lead to data loss! To avoid this, call + \ref CBLCollection_SaveDocumentWithConcurrencyControl or + \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocument(CBLCollection* collection, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLCollection_SaveDocumentWithConflictHandler instead. + @param collection The collection to save to. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConcurrencyControl(CBLCollection* collection, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @param collection The collection to save to. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLCollection_SaveDocumentWithConflictHandler(CBLCollection* collection, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocument(CBLCollection *collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @param collection The collection containing the document. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLCollection_DeleteDocumentWithConcurrencyControl(CBLCollection *collection, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document. This removes all traces of the document from the collection. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @note If you don't have the document in memory already, \ref CBLCollection_PurgeDocumentByID is a + simpler shortcut. + @param collection The collection containing the document. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLCollection_PurgeDocument(CBLCollection* collection, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document, given only its ID. + @note If no document with that ID exists, this function will return false but the error code will be zero. + @param collection The collection. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. + */ +bool CBLCollection_PurgeDocumentByID(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLCollection_SetDocumentExpiration + to set a document's expiration time. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLCollection_GetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @param collection The collection. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_SetDocumentExpiration(CBLCollection* collection, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLCollection_SaveDocument to persist the changes. + */ + +/** Reads a document from the collection, in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLCollection_GetDocument.) + @note You must release the document when you're done with it. + @param collection The collection. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLCollection_GetMutableDocument(CBLCollection* collection, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; +/** @} */ + +/** \name Query Indexes + @{ + */ + +/** Creates a value index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateValueIndex(CBLCollection *collection, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateFullTextIndex(CBLCollection *collection, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates an array index for use with UNNEST queries in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @param collection The collection. + @param name The name of the index. + @param config The index configuration. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_CreateArrayIndex(CBLCollection *collection, + FLString name, + CBLArrayIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** ENTERPRISE EDITION ONLY + + Creatres a vector index in the collection. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + */ +bool CBLCollection_CreateVectorIndex(CBLCollection *collection, + FLString name, + CBLVectorIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** Deletes an index in the collection by name. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLCollection_DeleteIndex(CBLCollection *collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes in the collection, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @param collection The collection. + @param outError On failure, an error is written here. + @return The index names in the collection, or NULL if an error occurred. */ +_cbl_warn_unused +FLMutableArray _cbl_nullable CBLCollection_GetIndexNames(CBLCollection *collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an index object representing an existing index in the collection. + @note You are responsible for releasing the returned index object. + @param collection The collection. + @param name The name of the index. + @param outError On failure, an error is written here. + @return A \ref CBLQueryIndex instance if the index exists, or NULL if the index doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLQueryIndex* _cbl_nullable CBLCollection_GetIndex(CBLCollection* collection, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name Change Listeners + @{ + A collection change listener lets you detect changes made to all documents in a collection. + (If you want to observe specific documents, use a \ref CBLCollectionDocumentChangeListener instead.) + @note If there are multiple \ref CBLCollection instances on the same database file, each one's + listeners will be notified of changes made by other collection instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +typedef struct { + const CBLCollection* collection; /// +#include + +CBL_CAPI_BEGIN + +/** \defgroup database Database + @{ + A \ref CBLDatabase is both a filesystem object and a container for documents. + */ + +#ifdef COUCHBASE_ENTERPRISE + +#ifdef __APPLE__ +#pragma mark - Database Extension +#endif + +/** \name Database Extension + @{ */ + +/** ENTERPRISE EDITION ONLY + + Enables Vector Search extension by specifying the extension path to search for the Vector Search extension library. + This function must be called before opening a database that intends to use the vector search extension. + @param path The file system path of the directory that contains the Vector Search extension library. + @param outError On return, will be set to the error that occurred. + @return True on success, false if there was an error. + @note Must be called before opening a database that intends to use the vector search extension. */ +bool CBL_EnableVectorSearch(FLString path, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +#ifdef __APPLE__ +#pragma mark - CONFIGURATION +#endif + +/** \name Database configuration + @{ */ + +#ifdef COUCHBASE_ENTERPRISE +/** Database encryption algorithms (available only in the Enterprise Edition). */ +typedef CBL_ENUM(uint32_t, CBLEncryptionAlgorithm) { + kCBLEncryptionNone = 0, ///< No encryption (default) + kCBLEncryptionAES256 ///< AES with 256-bit key +}; + +/** Encryption key sizes (in bytes). */ +typedef CBL_ENUM(uint64_t, CBLEncryptionKeySize) { + kCBLEncryptionKeySizeAES256 = 32, ///< Key size for \ref kCBLEncryptionAES256 +}; + +/** Encryption key specified in a \ref CBLDatabaseConfiguration. */ +typedef struct { + CBLEncryptionAlgorithm algorithm; ///< Encryption algorithm + uint8_t bytes[32]; ///< Raw key data +} CBLEncryptionKey; +#endif + +/** Database configuration options. */ +typedef struct { + FLString directory; ///< The parent directory of the database +#ifdef COUCHBASE_ENTERPRISE + CBLEncryptionKey encryptionKey; ///< The database's encryption key (if any) +#endif + /** As Couchbase Lite normally configures its databases, There is a very + small (though non-zero) chance that a power failure at just the wrong + time could cause the most recently committed transaction's changes to + be lost. This would cause the database to appear as it did immediately + before that transaction. + + Setting this mode true ensures that an operating system crash or + power failure will not cause the loss of any data. FULL synchronous + is very safe but it is also dramatically slower. */ + bool fullSync; + + /** + Disable memory-mapped I/O. By default, memory-mapped I/O is enabled. + Disabling it may affect database performance. Typically, there is no need to modify this setting. + @note Memory-mapped I/O is always disabled on macOS to prevent database corruption, + so setting mmapDisabled value has no effect on the macOS platform. */ + bool mmapDisabled; +} CBLDatabaseConfiguration; + +/** Returns the default database configuration. */ +CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Derives an encryption key from a password. If your UI uses passwords, call this function to + create the key used to encrypt the database. It is designed for security, and deliberately + runs slowly to make brute-force attacks impractical. + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPassword(CBLEncryptionKey *key, FLString password) CBLAPI; + +/** VOLATILE API: Derives an encryption key from a password in a way that is + compatible with certain variants of Couchbase Lite in which a slightly different + hashing algorithm is used. The same notes apply as in CBLEncryptionKey_FromPassword + @param key The derived AES key will be stored here. + @param password The input password, which can be any data. + @return True on success, false if there was a problem deriving the key. */ +bool CBLEncryptionKey_FromPasswordOld(CBLEncryptionKey *key, FLString password) CBLAPI; +#endif + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - FILE OPERATIONS +#endif +/** \name Database file operations + @{ + These functions operate on database files without opening them. + */ + +/** Returns true if a database with the given name exists in the given directory. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. */ +bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; + +/** Copies a database file to a new location, and assigns it a new internal UUID to distinguish + it from the original database when replicating. + @param fromPath The full filesystem path to the original database (including extension). + @param toName The new database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On return, will be set to the error that occurred, if applicable. + @note While a database is open, one or more of its files may be in use. Attempting to copy a file, while it is in use, will fail. We recommend that you close a database before attempting to copy it. */ +bool CBL_CopyDatabase(FLString fromPath, + FLString toName, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a database file. If the database file is open, an error is returned. + @param name The database name (without the ".cblite2" extension.) + @param inDirectory The directory containing the database. If NULL, `name` must be an + absolute or relative path to the database. + @param outError On return, will be set to the error that occurred, or a 0 code if no error. + @return True if the database was deleted, false if it doesn't exist or deletion failed. + (You can tell the last two cases apart by looking at \p outError.)*/ +bool CBL_DeleteDatabase(FLString name, + FLString inDirectory, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + +#ifdef __APPLE__ +#pragma mark - LIFECYCLE +#endif +/** \name Database lifecycle + @{ + Opening, closing, and managing open databases. + */ + +/** Opens a database, or creates it if it doesn't exist yet, returning a new \ref CBLDatabase + instance. + It's OK to open the same database file multiple times. Each \ref CBLDatabase instance is + independent of the others (and must be separately closed and released.) + @param name The database name (without the ".cblite2" extension.) + @param config The database configuration (directory and encryption option.) + @param outError On failure, the error will be written here. + @return The new database object, or NULL on failure. */ +_cbl_warn_unused +CBLDatabase* _cbl_nullable CBLDatabase_Open(FLSlice name, + const CBLDatabaseConfiguration* _cbl_nullable config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Closes an open database. */ +bool CBLDatabase_Close(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDatabase*, Database); + +/** Closes and deletes a database. If there are any other connections to the database, + an error is returned. */ +bool CBLDatabase_Delete(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Begins a transaction. You **must** later call \ref + CBLDatabase_EndTransaction to commit or abort the transaction. + @note Multiple writes are much faster when grouped in a transaction. + @note Changes will not be visible to other CBLDatabase instances on the same database until + the transaction ends. + @note Transactions can nest. Changes are not committed until the outer transaction ends. */ +bool CBLDatabase_BeginTransaction(CBLDatabase*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Ends a transaction, either committing or aborting. */ +bool CBLDatabase_EndTransaction(CBLDatabase*, + bool commit, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Encrypts or decrypts a database, or changes its encryption key. + + If \p newKey is NULL, or its \p algorithm is \ref kCBLEncryptionNone, the database will be decrypted. + Otherwise the database will be encrypted with that key; if it was already encrypted, it will be + re-encrypted with the new key.*/ +bool CBLDatabase_ChangeEncryptionKey(CBLDatabase*, + const CBLEncryptionKey* _cbl_nullable newKey, + CBLError* outError) CBLAPI; +#endif + +/** Maintenance Type used when performing database maintenance. */ +typedef CBL_ENUM(uint32_t, CBLMaintenanceType) { + /// Compact the database file and delete unused attachments + kCBLMaintenanceTypeCompact = 0, + + /// Rebuild the entire database's indexes. + kCBLMaintenanceTypeReindex, + + /// Check for the database’s corruption. If found, an error will be returned + kCBLMaintenanceTypeIntegrityCheck, + + /// Partially scan indexes to gather database statistics that help optimize queries. + /// This operation is also performed automatically when closing the database. + kCBLMaintenanceTypeOptimize, + + /// Fully scans all indexes to gather database statistics that help optimize queries. + /// This may take some time, depending on the size of the indexes, but it doesn't have to + /// be redone unless the database changes drastically, or new indexes are created. + kCBLMaintenanceTypeFullOptimize +}; + +/** Performs database maintenance. */ +bool CBLDatabase_PerformMaintenance(CBLDatabase* db, + CBLMaintenanceType type, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - ACCESSORS +#endif +/** \name Database accessors + @{ + Getting information about a database. + */ + +/** Returns the database's name. */ +FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; + +/** Returns the database's full filesystem path, or null slice if the database is closed or deleted. */ +_cbl_warn_unused +FLStringResult CBLDatabase_Path(const CBLDatabase*) CBLAPI; + +/** Returns the number of documents in the database, or zero if the database is closed or deleted. + @warning Deprecated : Use CBLCollection_Count on the default collection instead. */ +uint64_t CBLDatabase_Count(const CBLDatabase*) CBLAPI; + +/** Returns the database's configuration, as given when it was opened. */ +const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; + +/** @} */ + +/** \name Query Indexes + @{ + Query Index Management + */ + +/** Creates a value index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateValueIndex on the default collection instead. */ +bool CBLDatabase_CreateValueIndex(CBLDatabase *db, + FLString name, + CBLValueIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a full-text index. + Indexes are persistent. + If an identical index with that name already exists, nothing happens (and no error is returned.) + If a non-identical index with that name already exists, it is deleted and re-created. + @warning Deprecated : Use CBLCollection_CreateFullTextIndex on the default collection instead. */ +bool CBLDatabase_CreateFullTextIndex(CBLDatabase *db, + FLString name, + CBLFullTextIndexConfiguration config, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes an index given its name. + @warning Deprecated : Use CBLCollection_DeleteIndex on the default collection instead. */ +bool CBLDatabase_DeleteIndex(CBLDatabase *db, + FLString name, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the names of the indexes on this database, as a Fleece array of strings. + @note You are responsible for releasing the returned Fleece array. + @warning Deprecated : Use CBLCollection_GetIndexNames on the default collection instead. */ +_cbl_warn_unused +FLArray CBLDatabase_GetIndexNames(CBLDatabase *db) CBLAPI; + + +/** @} */ + +#ifdef __APPLE__ +#pragma mark - LISTENERS +#endif +/** \name Database listeners + @{ + A database change listener lets you detect changes made to all documents in the default collection. + (If you only want to observe specific documents, use a \ref CBLDocumentChangeListener instead.) + @note If there are multiple \ref CBLDatabase instances on the same database file, each one's + listeners will be notified of changes made by other database instances. + @warning Changes made to the database file by other processes will _not_ be notified. */ + +/** A default collection change listener callback, invoked after one or more documents in the default collection are changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database that changed. + @param numDocs The number of documents that changed (size of the `docIDs` array) + @param docIDs The IDs of the documents that changed, as a C array of `numDocs` C strings. */ +typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, + const CBLDatabase* db, + unsigned numDocs, + FLString docIDs[_cbl_nonnull]); + +/** Registers a default collection change listener callback. It will be called after one or more + documents are changed on disk. + @warning Deprecated : Use CBLCollection_AddChangeListener on the default collection instead. + @param db The database to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddChangeListener(const CBLDatabase* db, + CBLDatabaseChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + + +#ifdef __APPLE__ +#pragma mark - NOTIFICATION SCHEDULING +#endif +/** \defgroup listeners Listeners + @{ */ +/** \name Scheduling notifications + @{ + Applications may want control over when Couchbase Lite notifications (listener callbacks) + happen. They may want them called on a specific thread, or at certain times during an event + loop. This behavior may vary by database, if for instance each database is associated with a + separate thread. + + The API calls here enable this. When notifications are "buffered" for a database, calls to + listeners will be deferred until the application explicitly allows them. Instead, a single + callback will be issued when the first notification becomes available; this gives the app a + chance to schedule a time when the notifications should be sent and callbacks called. + */ + +/** Callback indicating that the database (or an object belonging to it) is ready to call one + or more listeners. You should call \ref CBLDatabase_SendNotifications at your earliest + convenience, in the context (thread, dispatch queue, etc.) you want them to run. + @note This callback is called _only once_ until the next time \ref CBLDatabase_SendNotifications + is called. If you don't respond by (sooner or later) calling that function, + you will not be informed that any listeners are ready. + @warning This can be called from arbitrary threads. It should do as little work as + possible, just scheduling a future call to \ref CBLDatabase_SendNotifications. */ +typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, + CBLDatabase* db); + +/** Switches the database to buffered-notification mode. Notifications for objects belonging + to this database (documents, queries, replicators, and of course the database) will not be + called immediately; your \ref CBLNotificationsReadyCallback will be called instead. + @param db The database whose notifications are to be buffered. + @param callback The function to be called when a notification is available. + @param context An arbitrary value that will be passed to the callback. */ +void CBLDatabase_BufferNotifications(CBLDatabase *db, + CBLNotificationsReadyCallback _cbl_nullable callback, + void* _cbl_nullable context) CBLAPI; + +/** Immediately issues all pending notifications for this database, by calling their listener + callbacks. */ +void CBLDatabase_SendNotifications(CBLDatabase *db) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d1c39a9 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,138 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2024-present Couchbase, Inc 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. +// + +// THIS IS AN AUTOGENERATED FILE, MANUAL CHANGES SHOULD BE EXPECTED TO +// BE OVERWRITTEN + + +#pragma once +#include +#include +#include + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLDatabaseConfiguration + @{ +*/ + +/** [false] Full sync is off by default because the performance hit is seldom worth the benefit */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseFullSync; + +/** [false] Memory mapped database files are enabled by default */ +CBL_PUBLIC extern const bool kCBLDefaultDatabaseMmapDisabled; + +/** @} */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlaintext; + +/** [false] Plaintext is not used, and instead binary encoding is used in log files + @warning Deprecated : Use kCBLDefaultLogFileUsePlaintext instead. */ +CBL_PUBLIC extern const bool kCBLDefaultLogFileUsePlainText; + +/** [524288] 512 KiB for the size of a log file */ +CBL_PUBLIC extern const size_t kCBLDefaultLogFileMaxSize; + +/** [1] 1 rotated file present (2 total, including the currently active log file) */ +CBL_PUBLIC extern const uint32_t kCBLDefaultLogFileMaxRotateCount; + +/** @} */ + +/** \name CBLFullTextIndexConfiguration + @{ +*/ + +/** [false] Accents and ligatures are not ignored when indexing via full text search */ +CBL_PUBLIC extern const bool kCBLDefaultFullTextIndexIgnoreAccents; + +/** @} */ + +/** \name CBLReplicatorConfiguration + @{ +*/ + +/** [kCBLReplicatorTypePushAndPull] Perform bidirectional replication */ +CBL_PUBLIC extern const CBLReplicatorType kCBLDefaultReplicatorType; + +/** [false] One-shot replication is used, and will stop once all initial changes are processed */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorContinuous; + +/** [300] A heartbeat messages is sent every 300 seconds to keep the connection alive */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorHeartbeat; + +/** [10] When replicator is not continuous, after 10 failed attempts give up on the replication */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsSingleShot; + +/** [UINT_MAX] When replicator is continuous, never give up unless explicitly stopped */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsContinuous; + +/** [300] Max wait time between retry attempts in seconds */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptsWaitTime; + +/** [300] Max wait time between retry attempts in seconds + @warning Deprecated : Use kCBLDefaultReplicatorMaxAttemptsWaitTime instead. */ +CBL_PUBLIC extern const unsigned kCBLDefaultReplicatorMaxAttemptWaitTime; + +/** [false] Purge documents when a user loses access */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorDisableAutoPurge; + +/** [false] Whether or not a replicator only accepts cookies for the sender's parent domains */ +CBL_PUBLIC extern const bool kCBLDefaultReplicatorAcceptParentCookies; + +/** @} */ + +#ifdef COUCHBASE_ENTERPRISE + +/** \name CBLVectorIndexConfiguration + @{ +*/ + +/** [false] Vectors are not lazily indexed, by default */ +CBL_PUBLIC extern const bool kCBLDefaultVectorIndexLazy; + +/** [kCBLDistanceMetricEuclideanSquared] By default, vectors are compared using Squared Euclidean metric. */ +CBL_PUBLIC extern const CBLDistanceMetric kCBLDefaultVectorIndexDistanceMetric; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMinTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids, encoding types, and the encoding parameters */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexMaxTrainingSize; + +/** [0] By default, the value will be determined based on the number of centroids. */ +CBL_PUBLIC extern const unsigned kCBLDefaultVectorIndexNumProbes; + +/** @} */ + +#endif + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h new file mode 100644 index 0000000..c42809b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h @@ -0,0 +1,358 @@ +// +// CBLDocument.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup documents Documents + @{ + A \ref CBLDocument is essentially a JSON object with an ID string that's unique in its database. + */ + +CBL_PUBLIC extern const FLSlice kCBLTypeProperty; ///< `"@type"` + +/** \name Document lifecycle + @{ */ + +/** Conflict-handling options when saving or deleting a document. */ +typedef CBL_ENUM(uint8_t, CBLConcurrencyControl) { + /** The current save/delete will overwrite a conflicting revision if there is a conflict. */ + kCBLConcurrencyControlLastWriteWins, + /** The current save/delete will fail if there is a conflict. */ + kCBLConcurrencyControlFailOnConflict +}; + + +/** Custom conflict handler for use when saving or deleting a document. This handler is called + if the save would cause a conflict, i.e. if the document in the database has been updated + (probably by a pull replicator, or by application code on another thread) + since it was loaded into the CBLDocument being saved. + @param context The value of the \p context parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler. + @param documentBeingSaved The document being saved (same as the parameter you passed to + \ref CBLDatabase_SaveDocumentWithConflictHandler.) The callback may modify + this document's properties as necessary to resolve the conflict. + @param conflictingDocument The revision of the document currently in the database, + which has been changed since \p documentBeingSaved was loaded. + May be NULL, meaning that the document has been deleted. + @return True to save the document, false to abort the save. */ +typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, + CBLDocument* _cbl_nullable documentBeingSaved, + const CBLDocument* _cbl_nullable conflictingDocument); + + +/** Reads a document from the default collection in an immutable form. + Each call to this function creates a new object (which must later be released.) + @note If you are reading the document in order to make changes to it, call + \ref CBLDatabase_GetMutableDocument instead. + @warning Deprecated : Use CBLCollection_GetDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLDocument*, Document); + +/** Saves a (mutable) document to the default collection. + @warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by + this one. This can lead to data loss! To avoid this, call + \ref CBLDatabase_SaveDocumentWithConcurrencyControl or + \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocument on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocument(CBLDatabase* db, + CBLDocument* doc, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection. + If a conflicting revision has been saved since \p doc was loaded, the \p concurrency + parameter specifies whether the save should fail, or the conflicting revision should + be overwritten with the revision being saved. + If you need finer-grained control, call \ref CBLDatabase_SaveDocumentWithConflictHandler instead. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param concurrency Conflict-handling strategy (fail or overwrite). + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, + CBLDocument* doc, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Saves a (mutable) document to the default collection, allowing for custom conflict handling in the event + that the document has been updated since \p doc was loaded. + @warning Deprecated : Use CBLCollection_SaveDocumentWithConflictHandler on the default collection instead. + @param db The database. + @param doc The mutable document to save. + @param conflictHandler The callback to be invoked if there is a conflict. + @param context An arbitrary value to be passed to the \p conflictHandler. + @param outError On failure, the error will be written here. + @return True on success, false on failure. */ +bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, + CBLDocument* doc, + CBLConflictHandler conflictHandler, + void* _cbl_nullable context, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocument on the default collection instead. + @param db The database. + @param document The document to delete. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocument(CBLDatabase *db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Deletes a document from the default collection. Deletions are replicated. + @warning You are still responsible for releasing the CBLDocument. + @warning Deprecated : Use CBLCollection_DeleteDocumentWithConcurrencyControl on the default collection instead. + @param db The database. + @param document The document to delete. + @param concurrency Conflict-handling strategy. + @param outError On failure, the error will be written here. + @return True if the document was deleted, false if an error occurred. */ +bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, + const CBLDocument* document, + CBLConcurrencyControl concurrency, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document from the default collection. This removes all traces of the document. + Purges are _not_ replicated. If the document is changed on a server, it will be re-created + when pulled. + @warning You are still responsible for releasing the \ref CBLDocument reference. + @warning Deprecated : Use CBLCollection_PurgeDocument on the default collection instead. + @note If you don't have the document in memory already, \ref CBLDatabase_PurgeDocumentByID is a + simpler shortcut. + @param db The database. + @param document The document to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocument(CBLDatabase* db, + const CBLDocument* document, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Purges a document by its ID from the default collection. + @note If no document with that ID exists, this function will return false but the error + code will be zero. + @warning Deprecated : Use CBLCollection_PurgeDocumentByID on the default collection instead. + @param database The database. + @param docID The document ID to purge. + @param outError On failure, the error will be written here. + @return True if the document was purged, false if it doesn't exist or the purge failed. */ +bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Mutable documents + @{ + The type `CBLDocument*` without a `const` qualifier refers to a _mutable_ document instance. + A mutable document exposes its properties as a mutable dictionary, so you can change them + in place and then call \ref CBLDatabase_SaveDocument to persist the changes. + */ + +/** Reads a document from the default collection in mutable form that can be updated and saved. + (This function is otherwise identical to \ref CBLDatabase_GetDocument.) + @note You must release the document when you're done with it. + @warning Deprecated : Use CBLCollection_GetMutableDocument on the default collection instead. + @param database The database. + @param docID The ID of the document. + @param outError On failure, the error will be written here. (A nonexistent document is not + considered a failure; in that event the error code will be zero.) + @return A new \ref CBLDocument instance, or NULL if the doc doesn't exist or an error occurred. */ +_cbl_warn_unused +CBLDocument* _cbl_nullable CBLDatabase_GetMutableDocument(CBLDatabase* database, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Creates a new, empty document in memory, with a randomly-generated unique ID. + It will not be added to a database until saved. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_Create(void) CBLAPI; + +/** Creates a new, empty document in memory, with the given ID. + It will not be added to a database until saved. + @note If the given ID conflicts with a document already in the database, that will not + be apparent until this document is saved. At that time, the result depends on the + conflict handling mode used when saving; see the save functions for details. + @param docID The ID of the new document, or NULL to assign a new unique ID. + @return The new mutable document instance. */ +_cbl_warn_unused +CBLDocument* CBLDocument_CreateWithID(FLString docID) CBLAPI; + +/** Creates a new mutable CBLDocument instance that refers to the same document as the original. + If the original document has unsaved changes, the new one will also start out with the same + changes; but mutating one document thereafter will not affect the other. + @note You must release the new reference when you're done with it. Similarly, the original + document still exists and must also be released when you're done with it.*/ +_cbl_warn_unused +CBLDocument* CBLDocument_MutableCopy(const CBLDocument* original) CBLAPI; + +/** @} */ + + + +/** \name Document properties and metadata + @{ + A document's body is essentially a JSON object. The properties are accessed in memory + using the Fleece API, with the body itself being a \ref FLDict "dictionary"). + */ + +/** Returns a document's ID. */ +FLString CBLDocument_ID(const CBLDocument*) CBLAPI; + +/** Returns a document's revision ID, which is a short opaque string that's guaranteed to be + unique to every change made to the document. + If the document doesn't exist yet, this function returns NULL. */ +FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; + +/** Returns a document's current sequence in the local database. + This number increases every time the document is saved, and a more recently saved document + will have a greater sequence number than one saved earlier, so sequences may be used as an + abstract 'clock' to tell relative modification times. */ +uint64_t CBLDocument_Sequence(const CBLDocument*) CBLAPI; + +/** Returns a document's collection or NULL for the new document that hasn't been saved. */ +CBLCollection* _cbl_nullable CBLDocument_Collection(const CBLDocument*) CBLAPI; + +/** Returns a document's properties as a dictionary. + @note The dictionary object is owned by the document; you do not need to release it. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) + @warning This dictionary _reference_ is immutable, but if the document is mutable the + underlying dictionary itself is mutable and could be modified through a mutable + reference obtained via \ref CBLDocument_MutableProperties. If you need to preserve the + properties, call \ref FLDict_MutableCopy to make a deep copy. */ +FLDict CBLDocument_Properties(const CBLDocument*) CBLAPI; + +/** Returns a mutable document's properties as a mutable dictionary. + You may modify this dictionary and then call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object is owned by the document; you do not need to release it. + @note Every call to this function returns the same mutable collection. This is the + same collection returned by \ref CBLDocument_Properties. + @note When accessing nested collections inside the properties as a mutable collection + for modification, use \ref FLMutableDict_GetMutableDict or \ref FLMutableDict_GetMutableArray. + @warning When the document is released, this reference to the properties becomes invalid. + If you need to use any properties after releasing the document, you must retain them + by calling \ref FLValue_Retain (and of course later release them.) */ +FLMutableDict CBLDocument_MutableProperties(CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties. + Call \ref CBLDatabase_SaveDocument to persist the changes. + @note The dictionary object will be retained by the document. You are responsible for + releasing any retained reference(s) you have to it. */ +void CBLDocument_SetProperties(CBLDocument*, + FLMutableDict properties) CBLAPI; + +/** Returns a document's properties as JSON. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLDocument_CreateJSON(const CBLDocument*) CBLAPI; + +/** Sets a mutable document's properties from a JSON string. */ +bool CBLDocument_SetJSON(CBLDocument*, + FLSlice json, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the time, if any, at which a given document will expire and be purged. + Documents don't normally expire; you have to call \ref CBLDatabase_SetDocumentExpiration + to set a document's expiration time. + @warning Deprecated : Use CBLCollection_GetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param outError On failure, an error is written here. + @return The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document does not have an expiration, + or -1 if the call failed. */ +CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Sets or clears the expiration time of a document. + @warning Deprecated : Use CBLCollection_SetDocumentExpiration instead. + @param db The database. + @param docID The ID of the document. + @param expiration The expiration time as a CBLTimestamp (milliseconds since Unix epoch), + or 0 if the document should never expire. + @param outError On failure, an error is written here. + @return True on success, false on failure. */ +bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, + FLSlice docID, + CBLTimestamp expiration, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + + + +/** \name Document listeners + @{ + A document change listener lets you detect changes made to a specific document after they + are persisted to the database. + @note If there are multiple CBLDatabase instances on the same database file, each one's + document listeners will be notified of changes made by other database instances. + */ + +/** A document change listener callback, invoked after a specific document is changed on disk. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @warning Deprecated : Use CBLCollectionChangeListener instead. + @param context An arbitrary value given when the callback was registered. + @param db The database containing the document. + @param docID The document's ID. */ +typedef void (*CBLDocumentChangeListener)(void *context, + const CBLDatabase* db, + FLString docID); + +/** Registers a document change listener callback. It will be called after a specific document + is changed on disk. + @warning Deprecated : Use CBLCollection_AddDocumentChangeListener on the default collection instead. + @param db The database to observe. + @param docID The ID of the document to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLDatabase_AddDocumentChangeListener(const CBLDatabase* db, + FLString docID, + CBLDocumentChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** @} */ +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h new file mode 100644 index 0000000..4665b9a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -0,0 +1,171 @@ +// +// CBLEncryptable.h +// +// Copyright (c) 2021 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** \defgroup encryptables Encryptables + @{ + + A \ref CBLEncryptable is a value to be encrypted by the replicator when a document is + pushed to the remote server. When a document is pulled from the remote server, the + encrypted value will be decrypted by the replicator. + + Similar to \ref CBLBlob, a \ref CBLEncryptable acts as a proxy for a dictionary structure + with the special marker property `"@type":"encryptable"`, and another property `value` + whose value is the actual value to be encrypted by the push replicator. + + The push replicator will automatically detect \ref CBLEncryptable dictionaries inside + the document and calls the specified \ref CBLPropertyEncryptor callback to encrypt the + actual value. When the value is successfully encrypted, the replicator will transform + the property key and the encrypted \ref CBLPropertyEncryptor dictionary value into + Couchbase Server SDK's encrypted field format : + + * The original key will be prefixed with 'encrypted$'. + + * The transformed \ref CBLEncryptable dictionary will contain `alg` property indicating + the encryption algorithm, `ciphertext` property whose value is a base-64 string of the + encrypted value, and optionally `kid` property indicating the encryption key identifier + if specified when returning the result of \ref CBLPropertyEncryptor callback call. + + For security reason, a document that contains CBLEncryptable dictionaries will fail + to push with the \ref kCBLErrorCrypto error if their value cannot be encrypted including + when a \ref CBLPropertyEncryptor callback is not specified or when there is an error + or a null result returned from the callback call. + + The pull replicator will automatically detect the encrypted properties that are in the + Couchbase Server SDK's encrypted field format and call the specified \ref CBLPropertyDecryptor + callback to decrypt the encrypted value. When the value is successfully decrypted, + the replicator will transform the property format back to the CBLEncryptable format + including removing the 'encrypted$' prefix. + + The \ref CBLPropertyDecryptor callback can intentionally skip the decryption by returnning a + null result. When a decryption is skipped, the encrypted property in the form of + Couchbase Server SDK's encrypted field format will be kept as it was received from the remote + server. If an error is returned from the callback call, the document will be failed to pull with + the \ref kCBLErrorCrypto error. + + If a \ref CBLPropertyDecryptor callback is not specified, the replicator will not attempt to + detect any encrypted properties. As a result, all encrypted properties in the form of + Couchbase Server SDK's encrypted field format will be kept as they was received from the remote + server. + + To create a new \ref CBLEncryptable, call CBLEncryptable_CreateWith + function such as \ref CBLEncryptable_CreateWithString. Then call \ref FLSlot_SetEncryptableValue + to add the \ref CBLEncryptable to a dictionary in the document. Noted that adding + \ref CBLEncryptable to an array is not supported. For example: + + FLSlot_SetEncryptableValue(FLMutableDict_Set(properties, key), encryptableValue); + + Note: When creating a \ref CBLEncryptable, you are responsible for releasing the + \ref CBLEncryptable object but not until its document is saved into the database. + + When a document is loaded from the database, call \ref FLDict_GetEncryptableValue on an + Encryptable dictionary value to obtain a \ref CBLEncryptable object. + */ + +CBL_PUBLIC extern const FLSlice kCBLEncryptableType; ///< `"encryptable"` +CBL_PUBLIC extern const FLSlice kCBLEncryptableValueProperty; ///< `"value"` + +CBL_REFCOUNTED(CBLEncryptable*, Encryptable); + +#ifdef __APPLE__ +#pragma mark - CREATING: +#endif + +/** Creates CBLEncryptable object with null value. */ +CBLEncryptable* CBLEncryptable_CreateWithNull(void) CBLAPI; + +/** Creates CBLEncryptable object with a boolean value. */ +CBLEncryptable* CBLEncryptable_CreateWithBool(bool value) CBLAPI; + +/** Creates CBLEncryptable object with an int value. */ +CBLEncryptable* CBLEncryptable_CreateWithInt(int64_t value) CBLAPI; + +/** Creates CBLEncryptable object with an unsigned int value. */ +CBLEncryptable* CBLEncryptable_CreateWithUInt(uint64_t value) CBLAPI; + +/** Creates CBLEncryptable object with a float value. */ +CBLEncryptable* CBLEncryptable_CreateWithFloat(float value) CBLAPI; + +/** Creates CBLEncryptable object with a double value. */ +CBLEncryptable* CBLEncryptable_CreateWithDouble(double value) CBLAPI; + +/** Creates CBLEncryptable object with a string value. */ +CBLEncryptable* CBLEncryptable_CreateWithString(FLString value) CBLAPI; + +/** Creates CBLEncryptable object with an FLValue value. */ +CBLEncryptable* CBLEncryptable_CreateWithValue(FLValue value) CBLAPI; + +/** Creates CBLEncryptable object with an FLArray value. */ +CBLEncryptable* CBLEncryptable_CreateWithArray(FLArray value) CBLAPI; + +/** Creates CBLEncryptable object with an FLDict value. */ +CBLEncryptable* CBLEncryptable_CreateWithDict(FLDict value) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - READING: +#endif + +/** Returns the value to be encrypted by the push replicator. */ +FLValue CBLEncryptable_Value(const CBLEncryptable* encryptable) CBLAPI; + +/** Returns the dictionary format of the \ref CBLEncryptable object. */ +FLDict CBLEncryptable_Properties(const CBLEncryptable* encryptable) CBLAPI; + +#ifdef __APPLE__ +#pragma mark - FLEECE: +#endif + +/** Checks whether the given dictionary is a \ref CBLEncryptable or not. */ +bool FLDict_IsEncryptableValue(FLDict _cbl_nullable) CBLAPI; + +/** Checks whether the given FLValue is a \ref CBLEncryptable or not. */ +static inline bool FLValue_IsEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_IsEncryptableValue(FLValue_AsDict(value)); +} + +/** Returns a \ref CBLEncryptable object corresponding to the given encryptable dictionary + in a document or NULL if the dictionary is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +const CBLEncryptable* _cbl_nullable FLDict_GetEncryptableValue(FLDict _cbl_nullable encryptableDict) CBLAPI; + +/** Returns a \ref CBLEncryptable object corresponding to the given \ref FLValue in a document + or NULL if the value is not a \ref CBLEncryptable. + \note The returned CBLEncryptable object will be released when its document is released. */ +static inline const CBLEncryptable* _cbl_nullable FLValue_GetEncryptableValue(FLValue _cbl_nullable value) { + return FLDict_GetEncryptableValue(FLValue_AsDict(value)); +} + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary's slot. */ +void FLSlot_SetEncryptableValue(FLSlot slot, const CBLEncryptable* encryptable) CBLAPI; + +/** Set a \ref CBLEncryptable's dictionary into a mutable dictionary. */ +static inline void FLMutableDict_SetEncryptableValue(FLMutableDict dict, FLString key, CBLEncryptable* encryptable) { + FLSlot_SetEncryptableValue(FLMutableDict_Set(dict, key), encryptable); +} + +/** @} */ + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h new file mode 100644 index 0000000..2c2c1b9 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h @@ -0,0 +1,145 @@ +// +// 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 + +CBL_CAPI_BEGIN + + +/** \defgroup logging Logging + @{ + Managing messages that Couchbase Lite logs at runtime. */ + +/** Subsystems that log information. */ +typedef CBL_ENUM(uint8_t, CBLLogDomain) { + kCBLLogDomainDatabase, + kCBLLogDomainQuery, + kCBLLogDomainReplicator, + kCBLLogDomainNetwork +}; + +/** Levels of log messages. Higher values are more important/severe. Each level includes the lower ones. */ +typedef CBL_ENUM(uint8_t, CBLLogLevel) { + kCBLLogDebug, ///< Extremely detailed messages, only written by debug builds of CBL. + kCBLLogVerbose, ///< Detailed messages about normally-unimportant stuff. + kCBLLogInfo, ///< Messages about ordinary behavior. + kCBLLogWarning, ///< Messages warning about unlikely and possibly bad stuff. + kCBLLogError, ///< Messages about errors + kCBLLogNone ///< Disables logging entirely. +}; + + +/** Formats and writes a message to the log, in the given domain at the given level. + \warning This function takes a `printf`-style format string, with extra parameters to match the format placeholders, and has the same security vulnerabilities as other `printf`-style functions. + + If you are logging a fixed string, call \ref CBL_LogMessage instead, otherwise any `%` + characters in the `format` string will be misinterpreted as placeholders and the dreaded + Undefined Behavior will result, possibly including crashes or overwriting the stack. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param format A `printf`-style format string. `%` characters in this string introduce parameters, + and corresponding arguments must follow. */ +void CBL_Log(CBLLogDomain domain, + CBLLogLevel level, + const char *format, ...) CBLAPI __printflike(3, 4); + +/** Writes a pre-formatted message to the log, exactly as given. + @param domain The log domain to associate this message with. + @param level The severity of the message. If this is lower than the current minimum level for the domain + (as set by \ref CBLLog_SetConsoleLevel), nothing is logged. + @param message The exact message to write to the log. */ +void CBL_LogMessage(CBLLogDomain domain, + CBLLogLevel level, + FLSlice message) CBLAPI; + + + +/** \name Console Logging and Custom Logging + @{ */ + +/** A logging callback that the application can register. + @param domain The domain of the message + @param level The severity level of the message. + @param message The actual formatted message. */ +typedef void (*CBLLogCallback)(CBLLogDomain domain, + CBLLogLevel level, + FLString message); + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the console. */ +CBLLogLevel CBLLog_ConsoleLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the console. */ +void CBLLog_SetConsoleLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log level for debug console logging. + Only messages at this level or higher will be logged to the callback. */ +CBLLogLevel CBLLog_CallbackLevel(void) CBLAPI; + +/** Sets the detail level of logging. + Only messages whose level is ≥ the given level will be logged to the callback. */ +void CBLLog_SetCallbackLevel(CBLLogLevel) CBLAPI; + +/** Gets the current log callback. */ +CBLLogCallback CBLLog_Callback(void) CBLAPI; + +/** Sets the callback for receiving log messages. If set to NULL, no messages are logged to the console. */ +void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; + +/** @} */ + + + +/** \name Log File Configuration + @{ */ + +/** The properties for configuring logging to files. + @warning `usePlaintext` results in significantly larger log files and higher CPU usage that may slow + down your app; we recommend turning it off in production. */ +typedef struct { + CBLLogLevel level; ///< The minimum level of message to write (Required). + + FLString directory; ///< The directory where log files will be created (Required). + + /** Max number of older log files to keep (in addition to current one.) + The default is \ref kCBLDefaultLogFileMaxRotateCount. */ + uint32_t maxRotateCount; + + /** The size in bytes at which a file will be rotated out (best effort). + The default is \ref kCBLDefaultLogFileMaxSize. */ + size_t maxSize; + + /** Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + The default is \ref kCBLDefaultLogFileUsePlaintext. */ + bool usePlaintext; +} CBLLogFileConfiguration; + +/** Gets the current file logging configuration, or NULL if none is configured. */ +const CBLLogFileConfiguration* _cbl_nullable CBLLog_FileConfig(void) CBLAPI; + +/** Sets the file logging configuration, and begins logging to files. */ +bool CBLLog_SetFileConfig(CBLLogFileConfiguration, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h new file mode 100644 index 0000000..8032b5a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPlatform.h @@ -0,0 +1,60 @@ +// +// CBLPlatform.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 + +CBL_CAPI_BEGIN + +#ifdef __ANDROID__ + +/** \defgroup android Android + @{ */ + +/** Application context information required for Android application to initialize before using + CouchbaseLite library. */ +typedef struct { + /** The directory where the opened database will be stored when a specific database + directory is not specified in \ref CBLDatabaseConfiguration. + @note Recommend to simply use the directory returned by the Android Context's + getFilesDir() API or a custom subdirectory under. + @note The specified fileDir directory must exist, otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* filesDir; + + /** The directory where the SQLite stores its temporary files. + @note Recommend to create and use a temp directory under the directory returned by + the Android Context's getFilesDir() API. + @note The specified tempDir must exist otherwise an error will be returend + when calling \r CBL_Init(). */ + const char* tempDir; +} CBLInitContext; + +/** Initialize application context information for Android application. This function is required + to be called the first time before using the CouchbaseLite library otherwise an error will be + returned when calling CBLDatabase_Open to open a database. Call \r CBL_Init more than once will + return an error. + @param context The application context information. + @param outError On failure, the error will be written here. */ +bool CBL_Init(CBLInitContext context, CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +#endif + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h new file mode 100644 index 0000000..625e736 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLPrediction.h @@ -0,0 +1,57 @@ +// +// CBLPrediction.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +#ifdef COUCHBASE_ENTERPRISE + +CBL_CAPI_BEGIN + +/** Predictive Model */ +typedef struct { + /** A pointer to any external data needed by the `prediction` callback, which will receive this as its first parameter. */ + void* _cbl_nullable context; + + /** Prediction callback, called from within a query (or document indexing) to run the prediction. + @param context The value of the CBLPredictiveModel's `context` field. + @param input The input dictionary from the query. + @return The output of the prediction function as an FLMutableDict, or NULL if there is no output. + @note The output FLMutableDict will be automatically released after the prediction callback is called. + @warning This function must be "pure": given the same input parameters it must always + produce the same output (otherwise indexes or queries may be messed up). + It MUST NOT alter the database or any documents, nor run a query: either of + those are very likely to cause a crash. */ + FLMutableDict _cbl_nullable (* _cbl_nonnull prediction)(void* _cbl_nullable context, FLDict input); + + /** Unregistered callback, called if the model is unregistered, so it can release resources. */ + void (*_cbl_nullable unregistered)(void* context); +} CBLPredictiveModel; + +/** Registers a predictive model. + @param name The name. + @param model The predictive model. */ +void CBL_RegisterPredictiveModel(FLString name, CBLPredictiveModel model) CBLAPI; + +/** Unregisters the predictive model. + @param name The name of the registered predictive model. */ +void CBL_UnregisterPredictiveModel(FLString name) CBLAPI; + +CBL_CAPI_END + +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h new file mode 100644 index 0000000..321b424 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h @@ -0,0 +1,230 @@ +// +// CBLQuery.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup query Query + @{ + A CBLQuery represents a compiled database query. The query language is a large subset of + the [N1QL](https://www.couchbase.com/products/n1ql) language from Couchbase Server, which + you can think of as "SQL for JSON" or "SQL++". + + Supported Query languages: + [N1QL](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) + + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + + JSON language resembles a parse tree of N1QL. The JSON syntax is harder for humans, but much more + amenable to machine generation, if you need to create queries programmatically or translate + them from some other form. + */ + +/** \name Query objects + @{ */ + +/** Creates a new query by compiling the input string. + This is fast, but not instantaneous. If you need to run the same query many times, keep the + \ref CBLQuery around instead of compiling it each time. If you need to run related queries + with only some values different, create one query with placeholder parameter(s), and substitute + the desired value(s) with \ref CBLQuery_SetParameters each time you run the query. + @note You must release the \ref CBLQuery when you're finished with it. + @param db The database to query. + @param language The query language, + [JSON](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) or + [N1QL](https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/index.html). + @param queryString The query string. + @param outErrorPos If non-NULL, then on a parse error the approximate byte offset in the + input expression will be stored here (or -1 if not known/applicable.) + @param outError On failure, the error will be written here. + @return The new query object. */ +_cbl_warn_unused +CBLQuery* _cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase* db, + CBLQueryLanguage language, + FLString queryString, + int* _cbl_nullable outErrorPos, + CBLError* _cbl_nullable outError) CBLAPI; + +CBL_REFCOUNTED(CBLQuery*, Query); + +/** Assigns values to the query's parameters. + These values will be substited for those parameters whenever the query is executed, + until they are next assigned. + + Parameters are specified in the query source as + e.g. `$PARAM` (N1QL) or `["$PARAM"]` (JSON). In this example, the `parameters` dictionary + to this call should have a key `PARAM` that maps to the value of the parameter. + @param query The query. + @param parameters The parameters in the form of a Fleece \ref FLDict "dictionary" whose + keys are the parameter names. (It's easiest to construct this by using the mutable + API, i.e. calling \ref FLMutableDict_New and adding keys/values.) */ +void CBLQuery_SetParameters(CBLQuery* query, + FLDict parameters) CBLAPI; + +/** Returns the query's current parameter bindings, if any. */ +FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery* query) CBLAPI; + +/** Runs the query, returning the results. + To obtain the results you'll typically call \ref CBLResultSet_Next in a `while` loop, + examining the values in the \ref CBLResultSet each time around. + @note You must release the result set when you're finished with it. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns information about the query, including the translated SQLite form, and the search + strategy. You can use this to help optimize the query: the word `SCAN` in the strategy + indicates a linear scan of the entire database, which should be avoided by adding an index. + The strategy will also show which index(es), if any, are used. + @note You are responsible for releasing the result by calling \ref FLSliceResult_Release. */ +_cbl_warn_unused +FLSliceResult CBLQuery_Explain(const CBLQuery*) CBLAPI; + +/** Returns the number of columns in each result. */ +unsigned CBLQuery_ColumnCount(const CBLQuery*) CBLAPI; + +/** Returns the name of a column in the result. + The column name is based on its expression in the `SELECT...` or `WHAT:` section of the + query. A column that returns a property or property path will be named after that property. + A column that returns an expression will have an automatically-generated name like `$1`. + To give a column a custom name, use the `AS` syntax in the query. + Every column is guaranteed to have a unique name. */ +FLSlice CBLQuery_ColumnName(const CBLQuery*, + unsigned columnIndex) CBLAPI; + +/** @} */ + + + +/** \name Result sets + @{ + A `CBLResultSet` is an iterator over the results returned by a query. It exposes one + result at a time -- as a collection of values indexed either by position or by name -- + and can be stepped from one result to the next. + + It's important to note that the initial position of the iterator is _before_ the first + result, so \ref CBLResultSet_Next must be called _first_. Example: + + ``` + CBLResultSet *rs = CBLQuery_Execute(query, &error); + assert(rs); + while (CBLResultSet_Next(rs) { + FLValue aValue = CBLResultSet_ValueAtIndex(rs, 0); + ... + } + CBLResultSet_Release(rs); + ``` + */ + +/** Moves the result-set iterator to the next result. + Returns false if there are no more results. + @warning This must be called _before_ examining the first result. */ +_cbl_warn_unused +bool CBLResultSet_Next(CBLResultSet*) CBLAPI; + +/** Returns the value of a column of the current result, given its (zero-based) numeric index. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. */ +FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet*, + unsigned index) CBLAPI; + +/** Returns the value of a column of the current result, given its name. + This may return a NULL pointer, indicating `MISSING`, if the value doesn't exist, e.g. if + the column is a property that doesn't exist in the document. (Or, of course, if the key + is not a column name in this query.) + @note See \ref CBLQuery_ColumnName for a discussion of column names. */ +FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet*, + FLString key) CBLAPI; + +/** Returns the current result as an array of column values. + @warning The array reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLArray_Retain (and release it when done.) */ +FLArray CBLResultSet_ResultArray(const CBLResultSet*) CBLAPI; + +/** Returns the current result as a dictionary mapping column names to values. + @warning The dict reference is only valid until the result-set is advanced or released. + If you want to keep it for longer, call \ref FLDict_Retain (and release it when done.) */ +FLDict CBLResultSet_ResultDict(const CBLResultSet*) CBLAPI; + +/** Returns the Query that created this ResultSet. */ +CBLQuery* CBLResultSet_GetQuery(const CBLResultSet *rs) CBLAPI; + +CBL_REFCOUNTED(CBLResultSet*, ResultSet); + +/** @} */ + + +/** \name Change listener + @{ + Adding a change listener to a query turns it into a "live query". When changes are made to + documents, the query will periodically re-run and compare its results with the prior + results; if the new results are different, the listener callback will be called. + + @note The result set passed to the listener is the _entire new result set_, not just the + rows that changed. + */ + +/** A callback to be invoked after the query's results have changed. + The actual result set can be obtained by calling \ref CBLQuery_CopyCurrentResults, either during + the callback or at any time thereafter. + @warning By default, this listener may be called on arbitrary threads. If your code isn't + prepared for that, you may want to use \ref CBLDatabase_BufferNotifications + so that listeners will be called in a safe context. + @param context The same `context` value that you passed when adding the listener. + @param query The query that triggered the listener. + @param token The token for obtaining the query results by calling \ref CBLQuery_CopyCurrentResults. */ +typedef void (*CBLQueryChangeListener)(void* _cbl_nullable context, + CBLQuery* query, + CBLListenerToken* token); + +/** Registers a change listener callback with a query, turning it into a "live query" until + the listener is removed (via \ref CBLListener_Remove). + + When the first change listener is added, the query will run (in the background) and notify + the listener(s) of the results when ready. After that, it will run in the background after + the database changes, and only notify the listeners when the result set changes. + @param query The query to observe. + @param listener The callback to be invoked. + @param context An opaque value that will be passed to the callback. + @return A token to be passed to \ref CBLListener_Remove when it's time to remove the + listener.*/ +_cbl_warn_unused +CBLListenerToken* CBLQuery_AddChangeListener(CBLQuery* query, + CBLQueryChangeListener listener, + void* _cbl_nullable context) CBLAPI; + +/** Returns the query's _entire_ current result set, after it's been announced via a call to the + listener's callback. + @note You must release the result set when you're finished with it. + @param query The query being listened to. + @param listener The query listener that was notified. + @param outError If the query failed to run, the error will be stored here. + @return A new object containing the query's current results, or NULL if the query failed to run. */ +_cbl_warn_unused +CBLResultSet* _cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery* query, + CBLListenerToken *listener, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h new file mode 100644 index 0000000..79bed5a --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndex.h @@ -0,0 +1,161 @@ +// +// CBLQueryIndex.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ + Indexes are used to speed up queries by allowing fast -- O(log n) -- lookup of documents + that have specific values or ranges of values. The values may be properties, or expressions + based on properties. + + An index will speed up queries that use the expression it indexes, but it takes up space in + the database file, and it slows down document saves slightly because it needs to be kept up + to date when documents change. + + Tuning a database with indexes can be a tricky task. Fortunately, a lot has been written about + it in the relational-database (SQL) realm, and much of that advice holds for Couchbase Lite. + You may find SQLite's documentation particularly helpful since Couchbase Lite's querying is + based on SQLite. + + Supported index types: + * Value indexes speed up queries by making it possible to look up property (or expression) + values without scanning every document. They're just like regular indexes in SQL or N1QL. + Multiple expressions are supported; the first is the primary key, second is secondary. + Expressions must evaluate to scalar types (boolean, number, string). + + * Full-Text Search (FTS) indexes enable fast search of natural-language words or phrases + by using the `MATCH()` function in a query. A FTS index is **required** for full-text + search: a query with a `MATCH()` function will fail to compile unless there is already a + FTS index for the property/expression being matched. + + * (Enterprise Edition Only) Vector indexes allows efficient search of ML vectors by using + the `VECTOR_MATCH()` function in a query. The `CouchbaseLiteVectorSearch` + extension library is **required** to use the functionality. Use \ref CBL_EnableVectorSearch + function to set the directoary path containing the extension library. */ + +/** \name CBLQueryIndex + @{ + CBLQueryIndex represents an existing index in a collection. + + Available in the enterprise edition, the \ref CBLQueryIndex can be used to obtain + a \ref CBLIndexUpdater object for updating the vector index in lazy mode. */ +CBL_REFCOUNTED(CBLQueryIndex*, QueryIndex); + +/** Returns the index's name. + @param index The index. + @return The name of the index. */ +FLString CBLQueryIndex_Name(const CBLQueryIndex* index) CBLAPI; + +/** Returns the collection that the index belongs to. + @param index The index. + @return A \ref CBLCollection instance that the index belongs to. */ +CBLCollection* CBLQueryIndex_Collection(const CBLQueryIndex* index) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE + +CBL_REFCOUNTED(CBLIndexUpdater*, IndexUpdater); + +/** ENTERPRISE EDITION ONLY + + Finds new or updated documents for which vectors need to be (re)computed and returns an \ref CBLIndexUpdater object + for setting the computed vectors to update the index. If the index is not lazy, an error will be returned. + @note For updating lazy vector indexes only. + @note You are responsible for releasing the returned A \ref CBLIndexUpdater object. + @param index The index. + @param limit The maximum number of vectors to be computed. + @param outError On failure, an error is written here. + @return A \ref CBLIndexUpdater object for setting the computed vectors to update the index, + or NULL if the index is up-to-date or an error occurred. */ +_cbl_warn_unused +CBLIndexUpdater* _cbl_nullable CBLQueryIndex_BeginUpdate(CBLQueryIndex* index, + size_t limit, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ + +/** \name IndexUpdater + @{ + CBLIndexUpdater used for updating the index in lazy mode. Currently, the vector index is the only index type that + can be updated lazily. + */ + +/** ENTERPRISE EDITION ONLY + + Returns the total number of vectors to compute and set for updating the index. + @param updater The index updater. + @return The total number of vectors to compute and set for updating the index. */ +size_t CBLIndexUpdater_Count(const CBLIndexUpdater* updater) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Returns the valut at the given index to compute a vector from. + @note The returned Fleece value is valid unilt its \ref CBLIndexUpdater is released. + If you want to keep it longer, retain it with `FLRetain`. + @param updater The index updater. + @param index The zero-based index. + @return A Fleece value of the index's evaluated expression at the given index. */ +FLValue CBLIndexUpdater_Value(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Sets the vector for the value corresponding to the given index. + Setting null vector means that there is no vector for the value, and any existing vector + will be removed when the `CBLIndexUpdater_Finish` is called. + @param updater The index updater. + @param index The zero-based index. + @param vector A pointer to the vector which is an array of floats, or NULL if there is no vector. + @param dimension The dimension of `vector`. Must be equal to the dimension value set in the vector index config. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_SetVector(CBLIndexUpdater* updater, + size_t index, + const float vector[_cbl_nullable], + size_t dimension, + CBLError* _cbl_nullable outError) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Skip setting the vector for the value corresponding to the index. + The vector will be required to compute and set again when the `CBLQueryIndex_BeginUpdate` is later called. + @param updater The index updater. + @param index The zero-based index. */ +void CBLIndexUpdater_SkipVector(CBLIndexUpdater* updater, size_t index) CBLAPI; + +/** ENTERPRISE EDITION ONLY + + Updates the index with the computed vectors and removes any index rows for which null vector was given. + If there are any indexes that do not have their vector value set or are skipped, a error will be returned. + @note Before calling `CBLIndexUpdater_Finish`, the set vectors are kept in the memory. + @warning The index updater cannot be used after calling `CBLIndexUpdater_Finish`. + @param updater The index updater. + @param outError On failure, an error is written here. + @return True if success, or False if an error occurred. */ +bool CBLIndexUpdater_Finish(CBLIndexUpdater* updater, CBLError* _cbl_nullable outError) CBLAPI; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h new file mode 100644 index 0000000..b26350e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryIndexTypes.h @@ -0,0 +1,206 @@ +// +// CBLQueryIndexTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 +#include + +CBL_CAPI_BEGIN + +/** \defgroup index Index + @{ */ + +/** \name Index Configuration + @{ */ + +/** Value Index Configuration. */ +typedef struct { + /** The language used in the expressions. */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. */ + FLString expressions; +} CBLValueIndexConfiguration; + +/** Full-Text Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expressions describing each coloumn of the index. The expressions could be specified + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ + FLString expressions; + + /** Should diacritical marks (accents) be ignored? + Defaults to \ref kCBLDefaultFullTextIndexIgnoreAccents. + Generally this should be left `false` for non-English text. */ + bool ignoreAccents; + + /** The dominant language. Setting this enables word stemming, i.e. + matching different cases of the same word ("big" and "bigger", for instance) and ignoring + common "stop-words" ("the", "a", "of", etc.) + + Can be an ISO-639 language code or a lowercase (English) language name; supported + languages are: da/danish, nl/dutch, en/english, fi/finnish, fr/french, de/german, + hu/hungarian, it/italian, no/norwegian, pt/portuguese, ro/romanian, ru/russian, + es/spanish, sv/swedish, tr/turkish. + + If left null, or set to an unrecognized language, no language-specific behaviors + such as stemming and stop-word removal occur. */ + FLString language; +} CBLFullTextIndexConfiguration; + +/** Array Index Configuration for indexing property values within arrays + in documents, intended for use with the UNNEST query. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** Path to the array, which can be nested to be indexed (Required). + Use "[]" to represent a property that is an array of each nested array level. + For a single array or the last level array, the "[]" is optional. For instance, + use "contacts[].phones" to specify an array of phones within each contact. */ + FLString path; + + /** Optional expressions representing the values within the array to be + indexed. The expressions could be specified in a JSON Array or in N1QL syntax + using comma delimiter. If the array specified by the path contains scalar values, + the expressions should be left unset or set to null. */ + FLString expressions; +} CBLArrayIndexConfiguration; + +#ifdef COUCHBASE_ENTERPRISE + +/** An opaque object representing vector encoding type to use in CBLVectorIndexConfiguration. */ +typedef struct CBLVectorEncoding CBLVectorEncoding; + +/** Creates a no-encoding type to use in CBLVectorIndexConfiguration; 4 bytes per dimension, no data loss. + @return A None encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateNone(void) CBLAPI; + +/** Scalar Quantizer encoding type */ +typedef CBL_ENUM(uint32_t, CBLScalarQuantizerType) { + kCBLSQ4 = 4, ///< 4 bits per dimension + kCBLSQ6 = 6, ///< 6 bits per dimension + kCBLSQ8 = 8 ///< 8 bits per dimension +}; + +/** Creates a Scalar Quantizer encoding to use in CBLVectorIndexConfiguration. + @param type Scalar Quantizer Type. + @return A Scalar Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateScalarQuantizer(CBLScalarQuantizerType type) CBLAPI; + +/** Creates a Product Quantizer encoding to use in CBLVectorIndexConfiguration. + @param subquantizers Number of subquantizers. Must be > 1 and a factor of vector dimensions. + @param bits Number of bits. Must be >= 4 and <= 12. + @return A Product Quantizer encoding object. */ +_cbl_warn_unused +CBLVectorEncoding* CBLVectorEncoding_CreateProductQuantizer(unsigned subquantizers, unsigned bits) CBLAPI; + +/** Frees a CBLVectorEncoding object. The encoding object can be freed after the index is created. */ +void CBLVectorEncoding_Free(CBLVectorEncoding* _cbl_nullable) CBLAPI; + +/** Distance metric to use in CBLVectorIndexConfiguration. */ +typedef CBL_ENUM(uint32_t, CBLDistanceMetric) { + kCBLDistanceMetricEuclideanSquared = 1, ///< Squared Euclidean distance (AKA Squared L2) + kCBLDistanceMetricCosine, ///< Cosine distance (1.0 - Cosine Similarity) + kCBLDistanceMetricEuclidean, ///< Euclidean distance (AKA L2) + kCBLDistanceMetricDot ///< Dot-product distance (Negative of dot-product) +}; + +/** ENTERPRISE EDITION ONLY + + Vector Index Configuration. */ +typedef struct { + /** The language used in the expressions (Required). */ + CBLQueryLanguage expressionLanguage; + + /** The expression could be specified in a JSON Array or in N1QL syntax depending on + the expressionLanguage. (Required) + + For non-lazy indexes, an expression returning either a vector, which is an array of 32-bit + floating-point numbers, or a Base64 string representing an array of 32-bit floating-point + numbers in little-endian order. + + For lazy indexex, an expression returning a value for computing a vector lazily when using + \ref CBLIndexUpdater to add or update the vector into the index. */ + FLString expression; + + /** The number of vector dimensions. (Required) + @note The maximum number of vector dimensions supported is 4096. */ + unsigned dimensions; + + /** The number of centroids which is the number buckets to partition the vectors in the index. (Required) + @note The recommended number of centroids is the square root of the number of vectors to be indexed, + and the maximum number of centroids supported is 64,000.*/ + unsigned centroids; + + /** The boolean flag indicating that index is lazy or not. The default value is false. + + If the index is lazy, it will not be automatically updated when the documents in the collection are changed, + except when the documents are deleted or purged. + + When configuring the index to be lazy, the expression set to the config is the expression that returns + a value used for computing the vector. + + To update the lazy index, use a CBLIndexUpdater object, which can be obtained + from a CBLQueryIndex object. To get a CBLQueryIndex object, call CBLCollection_GetIndex. */ + bool isLazy; + + /** Vector encoding type. The default value is 8-bits Scalar Quantizer. */ + CBLVectorEncoding* encoding; + + /** Distance Metric type. The default value is euclidean distance. */ + CBLDistanceMetric metric; + + /** The minimum number of vectors for training the index. + The default value is zero, meaning that minTrainingSize will be determined based on + the number of centroids, encoding types, and the encoding parameters. + + @note The training will occur at or before the APPROX_VECTOR_DISANCE query is + executed, provided there is enough data at that time, and consequently, if + training is triggered during a query, the query may take longer to return + results. + + @note If a query is executed against the index before it is trained, a full + scan of the vectors will be performed. If there are insufficient vectors + in the database for training, a warning message will be logged, + indicating the required number of vectors. */ + unsigned minTrainingSize; + + /** The maximum number of vectors used for training the index. + The default value is zero, meaning that the maxTrainingSize will be determined based on + the number of centroids, encoding types, and encoding parameters. */ + unsigned maxTrainingSize; + + /** The number of centroids that will be scanned during a query. + The default value is zero, meaning that the numProbes will be determined based on + the number of centroids. */ + unsigned numProbes; +} CBLVectorIndexConfiguration; + +#endif + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h new file mode 100644 index 0000000..25ad9aa --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQueryTypes.h @@ -0,0 +1,35 @@ +// +// CBLQueryTypes.h +// +// Copyright (c) 2024 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup queries Queries + @{ */ + +/** Supported Query languages */ +typedef CBL_ENUM(uint32_t, CBLQueryLanguage) { + kCBLJSONLanguage, ///< [JSON query schema](https://github.com/couchbase/couchbase-lite-core/wiki/JSON-Query-Schema) + kCBLN1QLLanguage ///< [N1QL syntax](https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/index.html) +}; + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h new file mode 100644 index 0000000..1c61c87 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -0,0 +1,640 @@ +// +// CBLReplicator.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + +CBL_CAPI_BEGIN + +/** \defgroup replication Replication + A replicator is a background task that synchronizes changes between a local database and + another database on a remote server (or on a peer device, or even another local database.) + @{ */ + +/** \name Configuration + @{ */ + +/** The name of the HTTP cookie used by Sync Gateway to store session keys. */ +CBL_PUBLIC extern const FLString kCBLAuthDefaultCookieName; + +/** An opaque object representing the location of a database to replicate with. */ +typedef struct CBLEndpoint CBLEndpoint; + +/** Creates a new endpoint representing a server-based database at the given URL. + The URL's scheme must be `ws` or `wss`, it must of course have a valid hostname, + and its path must be the name of the database on that server. + + The port can be omitted; it defaults to 80 for `ws` and 443 for `wss`. + For example: `wss://example.org/dbname`. + + If an invalid endpoint URL is specified, an error will be returned. + */ +_cbl_warn_unused +CBLEndpoint* _cbl_nullable CBLEndpoint_CreateWithURL(FLString url, + CBLError* _cbl_nullable outError) CBLAPI; + +#ifdef COUCHBASE_ENTERPRISE +/** Creates a new endpoint representing another local database. (Enterprise Edition only.) */ +_cbl_warn_unused +CBLEndpoint* CBLEndpoint_CreateWithLocalDB(CBLDatabase*) CBLAPI; +#endif + +/** Frees a CBLEndpoint object. */ +void CBLEndpoint_Free(CBLEndpoint* _cbl_nullable) CBLAPI; + + +/** An opaque object representing authentication credentials for a remote server. */ +typedef struct CBLAuthenticator CBLAuthenticator; + +/** Creates an authenticator for HTTP Basic (username/password) auth. */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreatePassword(FLString username, FLString password) CBLAPI; + +/** Creates an authenticator using a Couchbase Sync Gateway login session identifier, + and optionally a cookie name (pass NULL for the default.) */ +_cbl_warn_unused +CBLAuthenticator* CBLAuth_CreateSession(FLString sessionID, FLString cookieName) CBLAPI; + +/** Frees a CBLAuthenticator object. */ +void CBLAuth_Free(CBLAuthenticator* _cbl_nullable) CBLAPI; + + +/** Direction of replication: push, pull, or both. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorType) { + kCBLReplicatorTypePushAndPull = 0, ///< Bidirectional; both push and pull + kCBLReplicatorTypePush, ///< Pushing changes to the target + kCBLReplicatorTypePull ///< Pulling changes from the target +}; + + +/** Flags describing a replicated document. */ +typedef CBL_OPTIONS(unsigned, CBLDocumentFlags) { + kCBLDocumentFlagsDeleted = 1 << 0, ///< The document has been deleted. + kCBLDocumentFlagsAccessRemoved = 1 << 1 ///< Lost access to the document on the server. +}; + + +/** A callback that can decide whether a particular document should be pushed or pulled. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param document The document in question. + @param flags Indicates whether the document was deleted or removed. + @return True if the document should be replicated, false to skip it. */ +typedef bool (*CBLReplicationFilter)(void* _cbl_nullable context, + CBLDocument* document, + CBLDocumentFlags flags); + +/** Conflict-resolution callback for use in replications. This callback will be invoked + when the replicator finds a newer server-side revision of a document that also has local + changes. The local and remote changes must be resolved before the document can be pushed + to the server. + @note Any new CBLBlob objects set to the resolved document returned by the callback must + not be released. They need to be retained for installation while the resolved document + is being saved into the database, and the replicator will be responsible for + releasing them after they are installed. + @warning This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. However, unlike a filter callback, + it does not need to return quickly. If it needs to prompt for user input, + that's OK. + @param context The `context` field of the \ref CBLReplicatorConfiguration. + @param documentID The ID of the conflicted document. + @param localDocument The current revision of the document in the local database, + or NULL if the local document has been deleted. + @param remoteDocument The revision of the document found on the server, + or NULL if the document has been deleted on the server. + @return The resolved document to save locally (and push, if the replicator is pushing.) + This can be the same as \p localDocument or \p remoteDocument, or you can create + a mutable copy of either one and modify it appropriately. + Or return NULL if the resolution is to delete the document. */ +typedef const CBLDocument* _cbl_nullable (*CBLConflictResolver)(void* _cbl_nullable context, + FLString documentID, + const CBLDocument* _cbl_nullable localDocument, + const CBLDocument* _cbl_nullable remoteDocument); + +/** Default conflict resolver. This always returns `localDocument`. */ +CBL_PUBLIC extern const CBLConflictResolver CBLDefaultConflictResolver; + + +/** Types of proxy servers, for CBLProxySettings. */ +typedef CBL_ENUM(uint8_t, CBLProxyType) { + kCBLProxyHTTP, ///< HTTP proxy; must support 'CONNECT' method + kCBLProxyHTTPS, ///< HTTPS proxy; must support 'CONNECT' method +}; + + +/** Proxy settings for the replicator. */ +typedef struct { + CBLProxyType type; ///< Type of proxy + FLString hostname; ///< Proxy server hostname or IP address + uint16_t port; ///< Proxy server port + FLString username; ///< Username for proxy auth (optional) + FLString password; ///< Password for proxy auth +} CBLProxySettings; + +#ifdef COUCHBASE_ENTERPRISE + +/** Callback that encrypts \ref CBLEncryptable properties in the documents of the default collection + pushed by the replicator. The callback returns encrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyEncryptor instead. */ +typedef FLSliceResult (*CBLPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents of the default collection + pulled by the replicator. The callback returns decrypted data as a FLSliceResult object, + and the replicator will responsible for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). + @warning Deprecated : Use CBLDocumentPropertyDecryptor instead. */ +typedef FLSliceResult (*CBLPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +/** Callback that encrypts \ref CBLEncryptable properties in the documents pushed by the replicator. + The callback returns encrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during encryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during encryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the encryption callback + will be called again to encrypt the properties of the document. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + or only a null \ref FLSliceResult object is returned without setting an error, the document + will be failed to replicate as the kCBLDomain / kCBLErrorCrypto error is sepecified. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyEncryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be encrypted + FLSlice input, ///< Property data to be encrypted + FLStringResult* algorithm, ///< On return: algorithm name (Optional: Default Value is 'CB_MOBILE_CUSTOM') + FLStringResult* kid, ///< On return: encryption key identifier (Optional) + CBLError* error ///< On return: error (Optional) +); + +/** Callback that decrypts encrypted \ref CBLEncryptable properties in documents pulled by the replicator. + The callback returns decrypted data as a FLSliceResult object, and the replicator will responsible + for releasing the returned FLSliceResult object. + + If an error occurred during decryption, return a null \ref FLSliceResult with an error set to the + out error parameter of the callback. There are two errors that are supported by the callback : + + 1. kCBLDomain / kCBLErrorCrypto : Permanent Crypto Error. When this error is set, the document + will fail to replicate, and the document will not be synced again unless the document is updated, + or the replicator is reset. + + 2. kCBLWebSocketDomain / 503 : Service Unavailable Error. This error is for mostly for a case + such as when a crypto service is temporarily unavailable during decryption. When this error + is set, the replicator will go into the offline state and will retry again according to the replicator + retry logic. As a result, the document will be retried to replicate again, and the decryption callback + will be called again to decrypt the properties of the document. + + If the decryption should be skipped to retain the encrypted data as-is, return a null \ref FLSliceResult + object without setting an error set to the out error parameter. + + @note If an error besides the two errors above is set to the out error parameter of the callback, + the document will be failed to replicate as getting the kCBLDomain / kCBLErrorCrypto error. + @note A null \ref FLSliceResult can be created by calling FLSliceResult_CreateWith(nullptr, 0). */ +typedef FLSliceResult (*CBLDocumentPropertyDecryptor) ( + void* context, ///< Replicator’s context + FLString scope, ///< Scope's name of the collection + FLString collection, ///< Collection's name + FLString documentID, ///< Document ID + FLDict properties, ///< Document properties + FLString keyPath, ///< Key path of the property to be decrypted + FLSlice input, ///< Property data to be decrypted + FLString algorithm, ///< Algorithm name + FLString kid, ///< Encryption key identifier specified when encryting the value + CBLError* error ///< On return: error (Optional) +); + +#endif + +/** The collection and the configuration that can be configured specifically for the replication. */ +typedef struct { + CBLCollection* collection; ///< The collection. + + CBLConflictResolver _cbl_nullable conflictResolver; ///< Optional conflict-resolver callback + + CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed + CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs. + + /** Optional set of channels to pull from. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. */ + FLArray _cbl_nullable channels; + FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate +} CBLReplicationCollection; + +/** The configuration of a replicator. */ +typedef struct { + /** The database to replicate. When setting the database, ONLY the default collection will be used for replication. + (Required if collections is not set) + @warning Deprecated : Use collections instead. */ + CBLDatabase* _cbl_nullable database; + /** The address of the other database to replicate with (Required) */ + CBLEndpoint* endpoint; ///< + + //-- Types: + + /** Push, pull or both. The default value is \ref kCBLDefaultReplicatorType. */ + CBLReplicatorType replicatorType; + + /** Continuous replication?. The default value is \ref kCBLDefaultReplicatorContinuous. */ + bool continuous; + + //-- Auto Purge: + + /** If auto purge is active, then the library will automatically purge any documents that + the replicating user loses access to via the Sync Function on Sync Gateway. + If disableAutoPurge is true, this behavior is disabled and an access removed + event will be sent to any document listeners that are active on the replicator. + The default value is \ref kCBLDefaultReplicatorDisableAutoPurge. + + \note Auto Purge will not be performed when documentIDs filter is specified. + */ + bool disableAutoPurge; + + //-- Retry Logic: + + /** Max retry attempts where the initial connect to replicate counts toward the given value. + The default value is \ref kCBLDefaultReplicatorMaxAttemptsSingleShot for a one-shot replicator + and \ref kCBLDefaultReplicatorMaxAttemptsContinuous for a continuous replicator. + Specify 1 means there will be no retry after the first attempt. */ + unsigned maxAttempts; + + /** Max wait time between retry attempts in seconds. + The default value \ref kCBLDefaultReplicatorMaxAttemptsWaitTime. */ + unsigned maxAttemptWaitTime; + + //-- WebSocket: + + /** The heartbeat interval in seconds. + The default value is \ref kCBLDefaultReplicatorHeartbeat. */ + unsigned heartbeat; + +#ifdef __CBL_REPLICATOR_NETWORK_INTERFACE__ + /** The specific network interface to be used by the replicator to connect to the remote server. + If not specified, an active network interface based on the OS's routing table will be used. + @NOTE The networkInterface configuration is not supported. + */ + FLString networkInterface; +#endif + + //-- HTTP settings: + + CBLAuthenticator* _cbl_nullable authenticator; ///< Authentication credentials, if needed + const CBLProxySettings* _cbl_nullable proxy; ///< HTTP client proxy settings + FLDict _cbl_nullable headers; ///< Extra HTTP headers to add to the WebSocket request + + //-- TLS settings: + + /** An X.509 cert (PEM or DER) to "pin" for TLS connections. The pinned cert will be evaluated against any certs + in a cert chain, and the cert chain will be valid only if the cert chain contains the pinned cert. */ + FLSlice pinnedServerCertificate; + FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + //-- Filtering: + + /** Optional set of channels to pull from when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @note Channels are not supported in Peer-to-Peer and Database-to-Database replication. + @warning Deprecated : Use CBLReplicationCollection.channels instead. */ + FLArray _cbl_nullable channels; + + /** Optional set of document IDs to replicate when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.documentIDs instead. */ + FLArray _cbl_nullable documentIDs; + + /** Optional callback to filter which docs are pushed when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pushFilter instead. */ + CBLReplicationFilter _cbl_nullable pushFilter; + + /** Optional callback to validate incoming docs when replicating with the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.pullFilter instead. */ + CBLReplicationFilter _cbl_nullable pullFilter; + + //-- Conflict Resolver: + + /** Optional conflict-resolver callback. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use CBLReplicationCollection.conflictResolver instead. */ + CBLConflictResolver _cbl_nullable conflictResolver; + + //-- Context: + void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + +#ifdef COUCHBASE_ENTERPRISE + //-- Property Encryption + /** Optional callback to encrypt \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyEncryptor instead. */ + CBLPropertyEncryptor _cbl_nullable propertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values of the documents in the default collection. + @note This property can only be used when setting the config object with the database instead of collections. + @warning Deprecated : Use documentPropertyDecryptor instead. */ + CBLPropertyDecryptor _cbl_nullable propertyDecryptor; + + /** Optional callback to encrypt \ref CBLEncryptable values. */ + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; + + /** Optional callback to decrypt encrypted \ref CBLEncryptable values. */ + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; +#endif + + /** The collections to replicate with the target's endpoint (Required if the database is not set). */ + CBLReplicationCollection* _cbl_nullable collections; + + /** The number of collections (Required if the database is not set */ + size_t collectionCount; + + //-- Advanced HTTP settings: + + /** The option to remove the restriction that does not allow the replicator to save the parent-domain + cookies, the cookies whose domains are the parent domain of the remote host, from the HTTP + response. For example, when the option is set to true, the cookies whose domain are “.foo.com” + returned by “bar.foo.com” host will be permitted to save. This is only recommended if the host + issuing the cookie is well trusted. + + This option is disabled by default (see \ref kCBLDefaultReplicatorAcceptParentCookies) which means + that the parent-domain cookies are not permitted to save by default. */ + bool acceptParentDomainCookies; +} CBLReplicatorConfiguration; + + +/** @} */ + + +/** \name Lifecycle + @{ */ + +CBL_REFCOUNTED(CBLReplicator*, Replicator); + +/** Creates a replicator with the given configuration. */ +_cbl_warn_unused +CBLReplicator* _cbl_nullable CBLReplicator_Create(const CBLReplicatorConfiguration*, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns the configuration of an existing replicator. */ +const CBLReplicatorConfiguration* CBLReplicator_Config(CBLReplicator*) CBLAPI; + +/** Starts a replicator, asynchronously. Does nothing if it's already started. + @note Replicators cannot be started from within a database's transaction. + @param replicator The replicator instance. + @param resetCheckpoint If true, the persistent saved state ("checkpoint") for this replication + will be discarded, causing it to re-scan all documents. This significantly + increases time and bandwidth (redundant docs are not transferred, but their + IDs are) but can resolve unexpected problems with missing documents if one + side or the other has gotten out of sync. */ +void CBLReplicator_Start(CBLReplicator *replicator, + bool resetCheckpoint) CBLAPI; + +/** Stops a running replicator, asynchronously. Does nothing if it's not already started. + The replicator will call your \ref CBLReplicatorChangeListener with an activity level of + \ref kCBLReplicatorStopped after it stops. Until then, consider it still active. */ +void CBLReplicator_Stop(CBLReplicator*) CBLAPI; + +/** Informs the replicator whether it's considered possible to reach the remote host with + the current network configuration. The default value is true. This only affects the + replicator's behavior while it's in the Offline state: + * Setting it to false will cancel any pending retry and prevent future automatic retries. + * Setting it back to true will initiate an immediate retry.*/ +void CBLReplicator_SetHostReachable(CBLReplicator*, + bool reachable) CBLAPI; + +/** Puts the replicator in or out of "suspended" state. The default is false. + * Setting suspended=true causes the replicator to disconnect and enter Offline state; + it will not attempt to reconnect while it's suspended. + * Setting suspended=false causes the replicator to attempt to reconnect, _if_ it was + connected when suspended, and is still in Offline state. */ +void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; + +/** @} */ + + +/** \name Status and Progress + @{ + */ + +/** The possible states a replicator can be in during its lifecycle. */ +typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { + kCBLReplicatorStopped, ///< The replicator is unstarted, finished, or hit a fatal error. + kCBLReplicatorOffline, ///< The replicator is offline, as the remote host is unreachable. + kCBLReplicatorConnecting, ///< The replicator is connecting to the remote host. + kCBLReplicatorIdle, ///< The replicator is inactive, waiting for changes to sync. + kCBLReplicatorBusy ///< The replicator is actively transferring data. +}; + +/** A fractional progress value, ranging from 0.0 to 1.0 as replication progresses. + The value is very approximate and may bounce around during replication; making it more + accurate would require slowing down the replicator and incurring more load on the server. + It's fine to use in a progress bar, though. */ +typedef struct { + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ +_cbl_warn_unused +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document in the default collection with the given ID has local changes that + have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the default collection is not part of the replication, a NULL with an error + will be returned. + @warning Deprecated : Use CBLReplicator_IsDocumentPending2 instead. */ +bool CBLReplicator_IsDocumentPending(CBLReplicator *repl, + FLString docID, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates which documents in the given collection have local changes that have not yet been + pushed to the server by this replicator. This is of course a snapshot, that will go out of date + as the replicator makes progress and/or documents are saved locally. + + The result is, effectively, a set of document IDs: a dictionary whose keys are the IDs and + values are `true`. + If there are no pending documents, the dictionary is empty. + On error, NULL is returned. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs2(CBLReplicator*, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Indicates whether the document with the given ID in the given collection has local changes + that have not yet been pushed to the server by this replicator. + + This is equivalent to, but faster than, calling \ref CBLReplicator_PendingDocumentIDs2 and + checking whether the result contains \p docID. See that function's documentation for details. + @note A `false` result means the document is not pending, _or_ there was an error. + To tell the difference, compare the error code to zero. + @warning If the given collection is not part of the replication, a NULL with an error will be returned. */ +bool CBLReplicator_IsDocumentPending2(CBLReplicator *repl, + FLString docID, + const CBLCollection* collection, + CBLError* _cbl_nullable outError) CBLAPI; + +/** A callback that notifies you when the replicator's status changes. + @note This callback will be called on a background thread managed by the replicator. + It must pay attention to thread-safety. It should not take a long time to return, + or it will slow down the replicator. + @param context The value given when the listener was added. + @param replicator The replicator. + @param status The replicator's status. */ +typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, + CBLReplicator *replicator, + const CBLReplicatorStatus *status); + +/** Registers a listener that will be called when the replicator's status changes. */ +_cbl_warn_unused +CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, + CBLReplicatorChangeListener, + void* _cbl_nullable context) CBLAPI; + + +/** Information about a document that's been pushed or pulled. */ +typedef struct { + FLString ID; ///< The document ID. + CBLDocumentFlags flags; ///< Indicates whether the document was deleted or removed. + CBLError error; ///< If the code is nonzero, the document failed to replicate. + FLString scope; /// + +CBL_CAPI_BEGIN + +/** \defgroup scope Scope + @{ + A \ref CBLScope represents a scope or namespace of the collections. + + The scope implicitly exists when there is at least one collection created under the scope. + The default scope is exceptional in that it will always exists even there are no collections + under it. + + ## `CBLScope` Lifespan + `CBLScope` is ref-counted. Same as the CBLCollection, the CBLScope objects + retrieved from the database must be released after you are done using them. + When the database is closed or released, the scope objects will become invalid, + most operations on the invalid \ref CBLCollection object will fail with + \ref kCBLErrorNotOpen error result. */ + +CBL_REFCOUNTED(CBLScope*, Scope); + +/** \name Default Scope Name + @{ + The default scope name constant. + */ + +/** The default scope's name. */ +CBL_PUBLIC extern const FLString kCBLDefaultScopeName; + +/** @} */ + +/** \name Scope Accessors + @{ + Getting information about a scope. + */ + +/** Returns the name of the scope. + @param scope The scope. + @return The name of the scope. */ +FLString CBLScope_Name(const CBLScope* scope) CBLAPI; + +/** Returns the scope's database. + @note The database object is owned by the scope object; you do not need to release it. + @param scope The scope. + @return The database of the scope. */ +CBLDatabase* CBLScope_Database(const CBLScope* scope) CBLAPI; + +/** @} */ + +/** \name Collections + @{ + Accessing the collections under the scope. + */ + +/** Returns the names of all collections in the scope. + @note You are responsible for releasing the returned array. + @param scope The scope. + @param outError On failure, the error will be written here. + @return The names of all collections in the scope, or NULL if an error occurred. */ +FLMutableArray _cbl_nullable CBLScope_CollectionNames(const CBLScope* scope, + CBLError* _cbl_nullable outError) CBLAPI; + +/** Returns an existing collection in the scope with the given name. + @note You are responsible for releasing the returned collection. + @param scope The scope. + @param collectionName The name of the collection. + @param outError On failure, the error will be written here. + @return A \ref CBLCollection instance, or NULL if the collection doesn't exist or an error occurred. */ +CBLCollection* _cbl_nullable CBLScope_Collection(const CBLScope* scope, + FLString collectionName, + CBLError* _cbl_nullable outError) CBLAPI; + +/** @} */ +/** @} */ // end of outer \defgroup + +CBL_CAPI_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h new file mode 100644 index 0000000..0612778 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -0,0 +1,134 @@ +// +// CBL_Compat.h +// +// Copyright (c) 2018 Couchbase, Inc 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 + + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +#ifdef _MSC_VER + #include + #define CBLINLINE __forceinline + #define _cbl_nonnull _In_ + #define _cbl_warn_unused _Check_return_ +#else + #define CBLINLINE inline + #define _cbl_warn_unused __attribute__((warn_unused_result)) +#endif + +// Macros for defining typed enumerations and option flags. +// To define an enumeration whose values won't be combined: +// typedef CBL_ENUM(baseIntType, name) { ... }; +// To define an enumeration of option flags that will be ORed together: +// typedef CBL_OPTIONS(baseIntType, name) { ... }; +// These aren't just a convenience; they are required for Swift bindings. +#if __has_attribute(enum_extensibility) +#define __CBL_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CBL_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CBL_ENUM_ATTRIBUTES +#define __CBL_OPTIONS_ATTRIBUTES +#endif + +#if __APPLE__ + #include /* for CF_ENUM and CF_OPTIONS macros */ + #define CBL_ENUM CF_ENUM + #define CBL_OPTIONS CF_OPTIONS +#elif DOXYGEN_PARSING + #define CBL_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#else + #if (__cplusplus && _MSC_VER) || (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) + #define CBL_ENUM(_type, _name) int __CBL_ENUM_ ## _name; enum __CBL_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #if (__cplusplus) + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type + #else + #define CBL_OPTIONS(_type, _name) int __CBL_OPTIONS_ ## _name; enum __CBL_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type + #endif + #else + #define CBL_ENUM(_type, _name) _type _name; enum + #define CBL_OPTIONS(_type, _name) _type _name; enum + #endif +#endif + + +// Non-null annotations, for function parameters and struct fields. +// In between CBL_ASSUME_NONNULL_BEGIN and CBL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with _cbl_nullable (which must come after the `*`.) +// (_cbl_nonnull is occasionally necessary when there are C arrays or multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define CBL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define CBL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define _cbl_nullable _Nullable +# define _cbl_nonnull _Nonnull +#else +# define CBL_ASSUME_NONNULL_BEGIN +# define CBL_ASSUME_NONNULL_END +# define _cbl_nullable +#ifndef _cbl_nonnull +# define _cbl_nonnull +#endif +#endif + + +#ifdef __cplusplus + #define CBLAPI noexcept + #define CBL_CAPI_BEGIN extern "C" { CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END } +#else + #define CBLAPI + #define CBL_CAPI_BEGIN CBL_ASSUME_NONNULL_BEGIN + #define CBL_CAPI_END CBL_ASSUME_NONNULL_END +#endif + + +// On Windows, CBL_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with CBL_PUBLIC. See kCBLTypeProperty in CBLBlob.h and CBLBlob_CPI.cc +// for an example. +#ifdef _MSC_VER + #ifdef CBL_EXPORTS + #define CBL_PUBLIC __declspec(dllexport) + #else + #define CBL_PUBLIC __declspec(dllimport) + #endif +#else // _MSC_VER + #define CBL_PUBLIC +#endif + +// Type-checking for printf-style vararg functions: +#ifdef _MSC_VER + #define __printflike(A, B) +#else + #ifndef __printflike + #define __printflike(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + #endif +#endif + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h new file mode 100644 index 0000000..cbb4deb --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -0,0 +1,27 @@ +// +// CBL_Edition.h +// +// Copyright (c) 2018 Couchbase, Inc 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. +// + +#ifndef COUCHBASE_ENTERPRISE +#define COUCHBASE_ENTERPRISE +#endif + +#define CBLITE_VERSION "3.2.1" +#define CBLITE_VERSION_NUMBER 3002001 +#define CBLITE_BUILD_NUMBER 9 +#define CBLITE_SOURCE_ID "6728898+e322f9b" +#define CBLITE_BUILD_TIMESTAMP "2024-10-30T14:20:53Z" diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h new file mode 100644 index 0000000..382b19b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -0,0 +1,265 @@ +// +// CompilerSupport.h +// +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H + +// The __has_xxx() macros are supported by [at least] Clang and GCC. +// Define them to return 0 on other compilers. +// https://clang.llvm.org/docs/AttributeReference.html +// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +#ifndef __has_extension + #define __has_extension(x) 0 +#endif + + +// Tells the optimizer that a function's return value is never NULL. +#if __has_attribute(returns_nonnull) +# define RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define RETURNS_NONNULL +#endif + +// deprecated; use NODISCARD instead +#if __has_attribute(returns_nonnull) +# define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +# define MUST_USE_RESULT +#endif + +// NODISCARD expands to the C++17/C23 `[[nodiscard]]` attribute, or else MUST_USE_RESULT. +// (We can't just redefine MUST_USE_RESULT as `[[nodiscard]]` unfortunately, because the former is +// already in use in positions where `[[nodiscard]]` isn't valid, like at the end of a declaration.) +#if (__cplusplus >= 201700L) || (__STDC_VERSION__ >= 202000) +# define NODISCARD [[nodiscard]] +#else +# define NODISCARD MUST_USE_RESULT +#endif + +// These have no effect on behavior, but they hint to the optimizer which branch of an 'if' +// statement to make faster. +#if __has_builtin(__builtin_expect) +#define _usuallyTrue(VAL) __builtin_expect(VAL, true) +#define _usuallyFalse(VAL) __builtin_expect(VAL, false) +#else +#define _usuallyTrue(VAL) (VAL) +#define _usuallyFalse(VAL) (VAL) +#endif + + +// Nullability annotations, for function parameters and struct fields. +// In between FL_ASSUME_NONNULL_BEGIN and FL_ASSUME_NONNULL_END, all pointer declarations implicitly +// disallow NULL values, unless annotated with FL_NULLABLE (which must come after the `*`.) +// (FL_NONNULL is occasionally necessary when there are multiple levels of pointers.) +// NOTE: Only supported in Clang, so far. +#if __has_feature(nullability) +# define FL_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +# define FL_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +# define FL_NULLABLE _Nullable +# define FL_NONNULL _Nonnull +# define FL_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +# define FL_ASSUME_NONNULL_BEGIN +# define FL_ASSUME_NONNULL_END +# define FL_NULLABLE +# define FL_NONNULL +# define FL_RETURNS_NONNULL +#endif + + +// Declares that a parameter must not be NULL. The compiler can sometimes detect violations +// of this at compile time, if the parameter value is a literal. +// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime. +// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a +// parameter, it has to come after the function and list parameters by number. Oh well. +// TODO: Replace this with the better nullability annotations above. +#if __has_attribute(nonnull) +# define NONNULL __attribute__((nonnull)) +#else +# define NONNULL +#endif + + +// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable), +// and they cannot access volatile data or do I/O. +// +// Calling an FLPURE function twice in a row with the same arguments must return the same result. +// +// "Many functions have no effects except the return value, and their return value depends only on +// the parameters and/or global variables. Such a function can be subject to common subexpression +// elimination and loop optimization just as an arithmetic operator would be. These functions +// should be declared with the attribute pure." +// "The pure attribute prohibits a function from modifying the state of the program that is +// observable by means other than inspecting the function’s return value. However, functions +// declared with the pure attribute can safely read any non-volatile objects, and modify the value +// of objects in a way that does not affect their return value or the observable state of the +// program." -- GCC manual +#if __has_attribute(__pure__) +# define FLPURE __attribute__((__pure__)) +#else +# define FLPURE +#endif + +// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for +// reading immutable values like constants.) The return value can only depend on the parameters. +// +// Calling an FLCONST function with the same arguments must _always_ return the same result. +// +// "Calls to functions whose return value is not affected by changes to the observable state of the +// program and that have no observable effects on such state other than to return a value may lend +// themselves to optimizations such as common subexpression elimination. Declaring such functions +// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the +// function with the same argument values." +// "Note that a function that has pointer arguments and examines the data pointed to must not be +// declared const if the pointed-to data might change between successive invocations of the +// function. +// "In general, since a function cannot distinguish data that might change from data that cannot, +// const functions should never take pointer or, in C++, reference arguments. Likewise, a function +// that calls a non-const function usually must not be const itself." -- GCC manual +#if __has_attribute(__const__) +# define FLCONST __attribute__((__const__)) +#else +# define FLCONST +#endif + + +// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier. +// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s. +// The macro expands to `constexpr` in C++14 or later, otherwise to nothing. +#ifdef __cplusplus + #if __cplusplus >= 201400L || _MSVC_LANG >= 201400L + #define constexpr14 constexpr + #else + #define constexpr14 + #endif +#endif // __cplusplus + + +// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger +// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->, +// or slice constructors. Suppressing debug info for those functions means the debugger +// will continue through them when stepping in. +// (It probably also makes the debug-symbol file smaller.) +#if __has_attribute(nodebug) + #define STEPOVER __attribute((nodebug)) +#else + #define STEPOVER +#endif + + +// Note: Code below adapted from libmdbx source code. + +// `__optimize` is used by the macros below -- you should probably not use it directly, instead +// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function, +// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build. +#ifndef __optimize +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__optimize__) +# define __optimize(ops) +# elif defined(__GNUC__) || __has_attribute(__optimize__) +# define __optimize(ops) __attribute__((__optimize__(ops))) +# else +# define __optimize(ops) +# endif +# else +# define __optimize(ops) +# endif +#endif /* __optimize */ + +#if defined(__clang__) + #define HOTLEVEL "Ofast" + #define COLDLEVEL "Oz" +#else + #define HOTLEVEL "O3" + #define COLDLEVEL "Os" +#endif + +// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common +// code section for hot functions. Has no effect in an unoptimized build. +#ifndef __hot +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__hot__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put frequently used functions in separate section */ +# define __hot __attribute__((__section__("text.hot"))) __optimize(HOTLEVEL) +# elif defined(__GNUC__) || __has_attribute(__hot__) +# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL) +# else +# define __hot __optimize(HOTLEVEL) +# endif +# else +# define __hot +# endif +#endif /* __hot */ + +// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and +// moves it to a common code section for cold functions. Has no effect in an unoptimized build. +#ifndef __cold +# if defined(__OPTIMIZE__) +# if defined(__clang__) && !__has_attribute(__cold__) \ + && __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__)) + /* just put infrequently used functions in separate section */ +# define __cold __attribute__((__section__("text.unlikely"))) __optimize(COLDLEVEL) +# elif defined(__GNUC__) || __has_attribute(__cold__) +# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL) +# else +# define __cold __optimize(COLDLEVEL) +# endif +# else +# define __cold +# endif +#endif /* __cold */ + + +#ifndef _MSC_VER + #define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0 +#endif + +// On Windows, FLEECE_PUBLIC marks symbols as being exported from the shared library. +// However, this is not the whole list of things that are exported. The API methods +// are exported using a definition list, but it is not possible to correctly include +// initialized global variables, so those need to be marked (both in the header and +// implementation) with FLEECE_PUBLIC. See kFLNullValue below and in Fleece.cc +// for an example. +#if defined(_MSC_VER) +#ifdef FLEECE_EXPORTS +#define FLEECE_PUBLIC __declspec(dllexport) +#else +#define FLEECE_PUBLIC __declspec(dllimport) +#endif +#else +#define FLEECE_PUBLIC __attribute__((visibility("default"))) +#endif + +#ifdef __cplusplus + #define FLAPI noexcept +#else + #define FLAPI +#endif + +#else // _FLEECE_COMPILER_SUPPORT_H +#warn "Compiler is not honoring #pragma once" +#endif diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h new file mode 100644 index 0000000..bce263b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -0,0 +1,35 @@ +// +// CouchbaseLite.h +// +// Copyright (c) 2018 Couchbase, Inc 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h new file mode 100644 index 0000000..5b57154 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h @@ -0,0 +1,123 @@ +// +// FLBase.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLBASE_H +#define _FLBASE_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + //====== BASIC TYPES + + /** \defgroup types Basic Fleece Data Types + @{ */ + +#ifndef FL_IMPL + typedef const struct _FLValue* FLValue; ///< A reference to a value of any type. + typedef const struct _FLArray* FLArray; ///< A reference to an array value. + typedef const struct _FLDict* FLDict; ///< A reference to a dictionary (map) value. + typedef struct _FLSlot* FLSlot; ///< A reference to a mutable array/dict item + typedef struct _FLArray* FLMutableArray; ///< A reference to a mutable array. + typedef struct _FLDict* FLMutableDict; ///< A reference to a mutable dictionary. + typedef struct _FLEncoder* FLEncoder; ///< A reference to an encoder. + typedef struct _FLDoc* FLDoc; ///< A reference to a document. + typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. +#endif + + + /** Error codes returned from some API calls. */ + typedef enum { + kFLNoError = 0, + kFLMemoryError, // Out of memory, or allocation failed + kFLOutOfRange, // Array index or iterator out of range + kFLInvalidData, // Bad input data (NaN, non-string key, etc.) + kFLEncodeError, // Structural error encoding (missing value, too many ends, etc.) + kFLJSONError, // Error parsing JSON + kFLUnknownValue, // Unparseable data in a Value (corrupt? Or from some distant future?) + kFLInternalError, // Something that shouldn't happen + kFLNotFound, // Key not found + kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.) + kFLPOSIXError, + kFLUnsupported, // Operation is unsupported + } FLError; + + + /** Specifies whether not input data is trusted to be 100% valid Fleece. */ + typedef enum { + /** Input data is not trusted to be valid, and will be fully validated by the API call. */ + kFLUntrusted, + /** Input data is trusted to be valid. The API will perform only minimal validation when + reading it. This is faster than kFLUntrusted, but should only be used if + the data was generated by a trusted encoder and has not been altered or corrupted. For + example, this can be used to parse Fleece data previously stored by your code in local + storage. + If invalid data is read by this call, subsequent calls to Value accessor functions can + crash or return bogus results (including data from arbitrary memory locations.) */ + kFLTrusted + } FLTrust; + + + //====== TIMESTAMPS + + + /** \name Timestamps + @{ + Fleece does not have a native type for dates or times; like JSON, they are represented + as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z". + + They can also be represented more compactly as numbers, interpreted as milliseconds + since the Unix epoch (midnight at January 1 1970, UTC.) + */ + + /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */ + typedef int64_t FLTimestamp; + + /** A value representing a missing timestamp; returned when a date cannot be parsed. */ + #define FLTimestampNone INT64_MIN + + /** Returns an FLTimestamp corresponding to the current time. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI; + + /** Formats a timestamp as a date-time string in ISO-8601 format. + @note See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`. + @param timestamp A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.) + @param asUTC If true, the timestamp will be given in universal time; if false, in the + local timezone. + @return A heap-allocated string, which you are responsible for releasing. */ + FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI; + + /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`. + @note See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric + representations as well as strings. */ + FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI; + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLBASE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..5e2489e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,227 @@ +// +// FLCollections.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLCOLLECTIONS_H +#define _FLCOLLECTIONS_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + //====== ARRAY + + + /** \defgroup FLArray Fleece Arrays + @{ + FLArray is a "subclass" of FLValue, representing values that are arrays. It's always OK to + pass an FLArray to a function parameter expecting an FLValue, even though the compiler + makes you use an explicit type-cast. It's safe to type-cast the other direction, from + FLValue to FLArray, _only_ if you already know that the value is an array, e.g. by having + called FLValue_GetType on it. But it's safer to call FLValue_AsArray instead, since it + will return NULL if the value isn't an array. + */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLArray kFLEmptyArray; + + /** Returns the number of items in an array, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLArray_Count(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if an array is empty (or NULL). Depending on the array's representation, + this can be faster than `FLArray_Count(a) == 0` */ + FLEECE_PUBLIC bool FLArray_IsEmpty(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_AsMutable(FLArray FL_NULLABLE) FLAPI FLPURE; + + /** Returns an value at an array index, or NULL if the index is out of range. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArray_Get(FLArray FL_NULLABLE, uint32_t index) FLAPI FLPURE; + + /** \name Array iteration + @{ +Iterating an array typically looks like this: + +``` +FLArrayIterator iter; +FLArrayIterator_Begin(theArray, &iter); +FLValue value; +while (NULL != (value = FLArrayIterator_GetValue(&iter))) { + // ... + FLArrayIterator_Next(&iter); +} +``` + */ + + /** Opaque array iterator. Declare one on the stack and pass its address to + `FLArrayIteratorBegin`. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void* _private4; +#endif + } FLArrayIterator; + + /** Initializes a FLArrayIterator struct to iterate over an array. + Call FLArrayIteratorGetValue to get the first item, then as long as the item is not NULL, + call FLArrayIterator_Next to advance. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over, or NULL at the end. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValue(const FLArrayIterator*) FLAPI FLPURE; + + /** Returns a value in the array at the given offset from the current value. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLArrayIterator_GetValueAt(const FLArrayIterator*, uint32_t offset) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLArrayIterator_GetCount(const FLArrayIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the array is empty is always illegal. */ + FLEECE_PUBLIC bool FLArrayIterator_Next(FLArrayIterator*) FLAPI; + + /** @} */ + /** @} */ + + + //====== DICT + + + /** \defgroup FLDict Fleece Dictionaries + @{ */ + + /** A constant empty array value. */ + FLEECE_PUBLIC extern const FLDict kFLEmptyDict; + + /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ + FLEECE_PUBLIC uint32_t FLDict_Count(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if a dictionary is empty (or NULL). Depending on the dictionary's + representation, this can be faster than `FLDict_Count(a) == 0` */ + FLEECE_PUBLIC bool FLDict_IsEmpty(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_AsMutable(FLDict FL_NULLABLE) FLAPI FLPURE; + + /** Looks up a key in a dictionary, returning its value. + Returns NULL if the value is not found or if the dictionary is NULL. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_Get(FLDict FL_NULLABLE, FLSlice keyString) FLAPI FLPURE; + + + /** \name Dict iteration + @{ +Iterating a dictionary typically looks like this: + +``` +FLDictIterator iter; +FLDictIterator_Begin(theDict, &iter); +FLValue value; +while (NULL != (value = FLDictIterator_GetValue(&iter))) { + FLString key = FLDictIterator_GetKeyString(&iter); + // ... + FLDictIterator_Next(&iter); +} +``` + */ + + /** Opaque dictionary iterator. Declare one on the stack, and pass its address to + FLDictIterator_Begin. */ + typedef struct { +#if !DOXYGEN_PARSING + void* _private1; + uint32_t _private2; + bool _private3; + void *_private4, *_private5, *_private6, *_private7; + int _private8; +#endif + } FLDictIterator; + + /** Initializes a FLDictIterator struct to iterate over a dictionary. + Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, + then as long as the item is not NULL, call FLDictIterator_Next to advance. */ + FLEECE_PUBLIC void FLDictIterator_Begin(FLDict FL_NULLABLE, FLDictIterator*) FLAPI; + + /** Returns the current key being iterated over. + This Value will be a string or an integer, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value, or NULL when there are no more keys. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. + Returns NULL when there are no more values. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetValue(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the number of items remaining to be iterated, including the current one. */ + FLEECE_PUBLIC uint32_t FLDictIterator_GetCount(const FLDictIterator*) FLAPI FLPURE; + + /** Advances the iterator to the next value. + @warning It is illegal to call this when the iterator is already at the end. + In particular, calling this when the dict is empty is always illegal. */ + FLEECE_PUBLIC bool FLDictIterator_Next(FLDictIterator*) FLAPI; + + /** Cleans up after an iterator. Only needed if (a) the dictionary is a delta, and + (b) you stop iterating before the end (i.e. before FLDictIterator_Next returns false.) */ + FLEECE_PUBLIC void FLDictIterator_End(FLDictIterator*) FLAPI; + + + /** @} */ + /** \name Optimized Keys + @{ */ + + /** Opaque key for a dictionary. You are responsible for creating space for these; they can + go on the stack, on the heap, inside other objects, anywhere. + Be aware that the lookup operations that use these will write into the struct to store + "hints" that speed up future searches. */ + typedef struct { +#if !DOXYGEN_PARSING + FLSlice _private1; + void* _private2; + uint32_t _private3, private4; + bool private5; +#endif + } FLDictKey; + + /** Initializes an FLDictKey struct with a key string. + @warning The input string's memory MUST remain valid for as long as the FLDictKey is in + use! (The FLDictKey stores a pointer to the string, but does not copy it.) + @param string The key string (UTF-8). + @return An initialized FLDictKey struct. */ + FLEECE_PUBLIC FLDictKey FLDictKey_Init(FLSlice string) FLAPI; + + /** Returns the string value of the key (which it was initialized with.) */ + FLEECE_PUBLIC FLString FLDictKey_GetString(const FLDictKey*) FLAPI; + + /** Looks up a key in a dictionary using an FLDictKey. If the key is found, "hint" data will + be stored inside the FLDictKey that will speed up subsequent lookups. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDict_GetWithKey(FLDict FL_NULLABLE, FLDictKey*) FLAPI; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLCOLLECTIONS_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h new file mode 100644 index 0000000..d1699bf --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h @@ -0,0 +1,89 @@ +// +// FLDeepIterator.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDEEPITERATOR_H +#define _FLDEEPITERATOR_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLDeepIterator Fleece Deep Iterator + @{ + A deep iterator traverses every value contained in a dictionary, in depth-first order. + You can skip any nested collection by calling \ref FLDeepIterator_SkipChildren. */ + +#ifndef FL_IMPL + typedef struct _FLDeepIterator* FLDeepIterator; ///< A reference to a deep iterator. +#endif + + /** Creates a FLDeepIterator to iterate over a dictionary. + Call FLDeepIterator_GetKey and FLDeepIterator_GetValue to get the first item, + then FLDeepIterator_Next. */ + FLEECE_PUBLIC FLDeepIterator FLDeepIterator_New(FLValue FL_NULLABLE) FLAPI; + + FLEECE_PUBLIC void FLDeepIterator_Free(FLDeepIterator FL_NULLABLE) FLAPI; + + /** Returns the current value being iterated over. or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetValue(FLDeepIterator) FLAPI; + + /** Returns the parent/container of the current value, or NULL at the end of iteration. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDeepIterator_GetParent(FLDeepIterator) FLAPI; + + /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ + FLEECE_PUBLIC FLSlice FLDeepIterator_GetKey(FLDeepIterator) FLAPI; + + /** Returns the array index of the current value in its parent, or 0 if not in an array. */ + FLEECE_PUBLIC uint32_t FLDeepIterator_GetIndex(FLDeepIterator) FLAPI; + + /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ + FLEECE_PUBLIC size_t FLDeepIterator_GetDepth(FLDeepIterator) FLAPI; + + /** Tells the iterator to skip the children of the current value. */ + FLEECE_PUBLIC void FLDeepIterator_SkipChildren(FLDeepIterator) FLAPI; + + /** Advances the iterator to the next value, or returns false if at the end. */ + FLEECE_PUBLIC bool FLDeepIterator_Next(FLDeepIterator) FLAPI; + + typedef struct { + FLSlice key; ///< Dict key, or kFLSliceNull if none + uint32_t index; ///< Array index, only if there's no key + } FLPathComponent; + + /** Returns the path as an array of FLPathComponents. */ + FLEECE_PUBLIC void FLDeepIterator_GetPath(FLDeepIterator, + FLPathComponent* FL_NONNULL * FL_NONNULL outPath, + size_t* outDepth) FLAPI; + + /** Returns the current path in JavaScript format. */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator) FLAPI; + + /** Returns the current path in JSONPointer format (RFC 6901). */ + FLEECE_PUBLIC FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDEEPITERATOR_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..49f4747 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h @@ -0,0 +1,104 @@ +// +// FLDoc.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLDOC_H +#define _FLDOC_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup reading Reading Fleece Data + @{ + \name FLDoc + @{ + An FLDoc points to (and often owns) Fleece-encoded data and provides access to its + Fleece values. + */ + + + /** Creates an FLDoc from Fleece-encoded data that's been returned as a result from + FLSlice_Copy or other API. The resulting document retains the data, so you don't need to + worry about it remaining valid. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, + FLSharedKeys FL_NULLABLE, FLSlice externData) FLAPI; + + /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ + FLEECE_PUBLIC void FLDoc_Release(FLDoc FL_NULLABLE) FLAPI; + + /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you + call FLRelease to remove the reference. */ + FLEECE_PUBLIC FLDoc FLDoc_Retain(FLDoc FL_NULLABLE) FLAPI; + + /** Returns the encoded Fleece data backing the document. */ + FLEECE_PUBLIC FLSlice FLDoc_GetData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ + FLEECE_PUBLIC FLSliceResult FLDoc_GetAllocedData(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the root value in the FLDoc, usually an FLDict. */ + FLEECE_PUBLIC FLValue FLDoc_GetRoot(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ + FLEECE_PUBLIC FLSharedKeys FLDoc_GetSharedKeys(FLDoc FL_NULLABLE) FLAPI FLPURE; + + /** Looks up the Doc containing the Value, or NULL if there is none. + @note Caller must release the FLDoc reference!! */ + NODISCARD FLEECE_PUBLIC FLDoc FL_NULLABLE FLValue_FindDoc(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Associates an arbitrary pointer value with a document, and thus its contained values. + Allows client code to associate its own pointer with this FLDoc and its Values, + which can later be retrieved with \ref FLDoc_GetAssociated. + For example, this could be a pointer to an `app::Document` object, of which this Doc's + root FLDict is its properties. You would store it by calling + `FLDoc_SetAssociated(doc, myDoc, "app::Document");`. + @param doc The FLDoc to store a pointer in. + @param pointer The pointer to store in the FLDoc. + @param type A C string literal identifying the type. This is used to avoid collisions + with unrelated code that might try to store a different type of value. + @return True if the pointer was stored, false if a pointer of a different type is + already stored. + @warning Be sure to clear this before the associated object is freed/invalidated! + @warning This function is not thread-safe. Do not concurrently get & set objects. */ + FLEECE_PUBLIC bool FLDoc_SetAssociated(FLDoc FL_NULLABLE doc, + void * FL_NULLABLE pointer, + const char *type) FLAPI; + + /** Returns the pointer associated with the document. You can use this together with + \ref FLValue_FindDoc to associate your own object with Fleece values, for instance to find + your object that "owns" a value: + `myDoc = (app::Document*)FLDoc_GetAssociated(FLValue_FindDoc(val), "app::Document");`. + @param doc The FLDoc to get a pointer from. + @param type The type of object expected, i.e. the same string literal passed to + \ref FLDoc_SetAssociated. + @return The associated pointer of that type, if any. */ + FLEECE_PUBLIC void* FLDoc_GetAssociated(FLDoc FL_NULLABLE doc, const char *type) FLAPI FLPURE; + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLDOC_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7ce213e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h @@ -0,0 +1,233 @@ +// +// FLEncoder.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLENCODER_H +#define _FLENCODER_H + +#include +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLEncoder Fleece Encoders + @{ + An FLEncoder generates encoded Fleece or JSON data. It's sort of a structured output stream, + with nesting. There are functions for writing every type of scalar value, and for beginning + and ending collections. To write a collection you begin it, write its values, then end it. + (Of course a value in a collection can itself be another collection.) When writing a + dictionary, you have to call writeKey before writing each value. + */ + + + /** \name Setup and configuration + @{ */ + + /** Output formats a FLEncoder can generate. */ + typedef enum { + kFLEncodeFleece, ///< Fleece encoding + kFLEncodeJSON, ///< JSON encoding + kFLEncodeJSON5 ///< [JSON5](http://json5.org), an extension of JSON with a more readable syntax + } FLEncoderFormat; + + + /** Creates a new encoder, for generating Fleece data. Call FLEncoder_Free when done. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_New(void) FLAPI; + + /** Creates a new encoder, allowing some options to be customized. + @param format The output format to generate (Fleece, JSON, or JSON5.) + @param reserveSize The number of bytes to preallocate for the output. (Default is 256) + @param uniqueStrings (Fleece only) If true, string values that appear multiple times will be written + as a single shared value. This saves space but makes encoding slightly slower. + You should only turn this off if you know you're going to be writing large numbers + of non-repeated strings. (Default is true) */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, + size_t reserveSize, + bool uniqueStrings) FLAPI; + + /** Creates a new Fleece encoder that writes to a file, not to memory. */ + NODISCARD FLEECE_PUBLIC FLEncoder FLEncoder_NewWritingToFile(FILE*, bool uniqueStrings) FLAPI; + + /** Frees the space used by an encoder. */ + FLEECE_PUBLIC void FLEncoder_Free(FLEncoder FL_NULLABLE) FLAPI; + + /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ + FLEECE_PUBLIC void FLEncoder_SetSharedKeys(FLEncoder, FLSharedKeys FL_NULLABLE) FLAPI; + + /** Associates an arbitrary user-defined value with the encoder. */ + FLEECE_PUBLIC void FLEncoder_SetExtraInfo(FLEncoder, void* FL_NULLABLE info) FLAPI; + + /** Returns the user-defined value associated with the encoder; NULL by default. */ + FLEECE_PUBLIC void* FLEncoder_GetExtraInfo(FLEncoder) FLAPI; + + + /** Resets the state of an encoder without freeing it. It can then be reused to encode + another value. */ + FLEECE_PUBLIC void FLEncoder_Reset(FLEncoder) FLAPI; + + /** Returns the number of bytes encoded so far. */ + FLEECE_PUBLIC size_t FLEncoder_BytesWritten(FLEncoder) FLAPI; + + /** @} */ + + + /** \name Writing to the encoder + @{ + @note The functions that write to the encoder do not return error codes, just a 'false' + result on error. The actual error is attached to the encoder and can be accessed by calling + FLEncoder_GetError or FLEncoder_End. + + After an error occurs, the encoder will ignore all subsequent writes. */ + + /** Writes a `null` value to an encoder. (This is an explicitly-stored null, like the JSON + `null`, not the "undefined" value represented by a NULL FLValue pointer.) */ + FLEECE_PUBLIC bool FLEncoder_WriteNull(FLEncoder) FLAPI; + + /** Writes an `undefined` value to an encoder. (Its value when read will not be a `NULL` + pointer, but it can be recognized by `FLValue_GetType` returning `kFLUndefined`.) + @note The only real use for writing undefined values is to represent "holes" in an array. + An undefined dictionary value should be written simply by skipping the key and value. */ + FLEECE_PUBLIC bool FLEncoder_WriteUndefined(FLEncoder) FLAPI; + + /** Writes a boolean value (true or false) to an encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteBool(FLEncoder, bool) FLAPI; + + /** Writes an integer to an encoder. The parameter is typed as `int64_t` but you can pass any + integral type (signed or unsigned) except for huge `uint64_t`s. + The number will be written in a compact form that uses only as many bytes as necessary. */ + FLEECE_PUBLIC bool FLEncoder_WriteInt(FLEncoder, int64_t) FLAPI; + + /** Writes an unsigned integer to an encoder. + @note This function is only really necessary for huge + 64-bit integers greater than or equal to 2^63, which can't be represented as int64_t. */ + FLEECE_PUBLIC bool FLEncoder_WriteUInt(FLEncoder, uint64_t) FLAPI; + + /** Writes a 32-bit floating point number to an encoder. + @note As an implementation detail, if the number has no fractional part and can be + represented exactly as an integer, it'll be encoded as an integer to save space. This is + transparent to the reader, since if it requests the value as a float it'll be returned + as floating-point. */ + FLEECE_PUBLIC bool FLEncoder_WriteFloat(FLEncoder, float) FLAPI; + + /** Writes a 64-bit floating point number to an encoder. + @note As an implementation detail, the number may be encoded as a 32-bit float or even + as an integer, if this can be done without losing precision. For example, 123.0 will be + written as an integer, and 123.75 as a float.) */ + FLEECE_PUBLIC bool FLEncoder_WriteDouble(FLEncoder, double) FLAPI; + + /** Writes a string to an encoder. The string must be UTF-8-encoded and must not contain any + zero bytes. + @warning Do _not_ use this to write a dictionary key; use FLEncoder_WriteKey instead. */ + FLEECE_PUBLIC bool FLEncoder_WriteString(FLEncoder, FLString) FLAPI; + + /** Writes a timestamp to an encoder, as an ISO-8601 date string. + @note Since neither Fleece nor JSON have a 'Date' type, the encoded string has no + metadata that distinguishes it as a date. It's just a string.) + @param encoder The encoder to write to. + @param ts The timestamp (milliseconds since Unix epoch 1-1-1970). + @param asUTC If true, date is written in UTC (GMT); if false, with the local timezone. + @return True on success, false on error. */ + FLEECE_PUBLIC bool FLEncoder_WriteDateString(FLEncoder encoder, FLTimestamp ts, bool asUTC) FLAPI; + + /** Writes a binary data value (a blob) to an encoder. This can contain absolutely anything + including null bytes. + If the encoder is generating JSON, the blob will be written as a base64-encoded string. */ + FLEECE_PUBLIC bool FLEncoder_WriteData(FLEncoder, FLSlice) FLAPI; + + /** Writes a Fleece Value to an Encoder. */ + FLEECE_PUBLIC bool FLEncoder_WriteValue(FLEncoder, FLValue) FLAPI; + + + /** Begins writing an array value to an encoder. This pushes a new state where each + subsequent value written becomes an array item, until FLEncoder_EndArray is called. + @param reserveCount Number of array elements to reserve space for. If you know the size + of the array, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginArray(FLEncoder, size_t reserveCount) FLAPI; + + /** Ends writing an array value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndArray(FLEncoder) FLAPI; + + + /** Begins writing a dictionary value to an encoder. This pushes a new state where each + subsequent key and value written are added to the dictionary, until FLEncoder_EndDict is + called. + Before adding each value, you must call FLEncoder_WriteKey (_not_ FLEncoder_WriteString!), + to write the dictionary key. + @param reserveCount Number of dictionary items to reserve space for. If you know the size + of the dictionary, providing it here speeds up encoding slightly. If you don't know, + just use zero. */ + FLEECE_PUBLIC bool FLEncoder_BeginDict(FLEncoder, size_t reserveCount) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. */ + FLEECE_PUBLIC bool FLEncoder_WriteKey(FLEncoder, FLString) FLAPI; + + /** Specifies the key for the next value to be written to the current dictionary. + The key is given as a Value, which must be a string or integer. */ + FLEECE_PUBLIC bool FLEncoder_WriteKeyValue(FLEncoder, FLValue) FLAPI; + + /** Ends writing a dictionary value; pops back the previous encoding state. */ + FLEECE_PUBLIC bool FLEncoder_EndDict(FLEncoder) FLAPI; + + + /** Writes raw data directly to the encoded output. + (This is not the same as \ref FLEncoder_WriteData, which safely encodes a blob.) + @warning **Do not call this** unless you really know what you're doing ... + it's quite unsafe, and only used for certain advanced purposes. */ + FLEECE_PUBLIC bool FLEncoder_WriteRaw(FLEncoder, FLSlice) FLAPI; + + /** @} */ + + + /** \name Finishing up + @{ */ + + /** Ends encoding; if there has been no error, it returns the encoded Fleece data packaged in + an FLDoc. (This function does not support JSON encoding.) + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLDoc FL_NULLABLE FLEncoder_FinishDoc(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** Ends encoding; if there has been no error, it returns the encoded data, else null. + This does not free the FLEncoder; call FLEncoder_Free (or FLEncoder_Reset) next. */ + NODISCARD + FLEECE_PUBLIC FLSliceResult FLEncoder_Finish(FLEncoder, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Error handling + @{ */ + + /** Returns the error code of an encoder, or NoError (0) if there's no error. */ + FLEECE_PUBLIC FLError FLEncoder_GetError(FLEncoder) FLAPI; + + /** Returns the error message of an encoder, or NULL if there's no error. */ + FLEECE_PUBLIC const char* FL_NULLABLE FLEncoder_GetErrorMessage(FLEncoder) FLAPI; + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLENCODER_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..9dd697f --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,317 @@ +// +// FLExpert.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLOBSCURE_H +#define _FLOBSCURE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // VOLATILE API: FLExpert methods are meant for internal use, and will be removed + // in a future release + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Obscure Rarely-needed or advanced functions + @{ */ + + /** For use with \ref FLDoc_FromResultData. This option prevents the function from parsing the + data at all; you are responsible for locating the FLValues in it. + This is for the case where you have trusted data in a custom format that contains Fleece- + encoded data within it. You still need an FLDoc to access the data safely (especially to + retain FLValues), but it can't be parsed as-is. */ + #define kFLTrustedDontParse FLTrust(-1) + + /** \name Delta Compression + @{ + These functions implement a fairly-efficient "delta" encoding that encapsulates the changes + needed to transform one Fleece value into another. The delta is expressed in JSON form. + + A delta can be stored or transmitted + as an efficient way to produce the second value, when the first is already present. Deltas + are frequently used in version-control systems and efficient network protocols. + */ + + /** Returns JSON that encodes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @return JSON data representing the changes from `old` to `nuu`, or NULL on + (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLCreateJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu) FLAPI; + + /** Writes JSON that describes the changes to turn the value `old` into `nuu`. + (The format is documented in Fleece.md, but you should treat it as a black box.) + @param old A value that's typically the old/original state of some data. + @param nuu A value that's typically the new/changed state of the `old` data. + @param jsonEncoder An encoder to write the JSON to. Must have been created using + `FLEncoder_NewWithOptions`, with JSON or JSON5 format. + @return True on success, false on (extremely unlikely) failure. */ + NODISCARD FLEECE_PUBLIC bool FLEncodeJSONDelta(FLValue FL_NULLABLE old, + FLValue FL_NULLABLE nuu, + FLEncoder jsonEncoder) FLAPI; + + + /** Applies the JSON data created by `CreateJSONDelta` to the value `old`, which must be equal + to the `old` value originally passed to `FLCreateJSONDelta`, and returns a Fleece document + equal to the original `nuu` value. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param outError On failure, error information will be stored where this points, if non-null. + @return The corresponding `nuu` value, encoded as Fleece, or null if an error occurred. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLApplyJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLError* FL_NULLABLE outError) FLAPI; + + /** Applies the (parsed) JSON data created by `CreateJSONDelta` to the value `old`, which must be + equal to the `old` value originally passed to `FLCreateJSONDelta`, and writes the corresponding + `nuu` value to the encoder. + @param old A value that's typically the old/original state of some data. This must be + equal to the `old` value used when creating the `jsonDelta`. + @param jsonDelta A JSON-encoded delta created by `FLCreateJSONDelta` or `FLEncodeJSONDelta`. + @param encoder A Fleece encoder to write the decoded `nuu` value to. (JSON encoding is not + supported.) + @return True on success, false on error; call `FLEncoder_GetError` for details. */ + FLEECE_PUBLIC bool FLEncodeApplyingJSONDelta(FLValue FL_NULLABLE old, + FLSlice jsonDelta, + FLEncoder encoder) FLAPI; + /** @} */ + + + /** \name Shared Keys + @{ + FLSharedKeys represents a mapping from short strings to small integers in the range + [0...2047]. It's used by FLDict to abbreviate dictionary keys. A shared key can be stored in + a fixed two bytes and is faster to compare against. However, the same mapping has to be used + when encoding and when accessing the Dict. + + To use shared keys: + * Call \ref FLSharedKeys_New to create a new empty mapping. + * After creating an FLEncoder, call \ref FLEncoder_SetSharedKeys so dictionary keys will + be added to the mapping and written in integer form. + * When loading Fleece data, use \ref FLDoc_FromResultData and pass the FLSharedKeys as + a parameter. + * Save the mapping somewhere by calling \ref FLSharedKeys_GetStateData or + \ref FLSharedKeys_WriteState. + * You can later reconstitute the mapping by calling \ref FLSharedKeys_LoadStateData + or \ref FLSharedKeys_LoadState on a new empty instance. + */ + + /** Creates a new empty FLSharedKeys object, which must eventually be released. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + NODISCARD FLEECE_PUBLIC FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, + void* FL_NULLABLE context) FLAPI; + + /** Returns a data blob containing the current state (all the keys and their integers.) */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. + Returns true if new keys were added, false if not. */ + FLEECE_PUBLIC bool FLSharedKeys_LoadStateData(FLSharedKeys, FLSlice) FLAPI; + + /** Writes the current state to a Fleece encoder as a single value, + which can later be decoded and passed to \ref FLSharedKeys_LoadState. */ + FLEECE_PUBLIC void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; + + /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by + \ref FLSharedKeys_WriteState. */ + NODISCARD FLEECE_PUBLIC bool FLSharedKeys_LoadState(FLSharedKeys, FLValue) FLAPI; + + /** Maps a key string to a number in the range [0...2047], or returns -1 if it isn't mapped. + If the key doesn't already have a mapping, and the `add` flag is true, + a new mapping is assigned and returned. + However, the `add` flag has no effect if the key is unmappable (is longer than 16 bytes + or contains non-identifier characters), or if all available integers have been assigned. */ + FLEECE_PUBLIC int FLSharedKeys_Encode(FLSharedKeys, FLString, bool add) FLAPI; + + /** Returns the key string that maps to the given integer `key`, else NULL. */ + FLEECE_PUBLIC FLString FLSharedKeys_Decode(FLSharedKeys, int key) FLAPI; + + /** Returns the number of keys in the mapping. This number increases whenever the mapping + is changed, and never decreases. */ + FLEECE_PUBLIC unsigned FLSharedKeys_Count(FLSharedKeys) FLAPI; + + /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ + FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI; + + /** Disable caching of the SharedKeys.. */ + FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI; + + /** Increments the reference count of an FLSharedKeys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI; + + /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ + FLEECE_PUBLIC void FLSharedKeys_Release(FLSharedKeys FL_NULLABLE) FLAPI; + + + typedef struct _FLSharedKeyScope* FLSharedKeyScope; + + /** Registers a range of memory containing Fleece data that uses the given shared keys. + This allows Dict accessors to look up the values of shared keys. */ + NODISCARD FLEECE_PUBLIC FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; + + /** Unregisters a scope created by \ref FLSharedKeyScope_WithRange. */ + FLEECE_PUBLIC void FLSharedKeyScope_Free(FLSharedKeyScope FL_NULLABLE) FLAPI; + + /** @} */ + + + /** \name Parsing Fleece Data Directly + @{ */ + + /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. + You should generally use an \ref FLDoc instead; it's safer. Here's why: + + On the plus side, \ref FLValue_FromData is _extremely_ fast: it allocates no memory, + only scans enough of the data to ensure it's valid (and if `trust` is set to `kFLTrusted`, + it doesn't even do that.) + + But it's potentially _very_ dangerous: the FLValue, and all values found through it, are + only valid as long as the input `data` remains intact and unchanged. If you violate + that, the values will be pointing to garbage and Bad Things will happen when you access + them...*/ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_FromData(FLSlice data, FLTrust trust) FLAPI FLPURE; + + /** @} */ + + + /** \name JSON + @{ */ + + /** Converts valid JSON5 to JSON. Among other things, it converts single + quotes to double, adds missing quotes around dictionary keys, removes trailing commas, + and removes comments. + @note If given invalid JSON5, it will _usually_ return an error, but may just ouput + comparably invalid JSON, in which case the caller's subsequent JSON parsing will + detect the error. The types of errors it overlooks tend to be subtleties of string + or number encoding. + @param json5 The JSON5 to parse + @param outErrorMessage On failure, the error message will be stored here (if not NULL.) + As this is a \ref FLStringResult, you will be responsible for freeing it. + @param outErrorPos On a parse error, the byte offset in the input where the error occurred + will be stored here (if it's not NULL.) + @param outError On failure, the error code will be stored here (if it's not NULL.) + @return The converted JSON. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLJSON5_ToJSON(FLString json5, + FLStringResult* FL_NULLABLE outErrorMessage, + size_t* FL_NULLABLE outErrorPos, + FLError* FL_NULLABLE outError) FLAPI; + + /** Directly converts JSON data to Fleece-encoded data. Not commonly needed. + Prefer \ref FLDoc_FromJSON instead. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLData_ConvertJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** @} */ + + + /** \name Encoder + @{ */ + + /** Tells the encoder to logically append to the given Fleece document, rather than making a + standalone document. Any calls to FLEncoder_WriteValue() where the value points inside the + base data will write a pointer back to the original value. + The resulting data returned by FLEncoder_FinishDoc() will *NOT* be standalone; it can only + be used by first appending it to the base data. + @param e The FLEncoder affected. + @param base The base document to create an amendment of. + @param reuseStrings If true, then writing a string that already exists in the base will + just create a pointer back to the original. But the encoder has to scan the + base for strings first. + @param externPointers If true, pointers into the base will be marked with the `extern` + flag. This allows them to be resolved using the `FLResolver_Begin` function, + so that when the delta is used the base document can be anywhere in memory, + not just immediately preceding the delta document. */ + FLEECE_PUBLIC void FLEncoder_Amend(FLEncoder e, FLSlice base, + bool reuseStrings, bool externPointers) FLAPI; + + /** Returns the `base` value passed to FLEncoder_Amend. */ + FLEECE_PUBLIC FLSlice FLEncoder_GetBase(FLEncoder) FLAPI; + + /** Tells the encoder not to write the two-byte Fleece trailer at the end of the data. + This is only useful for certain special purposes. */ + FLEECE_PUBLIC void FLEncoder_SuppressTrailer(FLEncoder) FLAPI; + + /** Returns the byte offset in the encoded data where the next value will be written. + (Due to internal buffering, this is not the same as FLEncoder_BytesWritten.) */ + FLEECE_PUBLIC size_t FLEncoder_GetNextWritePos(FLEncoder) FLAPI; + + #define kFLNoWrittenValue INTPTR_MIN + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning kFLNoWrittenValue) if nothing has been written, or if the value is inline + and can't be referenced this way -- that only happens with small scalars or empty + collections. */ + FLEECE_PUBLIC intptr_t FLEncoder_LastValueWritten(FLEncoder) FLAPI; + + /** Writes another reference (a "pointer") to an already-written value, given a reference previously + returned from \ref FLEncoder_LastValueWritten. The effect is exactly the same as if you wrote the + entire value again, except that the size of the encoded data only grows by 4 bytes. + Returns false if the reference couldn't be written. */ + FLEECE_PUBLIC bool FLEncoder_WriteValueAgain(FLEncoder, intptr_t preWrittenValue) FLAPI; + + /** Returns the data written so far as a standalone Fleece document, whose root is the last + value written. You can continue writing, and the final output returned by \ref FLEncoder_Finish will + consist of everything after this point. That second part can be used in the future by loading it + as an `FLDoc` with the first part as its `extern` reference. */ + NODISCARD FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + NODISCARD FLEECE_PUBLIC size_t FLEncoder_FinishItem(FLEncoder) FLAPI; + + /** In a JSON encoder, adds a newline ('\n') and prepares to start encoding another + top-level object. The encoder MUST be not be within an array or dict. + Has no effect in a Fleece encoder. */ + FLEECE_PUBLIC void FLJSONEncoder_NextDocument(FLEncoder) FLAPI; + + + /** @} */ + + + /** \name Debugging Functions + @{ */ + + /** Debugging function that returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDump(FLValue FL_NULLABLE) FLAPI; + + /** Debugging function that parses Fleece data and returns a C string of JSON. + Does not free the string's memory! */ + FLEECE_PUBLIC const char* FL_NULLABLE FLDumpData(FLSlice data) FLAPI; + + /** Produces a human-readable dump of Fleece-encoded data. + This is only useful if you already know, or want to learn, the encoding format. */ + FLEECE_PUBLIC FLStringResult FLData_Dump(FLSlice data) FLAPI; + + /** @} */ + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLOBSCURE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..677d3e4 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h @@ -0,0 +1,86 @@ +// +// FLJSON.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLJSON_H +#define _FLJSON_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + /** \defgroup json JSON Interoperability */ + + /** \name Converting to JSON + @{ + These are convenience functions that directly return a JSON representation of a value. + For more control over the encoding, use an \ref FLEncoder with format \ref kFLEncodeJSON. */ + + /** Encodes a Fleece value as JSON (or a JSON fragment.) + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE) FLAPI; + + /** Encodes a Fleece value as JSON5, a more lenient variant of JSON that allows dictionary + keys to be unquoted if they're alphanumeric. This tends to be more readable. + @note Any Data values will be encoded as base64-encoded strings. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSON5(FLValue FL_NULLABLE) FLAPI; + + /** Most general Fleece to JSON converter. + @param v The Fleece value to encode + @param json5 If true, outputs JSON5, like \ref FLValue_ToJSON5 + @param canonicalForm If true, outputs the JSON in a consistent "canonical" form. All + equivalent values should produce byte-for-byte identical canonical JSON. + This is useful for creating digital signatures, for example. */ + FLEECE_PUBLIC FLStringResult FLValue_ToJSONX(FLValue FL_NULLABLE v, + bool json5, + bool canonicalForm) FLAPI; + + /** @} */ + + + /** \name Parsing JSON to Fleece Values + @{ */ + + /** Creates an FLDoc from JSON-encoded data. The data is first encoded into Fleece, and the + Fleece data is kept by the doc; the input JSON data is no longer needed after this + function returns. */ + NODISCARD FLEECE_PUBLIC FLDoc FLDoc_FromJSON(FLSlice json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Array from JSON. It is an error if the JSON is not an array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Creates a new mutable Dict from json. It is an error if the JSON is not a dictionary/object. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_NewFromJSON(FLString json, FLError* FL_NULLABLE outError) FLAPI; + + /** Parses JSON data and writes the value(s) to the encoder as their Fleece equivalents. + (This acts as a single write, like WriteInt; it's just that the value written is likely to + be an entire dictionary or array.) */ + FLEECE_PUBLIC bool FLEncoder_ConvertJSON(FLEncoder, FLSlice json) FLAPI; + + /** @} */ + + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLJSON_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..9ed12e3 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,84 @@ +// +// FLKeyPath.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLKEYPATH_H +#define _FLKEYPATH_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLKeyPath Fleece Paths + @{ + An FLKeyPath Describes a location in a Fleece object tree, as a path from the root that follows + dictionary properties and array elements. + It's similar to a JSONPointer or an Objective-C KeyPath, but simpler (so far.) + The path is compiled into an efficient form that can be traversed quickly. + + It looks like `foo.bar[2][-3].baz` -- that is, properties prefixed with a `.`, and array + indexes in brackets. (Negative indexes count from the end of the array.) + + A leading JSONPath-like `$.` is allowed but ignored. + + A '\' can be used to escape a special character ('.', '[' or '$'). + */ + +#ifndef FL_IMPL + typedef struct _FLKeyPath* FLKeyPath; ///< A reference to a key path. +#endif + + /** Creates a new FLKeyPath object by compiling a path specifier string. */ + NODISCARD FLEECE_PUBLIC FLKeyPath FL_NULLABLE FLKeyPath_New(FLSlice specifier, + FLError* FL_NULLABLE outError) FLAPI; + + /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ + FLEECE_PUBLIC void FLKeyPath_Free(FLKeyPath FL_NULLABLE) FLAPI; + + /** Evaluates a compiled key-path for a given Fleece root object. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_Eval(FLKeyPath, + FLValue root) FLAPI; + + /** Evaluates a key-path from a specifier string, for a given Fleece root object. + If you only need to evaluate the path once, this is a bit faster than creating an + FLKeyPath object, evaluating, then freeing it. */ + NODISCARD FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + NODISCARD FLEECE_PUBLIC FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; + + /** Equality test. */ + FLEECE_PUBLIC bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; + + /** Returns an element of a path, either a key or an array index. */ + FLEECE_PUBLIC bool FLKeyPath_GetElement(FLKeyPath, + size_t i, + FLSlice *outDictKey, + int32_t *outArrayIndex) FLAPI; + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLKEYPATH_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..1072e64 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h @@ -0,0 +1,457 @@ +// +// FLMutable.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLMUTABLE_H +#define _FLMUTABLE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup Mutable Mutable Values + @{ */ + + + /** Option flags for making mutable copies of values. */ + typedef enum { + kFLDefaultCopy = 0, ///< Shallow copy. References immutables instead of copying. + kFLDeepCopy = 1, ///< Deep copy of mutable values + kFLCopyImmutables = 2, ///< Makes mutable copies of immutables instead of just refs. + kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), ///< Both deep-copy and copy-immutables. + } FLCopyFlags; + + + //====== MUTABLE ARRAY + + + /** \name Mutable Arrays + @{ */ + + /** Creates a new mutable Array that's a copy of the source Array. + Its initial ref-count is 1, so a call to \ref FLMutableArray_Release will free it. + + Copying an immutable Array is very cheap (only one small allocation) unless the flag + \ref kFLCopyImmutables is set. + + Copying a mutable Array is cheap if it's a shallow copy; but if \ref kFLDeepCopy is set, + nested mutable Arrays and Dicts are also copied, recursively; if \ref kFLCopyImmutables is + also set, immutable values are also copied, recursively. + + If the source Array is NULL, then NULL is returned. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLArray_MutableCopy(FLArray FL_NULLABLE, + FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Array. + Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_New(void) FLAPI; + + /** Increments the ref-count of a mutable Array. */ + static inline FLMutableArray FL_NULLABLE FLMutableArray_Retain(FLMutableArray FL_NULLABLE d) { + return (FLMutableArray)FLValue_Retain((FLValue)d); + } + /** Decrements the refcount of (and possibly frees) a mutable Array. */ + static inline void FLMutableArray_Release(FLMutableArray FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLMutableArray_GetSource(FLMutableArray FL_NULLABLE) FLAPI; + + /** Returns true if the Array has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableArray_IsChanged(FLMutableArray FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Array's "changed" flag. */ + FLEECE_PUBLIC void FLMutableArray_SetChanged(FLMutableArray FL_NULLABLE, + bool changed) FLAPI; + + /** Inserts a contiguous range of JSON `null` values into the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first value to be inserted. + @param count The number of items to insert. */ + FLEECE_PUBLIC void FLMutableArray_Insert(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Removes contiguous items from the array. + @param array The array to operate on. + @param firstIndex The zero-based index of the first item to remove. + @param count The number of items to remove. */ + FLEECE_PUBLIC void FLMutableArray_Remove(FLMutableArray FL_NULLABLE array, + uint32_t firstIndex, + uint32_t count) FLAPI; + + /** Changes the size of an array. + If the new size is larger, the array is padded with JSON `null` values. + If it's smaller, values are removed from the end. */ + FLEECE_PUBLIC void FLMutableArray_Resize(FLMutableArray FL_NULLABLE array, + uint32_t size) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableArray_GetMutableArray(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + NODISCARD FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableArray_GetMutableDict(FLMutableArray FL_NULLABLE, + uint32_t index) FLAPI; + + + /// Stores a JSON null value into an array. + static inline void FLMutableArray_SetNull(FLMutableArray, uint32_t index); + /// Stores a boolean value into an array. + static inline void FLMutableArray_SetBool(FLMutableArray, uint32_t index, bool); + /// Stores an integer into an array. + static inline void FLMutableArray_SetInt(FLMutableArray, uint32_t index, int64_t); + /// Stores an unsigned integer into an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_SetUInt(FLMutableArray, uint32_t index, uint64_t); + /// Stores a 32-bit floating-point number into an array. + static inline void FLMutableArray_SetFloat(FLMutableArray, uint32_t index, float); + /// Stores a 64-bit floating point number into an array. + static inline void FLMutableArray_SetDouble(FLMutableArray, uint32_t index, double); + /// Stores a UTF-8-encoded string into an array. + static inline void FLMutableArray_SetString(FLMutableArray, uint32_t index, FLString); + /// Stores a binary data blob into an array. + static inline void FLMutableArray_SetData(FLMutableArray, uint32_t index, FLSlice); + /// Stores a Fleece value into an array. + static inline void FLMutableArray_SetValue(FLMutableArray, uint32_t index, FLValue); + /// Stores a Fleece array into an array + static inline void FLMutableArray_SetArray(FLMutableArray, uint32_t index, FLArray); + /// Stores a Fleece dictionary into an array + static inline void FLMutableArray_SetDict(FLMutableArray, uint32_t index, FLDict); + + /// Appends a JSON null value to an array. + static inline void FLMutableArray_AppendNull(FLMutableArray); + /// Appends a boolean value to an array. + static inline void FLMutableArray_AppendBool(FLMutableArray, bool); + /// Appends an integer to an array. + static inline void FLMutableArray_AppendInt(FLMutableArray, int64_t); + /// Appends an unsigned integer to an array. + /// \note: The only time this needs to be called, instead of \ref FLMutableArray_AppendInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableArray_AppendUInt(FLMutableArray, uint64_t); + /// Appends a 32-bit floating-point number to an array. + static inline void FLMutableArray_AppendFloat(FLMutableArray, float); + /// Appends a 64-bit floating point number to an array. + static inline void FLMutableArray_AppendDouble(FLMutableArray, double); + /// Appends a UTF-8-encoded string to an array. + static inline void FLMutableArray_AppendString(FLMutableArray, FLString); + /// Appends a binary data blob to an array. + static inline void FLMutableArray_AppendData(FLMutableArray, FLSlice); + /// Appends a Fleece value to an array. + static inline void FLMutableArray_AppendValue(FLMutableArray, FLValue); + /// Appends a Fleece array to an array + static inline void FLMutableArray_AppendArray(FLMutableArray, FLArray); + /// Appends a Fleece dictionary to an array + static inline void FLMutableArray_AppendDict(FLMutableArray, FLDict); + + /** @} */ + + + //====== MUTABLE DICT + + + /** \name Mutable dictionaries + @{ */ + + /** Creates a new mutable Dict that's a copy of the source Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. + + Copying an immutable Dict is very cheap (only one small allocation.) The `deepCopy` flag + is ignored. + + Copying a mutable Dict is cheap if it's a shallow copy, but if `deepCopy` is true, + nested mutable Dicts and Arrays are also copied, recursively. + + If the source dict is NULL, then NULL is returned. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLDict_MutableCopy(FLDict FL_NULLABLE source, FLCopyFlags) FLAPI; + + /** Creates a new empty mutable Dict. + Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_New(void) FLAPI; + + /** Increments the ref-count of a mutable Dict. */ + static inline FLMutableDict FL_NULLABLE FLMutableDict_Retain(FLMutableDict FL_NULLABLE d) { + return (FLMutableDict)FLValue_Retain((FLValue)d); + } + + /** Decrements the refcount of (and possibly frees) a mutable Dict. */ + static inline void FLMutableDict_Release(FLMutableDict FL_NULLABLE d) { + FLValue_Release((FLValue)d); + } + + /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLMutableDict_GetSource(FLMutableDict FL_NULLABLE) FLAPI; + + /** Returns true if the Dict has been changed from the source it was copied from. */ + FLEECE_PUBLIC bool FLMutableDict_IsChanged(FLMutableDict FL_NULLABLE) FLAPI; + + /** Sets or clears the mutable Dict's "changed" flag. */ + FLEECE_PUBLIC void FLMutableDict_SetChanged(FLMutableDict FL_NULLABLE, bool) FLAPI; + + /** Removes the value for a key. */ + FLEECE_PUBLIC void FLMutableDict_Remove(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Removes all keys and values. */ + FLEECE_PUBLIC void FLMutableDict_RemoveAll(FLMutableDict FL_NULLABLE) FLAPI; + + /** Convenience function for getting an array-valued property in mutable form. + - If the value for the key is not an array, returns NULL. + - If the value is a mutable array, returns it. + - If the value is an immutable array, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableArray FL_NULLABLE FLMutableDict_GetMutableArray(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + /** Convenience function for getting a dict-valued property in mutable form. + - If the value for the key is not a dict, returns NULL. + - If the value is a mutable dict, returns it. + - If the value is an immutable dict, this function makes a mutable copy, assigns the + copy as the property value, and returns the copy. */ + FLEECE_PUBLIC FLMutableDict FL_NULLABLE FLMutableDict_GetMutableDict(FLMutableDict FL_NULLABLE, FLString key) FLAPI; + + + /// Stores a JSON null value into a mutable dictionary. + static inline void FLMutableDict_SetNull(FLMutableDict, FLString key); + /// Stores a boolean value into a mutable dictionary. + static inline void FLMutableDict_SetBool(FLMutableDict, FLString key, bool); + /// Stores an integer into a mutable dictionary. + static inline void FLMutableDict_SetInt(FLMutableDict, FLString key, int64_t); + /// Stores an unsigned integer into a mutable dictionary. + /// \note: The only time this needs to be called, instead of \ref FLMutableDict_SetInt, + /// is if the value is greater than or equal to 2^63 and won't fit in an `int64_t`. + static inline void FLMutableDict_SetUInt(FLMutableDict, FLString key, uint64_t); + /// Stores a 32-bit floating-point number into a mutable dictionary. + static inline void FLMutableDict_SetFloat(FLMutableDict, FLString key, float); + /// Stores a 64-bit floating point number into a mutable dictionary. + static inline void FLMutableDict_SetDouble(FLMutableDict, FLString key, double); + /// Stores a UTF-8-encoded string into a mutable dictionary. + static inline void FLMutableDict_SetString(FLMutableDict, FLString key, FLString); + /// Stores a binary data blob into a mutable dictionary. + static inline void FLMutableDict_SetData(FLMutableDict, FLString key, FLSlice); + /// Stores a Fleece value into a mutable dictionary. + static inline void FLMutableDict_SetValue(FLMutableDict, FLString key, FLValue); + /// Stores a Fleece array into a mutable dictionary. + static inline void FLMutableDict_SetArray(FLMutableDict, FLString key, FLArray); + /// Stores a Fleece dictionary into a mutable dictionary. + static inline void FLMutableDict_SetDict(FLMutableDict, FLString key, FLDict); + + /** @} */ + + + //====== NEWSTRING, NEWDATA + + + /** \name Creating string and data values + @{ */ + + /** Allocates a string value on the heap. This is rarely needed -- usually you'd just add a string + to a mutable Array or Dict directly using one of their "...SetString" or "...AppendString" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewString(FLString) FLAPI; + + /** Allocates a data/blob value on the heap. This is rarely needed -- usually you'd just add data + to a mutable Array or Dict directly using one of their "...SetData or "...AppendData" + methods. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_NewData(FLSlice) FLAPI; + + /** @} */ + + + //====== VALUE SLOTS + + + /** \defgroup Slots Value Slots + @{ + An \ref FLSlot is a temporary reference to an element of a mutable Array/Dict; + its only purpose is to let you store a value into it, using the `FLSlot_...` functions. + + Since there are three ways to store a value into a collection (array set, array append, + dict set) and nine types of values that can be stored, that makes 27 setter functions. + For efficiency, these are declared as inlines that call one of three functions to acquire + a slot, and one of nine functions to store a value into it. + + It's usually more convenient to use the typed functions like \ref FLMutableArray_SetInt, + but you might drop down to the lower level ones if you're creating an adapter between + Fleece and a different data model, such as Apple's Foundation classes. */ + + /** Returns an \ref FLSlot that refers to the given index of the given array. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Set(FLMutableArray, uint32_t index) FLAPI; + + /** Appends a null value to the array and returns an \ref FLSlot that refers to that position. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the array invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableArray_Append(FLMutableArray) FLAPI; + + /** Returns an \ref FLSlot that refers to the given key/value pair of the given dictionary. + You store a value to it by calling one of the nine `FLSlot_Set...` functions. + \warning You should immediately store a value into the `FLSlot`. Do not keep it around; + any changes to the dictionary invalidate it.*/ + NODISCARD + FLEECE_PUBLIC FLSlot FLMutableDict_Set(FLMutableDict, FLString key) FLAPI; + + + FLEECE_PUBLIC void FLSlot_SetNull(FLSlot) FLAPI; ///< Stores a JSON null into a slot. + FLEECE_PUBLIC void FLSlot_SetBool(FLSlot, bool) FLAPI; ///< Stores a boolean into a slot. + FLEECE_PUBLIC void FLSlot_SetInt(FLSlot, int64_t) FLAPI; ///< Stores an integer into a slot. + FLEECE_PUBLIC void FLSlot_SetUInt(FLSlot, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. + FLEECE_PUBLIC void FLSlot_SetFloat(FLSlot, float) FLAPI; ///< Stores a `float` into a slot. + FLEECE_PUBLIC void FLSlot_SetDouble(FLSlot, double) FLAPI; ///< Stores a `double` into a slot. + FLEECE_PUBLIC void FLSlot_SetString(FLSlot, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. + FLEECE_PUBLIC void FLSlot_SetData(FLSlot, FLSlice) FLAPI; ///< Stores a data blob into a slot. + FLEECE_PUBLIC void FLSlot_SetValue(FLSlot, FLValue) FLAPI; ///< Stores an FLValue into a slot. + + static inline void FLSlot_SetArray(FLSlot slot, FLArray array) { + FLSlot_SetValue(slot, (FLValue)array); + } + + static inline void FLSlot_SetDict(FLSlot slot, FLDict dict) { + FLSlot_SetValue(slot, (FLValue)dict); + } + + + // implementations of the inline methods declared earlier: + + static inline void FLMutableArray_SetNull(FLMutableArray a, uint32_t index) { + FLSlot_SetNull(FLMutableArray_Set(a, index)); + } + static inline void FLMutableArray_SetBool(FLMutableArray a, uint32_t index, bool val) { + FLSlot_SetBool(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetInt(FLMutableArray a, uint32_t index, int64_t val) { + FLSlot_SetInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetUInt(FLMutableArray a, uint32_t index, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetFloat(FLMutableArray a, uint32_t index, float val) { + FLSlot_SetFloat(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetDouble(FLMutableArray a, uint32_t index, double val) { + FLSlot_SetDouble(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetString(FLMutableArray a, uint32_t index, FLString val) { + FLSlot_SetString(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetData(FLMutableArray a, uint32_t index, FLSlice val) { + FLSlot_SetData(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetValue(FLMutableArray a, uint32_t index, FLValue val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), val); + } + static inline void FLMutableArray_SetArray(FLMutableArray a, uint32_t index, FLArray val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + static inline void FLMutableArray_SetDict(FLMutableArray a, uint32_t index, FLDict val) { + FLSlot_SetValue(FLMutableArray_Set(a, index), (FLValue)val); + } + + static inline void FLMutableArray_AppendNull(FLMutableArray a) { + FLSlot_SetNull(FLMutableArray_Append(a)); + } + static inline void FLMutableArray_AppendBool(FLMutableArray a, bool val) { + FLSlot_SetBool(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendInt(FLMutableArray a, int64_t val) { + FLSlot_SetInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendUInt(FLMutableArray a, uint64_t val) { + FLSlot_SetUInt(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendFloat(FLMutableArray a, float val) { + FLSlot_SetFloat(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendDouble(FLMutableArray a, double val) { + FLSlot_SetDouble(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendString(FLMutableArray a, FLString val) { + FLSlot_SetString(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendData(FLMutableArray a, FLSlice val) { + FLSlot_SetData(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendValue(FLMutableArray a, FLValue val) { + FLSlot_SetValue(FLMutableArray_Append(a), val); + } + static inline void FLMutableArray_AppendArray(FLMutableArray a, FLArray val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + static inline void FLMutableArray_AppendDict(FLMutableArray a, FLDict val) { + FLSlot_SetValue(FLMutableArray_Append(a), (FLValue)val); + } + + static inline void FLMutableDict_SetNull(FLMutableDict d, FLString key) { + FLSlot_SetNull(FLMutableDict_Set(d, key)); + } + static inline void FLMutableDict_SetBool(FLMutableDict d, FLString key, bool val) { + FLSlot_SetBool(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetInt(FLMutableDict d, FLString key, int64_t val) { + FLSlot_SetInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetUInt(FLMutableDict d, FLString key, uint64_t val) { + FLSlot_SetUInt(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetFloat(FLMutableDict d, FLString key, float val) { + FLSlot_SetFloat(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetDouble(FLMutableDict d, FLString key, double val) { + FLSlot_SetDouble(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetString(FLMutableDict d, FLString key, FLString val) { + FLSlot_SetString(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetData(FLMutableDict d, FLString key, FLSlice val) { + FLSlot_SetData(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetValue(FLMutableDict d, FLString key, FLValue val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), val); + } + static inline void FLMutableDict_SetArray(FLMutableDict d, FLString key, FLArray val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + static inline void FLMutableDict_SetDict(FLMutableDict d, FLString key, FLDict val) { + FLSlot_SetValue(FLMutableDict_Set(d, key), (FLValue)val); + } + + + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLMUTABLE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h new file mode 100644 index 0000000..9713584 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h @@ -0,0 +1,221 @@ +// +// FLSlice.h +// Fleece +// +// Created by Jens Alfke on 8/13/18. +// Copyright 2018-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLSLICE_H +#define _FLSLICE_H + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus + #include + namespace fleece { struct alloc_slice; } +#endif + + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup FLSlice Slices + @{ */ + + +/** A simple reference to a block of memory. Does not imply ownership. + (This is equivalent to the C++ class `slice`.) */ +typedef struct FLSlice { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator std::string() const {return std::string((char*)buf, size);} +#endif +} FLSlice; + + +/** A heap-allocated block of memory returned from an API call. + The caller takes ownership, and must call \ref FLSliceResult_Release when done with it. + \warning The contents of the block must not be modified, since others may be using it. + \note This is equivalent to the C++ class `alloc_slice`. In C++ the easiest way to deal with + a `FLSliceResult` return value is to construct an `alloc_slice` from it, which will + adopt the reference, and release it in its destructor. For example: + `alloc_slice foo( CopyFoo() );` */ +struct NODISCARD FLSliceResult { + const void* FL_NULLABLE buf; + size_t size; + +#ifdef __cplusplus + explicit operator bool() const noexcept FLPURE {return buf != nullptr;} + explicit operator FLSlice () const {return {buf, size};} + inline explicit operator std::string() const; +#endif +}; +typedef struct FLSliceResult FLSliceResult; + + +/** A heap-allocated, reference-counted slice. This type is really just a hint in an API + that the data can be retained instead of copied, by assigning it to an alloc_slice. + You can just treat it like FLSlice. */ +#ifdef __cplusplus + struct FLHeapSlice : public FLSlice { + constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } + private: + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } + friend struct fleece::alloc_slice; + }; +#else + typedef FLSlice FLHeapSlice; +#endif + + +// Aliases used to indicate that a slice is expected to contain UTF-8 data. +typedef FLSlice FLString; +typedef FLSliceResult FLStringResult; + + +/** A convenient constant denoting a null slice. */ +#ifdef _MSC_VER + static const FLSlice kFLSliceNull = { NULL, 0 }; +#else + #define kFLSliceNull ((FLSlice){NULL, 0}) +#endif + + +/** Exactly like memcmp, but safely handles the case where a or b is NULL and size is 0 (by returning 0), + instead of producing "undefined behavior" as per the C spec. */ +static inline FLPURE int FLMemCmp(const void * FL_NULLABLE a, + const void * FL_NULLABLE b, size_t size) FLAPI +{ + if (_usuallyFalse(size == 0)) + return 0; + return memcmp(a, b, size); +} + +/** Exactly like memcmp, but safely handles the case where dst or src is NULL and size is 0 (as a no-op), + instead of producing "undefined behavior" as per the C spec. */ +static inline void FLMemCpy(void* FL_NULLABLE dst, const void* FL_NULLABLE src, size_t size) FLAPI { + if (_usuallyTrue(size > 0)) + memcpy(dst, src, size); +} + + +/** Returns a slice pointing to the contents of a C string. + It's OK to pass NULL; this returns an empty slice. + \note If the string is a literal, it's more efficient to use \ref FLSTR instead. + \note Performance is O(n) with the length of the string, since it has to call `strlen`. */ +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { + FLSlice foo = { str, str ? strlen(str) : 0 }; + return foo; +} + +/// Macro version of \ref FLStr, for use in initializing compile-time constants. +/// `STR` must be a C string literal. Has zero runtime overhead. +#ifdef __cplusplus + #define FLSTR(STR) (FLSlice {("" STR), sizeof(("" STR))-1}) +#else + #define FLSTR(STR) ((FLSlice){("" STR), sizeof(("" STR))-1}) +#endif + + +/** Equality test of two slices. */ +FLEECE_PUBLIC bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; + +/** Lexicographic comparison of two slices; basically like memcmp(), but taking into account + differences in length. */ +FLEECE_PUBLIC int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; + +/** Computes a 32-bit hash of a slice's data, suitable for use in hash tables. */ +FLEECE_PUBLIC uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; + +/** Copies a slice to a buffer, adding a trailing zero byte to make it a valid C string. + If there is not enough capacity the slice will be truncated, but the trailing zero byte is + always written. + @param s The FLSlice to copy. + @param buffer Where to copy the bytes. At least `capacity` bytes must be available. + @param capacity The maximum number of bytes to copy (including the trailing 0.) + @return True if the entire slice was copied, false if it was truncated. */ +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; + +/** Allocates an FLSliceResult of the given size, without initializing the buffer. */ +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; + +/** Allocates an FLSliceResult, copying the given slice. */ +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; + + +/** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { + FLSlice s = {bytes, size}; + return FLSlice_Copy(s); +} + + +FLEECE_PUBLIC void _FLBuf_Retain(const void* FL_NULLABLE) FLAPI; // internal; do not call +FLEECE_PUBLIC void _FLBuf_Release(const void* FL_NULLABLE) FLAPI; // internal; do not call + +/** Increments the ref-count of a FLSliceResult. */ +static inline FLSliceResult FLSliceResult_Retain(FLSliceResult s) FLAPI { + _FLBuf_Retain(s.buf); + return s; +} + +/** Decrements the ref-count of a FLSliceResult, freeing its memory if it reached zero. */ +static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { + _FLBuf_Release(s.buf); +} + +/** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ +static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { + FLSlice ret; + memcpy(&ret, &sr, sizeof(ret)); + return ret; +} + + +/** Writes zeroes to `size` bytes of memory starting at `dst`. + Unlike a call to `memset`, these writes cannot be optimized away by the compiler. + This is useful for securely removing traces of passwords or encryption keys. */ +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; + + +/** @} */ + +#ifdef __cplusplus +} + + FLPURE static inline bool operator== (FLSlice s1, FLSlice s2) {return FLSlice_Equal(s1, s2);} + FLPURE static inline bool operator!= (FLSlice s1, FLSlice s2) {return !(s1 == s2);} + + FLPURE static inline bool operator== (FLSliceResult sr, FLSlice s) {return (FLSlice)sr == s;} + FLPURE static inline bool operator!= (FLSliceResult sr, FLSlice s) {return !(sr ==s);} + + + FLSliceResult::operator std::string () const { + auto str = std::string((char*)buf, size); + FLSliceResult_Release(*this); + return str; + } +#endif + +FL_ASSUME_NONNULL_END +#endif // _FLSLICE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h new file mode 100644 index 0000000..874172f --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h @@ -0,0 +1,185 @@ +// +// FLValue.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLVALUE_H +#define _FLVALUE_H + +#include + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + // This is the C API! For the C++ API, see Fleece.hh. + + + /** \defgroup FLValue Fleece Values + @{ + The core Fleece data type is FLValue: a reference to a value in Fleece-encoded data. + An FLValue can represent any JSON type (plus binary data). + + - Scalar data types -- numbers, booleans, null, strings, data -- can be accessed + using individual functions of the form `FLValue_As...`; these return the scalar value, + or a default zero/false/null value if the value is not of that type. + - Collections -- arrays and dictionaries -- have their own "subclasses": FLArray and + FLDict. These have the same pointer values as an FLValue but are not type-compatible + in C. To coerce an FLValue to a collection type, call FLValue_AsArray or FLValue_AsDict. + If the value is not of that type, NULL is returned. (FLArray and FLDict are documented + fully in their own sections.) + + @note It's safe to pass a `NULL` pointer to an `FLValue`, `FLArray` or `FLDict` + function parameter, except where specifically noted. + @note Conversion/accessor functions that take `FLValue` won't complain if the value isn't + of the desired subtype; they'll just return some default like 0 or `NULL`. + For example, \ref FLValue_AsInt will return 0 if passed a non-integer value or NULL.*/ + + /** Types of Fleece values. Basically JSON, with the addition of Data (raw blob). */ + typedef enum { + kFLUndefined = -1, /**< Type of a NULL pointer, i.e. no such value, like JSON `undefined`. + Also the type of \ref kFLUndefinedValue, and of a value created by + \ref FLEncoder_WriteUndefined(). */ + kFLNull = 0, ///< Equivalent to a JSON 'null' + kFLBoolean, ///< A `true` or `false` value + kFLNumber, ///< A numeric value, either integer or floating-point + kFLString, ///< A string + kFLData, ///< Binary data (no JSON equivalent) + kFLArray, ///< An array of values + kFLDict ///< A mapping of strings to values (AKA "object" in JSON.) + } FLValueType; + + + /** A constant null value (like a JSON `null`, not a NULL pointer!) */ + FLEECE_PUBLIC extern const FLValue kFLNullValue; + + /** A constant undefined value. This is not a NULL pointer, but its type is \ref kFLUndefined. + It can be stored in an \ref FLMutableArray or \ref FLMutableDict if you really, really + need to store an undefined/empty value, not just a JSON `null`. */ + FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; + + + /** \name Accessors + @{ */ + + /** Returns the data type of an arbitrary value. + If the parameter is a NULL pointer, returns `kFLUndefined`. */ + FLEECE_PUBLIC FLValueType FLValue_GetType(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer. */ + FLEECE_PUBLIC bool FLValue_IsInteger(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents an integer >= 2^63. Such a value can't + be represented in C as an `int64_t`, only a `uint64_t`, so you should access it by calling + `FLValueAsUnsigned`, _not_ FLValueAsInt, which would return an incorrect (negative) + value. */ + FLEECE_PUBLIC bool FLValue_IsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ + FLEECE_PUBLIC bool FLValue_IsDouble(FLValue FL_NULLABLE) FLAPI; + + /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), + null, false, or zero. */ + FLEECE_PUBLIC bool FLValue_AsBool(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an integer. True and false are returned as 1 and 0, and + floating-point numbers are rounded. All other types are returned as 0. + @warning Large 64-bit unsigned integers (2^63 and above) will come out wrong. You can + check for these by calling `FLValueIsUnsigned`. */ + FLEECE_PUBLIC int64_t FLValue_AsInt(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to an unsigned integer. + This is the same as `FLValueAsInt` except that it _can't_ handle negative numbers, but + does correctly return large `uint64_t` values of 2^63 and up. */ + FLEECE_PUBLIC uint64_t FLValue_AsUnsigned(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Large integers (outside approximately +/- 2^23) will lose precision due to the + limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC float FLValue_AsFloat(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a value coerced to a 32-bit floating point number. + True and false are returned as 1.0 and 0.0, and integers are converted to float. All other + types are returned as 0.0. + @warning Very large integers (outside approximately +/- 2^50) will lose precision due to + the limitations of IEEE 32-bit float format. */ + FLEECE_PUBLIC double FLValue_AsDouble(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a string value, or null for all other types. */ + FLEECE_PUBLIC FLString FLValue_AsString(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Converts a value to a timestamp, in milliseconds since Unix epoch, or INT64_MIN on failure. + - A string is parsed as ISO-8601 (standard JSON date format). + - A number is interpreted as a timestamp and returned as-is. */ + FLEECE_PUBLIC FLTimestamp FLValue_AsTimestamp(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns the exact contents of a data value, or null for all other types. */ + FLEECE_PUBLIC FLSlice FLValue_AsData(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ + FLEECE_PUBLIC FLArray FL_NULLABLE FLValue_AsArray(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ + FLEECE_PUBLIC FLDict FL_NULLABLE FLValue_AsDict(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** Returns a string representation of any scalar value. Data values are returned in raw form. + Arrays and dictionaries don't have a representation and will return NULL. */ + FLEECE_PUBLIC FLStringResult FLValue_ToString(FLValue FL_NULLABLE) FLAPI; + + /** Compares two values for equality. This is a deep recursive comparison. */ + FLEECE_PUBLIC bool FLValue_IsEqual(FLValue FL_NULLABLE v1, FLValue FL_NULLABLE v2) FLAPI FLPURE; + + /** Returns true if the value is mutable. */ + FLEECE_PUBLIC bool FLValue_IsMutable(FLValue FL_NULLABLE) FLAPI FLPURE; + + /** @} */ + + + /** \name Reference-Counting + Retaining a value extends its lifespan (and that of any values contained in it) until + at least such time that it's released. + - If the value comes from an \ref FLDoc, the doc's ref-count will be incremented. + - If the value is mutable (heap-based), it has its own ref-count that will be incremented. + @warning Values obtained from \ref FLValue_FromData don't match either of those critera. + Their lifespan is entirely determined by the caller-provided data pointer, so + the retain call can't do anything about it. In this situation Fleece will throw + an exception like "Can't retain immutable Value that's not part of a Doc." + @{ */ + + /** Increments the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLValue_Retain(FLValue FL_NULLABLE) FLAPI; + + /** Decrements the ref-count of a mutable value, or of an immutable value's \ref FLDoc. + If the ref-count reaches zero the corresponding object is freed. + @warning It is illegal to call this on a value obtained from \ref FLValue_FromData. */ + FLEECE_PUBLIC void FLValue_Release(FLValue FL_NULLABLE) FLAPI; + + static inline FLArray FL_NULLABLE FLArray_Retain(FLArray FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLArray_Release(FLArray FL_NULLABLE v) {FLValue_Release((FLValue)v);} + static inline FLDict FL_NULLABLE FLDict_Retain(FLDict FL_NULLABLE v) {FLValue_Retain((FLValue)v); return v;} + static inline void FLDict_Release(FLDict FL_NULLABLE v) {FLValue_Release((FLValue)v);} + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END + +#endif // _FLVALUE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h new file mode 100644 index 0000000..ce14e29 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -0,0 +1,91 @@ +// +// Fleece+CoreFoundation.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#include +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + + /** \defgroup CF Fleece CoreFoundation and Objective-C Helpers + @{ */ + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + NODISCARD FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + + + /** Returns a Value as a corresponding CoreFoundation object. + Caller must CFRelease the result. */ + NODISCARD FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; + + + /** Same as FLDictGet, but takes the key as a CFStringRef. */ + NODISCARD FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; + + +#ifdef __OBJC__ + // Equivalents of the above functions that take & return Objective-C object types: + + /** Writes a Core Foundation (or Objective-C) object to an Encoder. + Supports all the JSON types, as well as CFData. */ + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + + + /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + + + /** Returns a Value as a corresponding (autoreleased) Foundation object. */ + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + + /** Same as FLDictGet, but takes the key as an NSString. */ + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; + + + /** Returns an FLDictIterator's current key as an NSString. */ + FLEECE_PUBLIC NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, + NSMapTable* FL_NULLABLE sharedStrings) FLAPI; + + /** Same as FLEncoder_Finish, but returns result as NSData or error as NSError. */ + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; + + + /** NSError domain string for Fleece errors */ + FLEECE_PUBLIC extern NSString* const FLErrorDomain; + + + @interface NSObject (Fleece) + /** This method is called on objects being encoded by + FLEncoder_WriteNSObject (even recursively) if the encoder doesn't know how to encode + them. You can implement this method in your classes. In it, call the encoder to write + a single object (which may of course be an array or dictionary.) */ + - (void) fl_encodeToFLEncoder: (FLEncoder)enc; + @end +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h new file mode 100644 index 0000000..6476347 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h @@ -0,0 +1,36 @@ +// +// Fleece.h +// +// Copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +// + +#pragma once +#ifndef _FLEECE_H +#define _FLEECE_H + +// This "umbrella header" includes the commonly-used parts of the Fleece C API. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include -- advanced & rarely-used functionality + +#ifdef __OBJC__ + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include +#endif + +#endif // _FLEECE_H diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist new file mode 100644 index 0000000..27fb217 Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap new file mode 100644 index 0000000..42fd88e --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap @@ -0,0 +1,38 @@ +framework module CouchbaseLite { + header "CouchbaseLite.h" + header "CBL_Compat.h" + header "CBL_Edition.h" + header "CBLBase.h" + header "CBLBlob.h" + header "CBLCollection.h" + header "CBLDatabase.h" + header "CBLDefaults.h" + header "CBLDocument.h" + header "CBLEncryptable.h" + header "CBLLog.h" + header "CBLPlatform.h" + header "CBLPrediction.h" + header "CBLQuery.h" + header "CBLQueryIndex.h" + header "CBLQueryIndexTypes.h" + header "CBLQueryTypes.h" + header "CBLReplicator.h" + header "CBLScope.h" + + module Fleece { + header "Fleece.h" + header "FLBase.h" + header "FLCollections.h" + header "FLDeepIterator.h" + header "FLDoc.h" + header "Fleece+CoreFoundation.h" + header "FLEncoder.h" + header "FLExpert.h" + header "FLJSON.h" + header "FLKeyPath.h" + header "FLMutable.h" + header "FLSlice.h" + header "FLValue.h" + header "CompilerSupport.h" + } +} diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..6cb5e91 --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist new file mode 100644 index 0000000..dedf43b --- /dev/null +++ b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.com.couchbase.CouchbaseLite-C + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 3.2.1 + CFBundleVersion + 9 + + diff --git a/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite new file mode 100644 index 0000000..c99acfd Binary files /dev/null and b/libcblite_enterprise/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite_enterprise/lib/macos/libcblite.3.dylib b/libcblite_enterprise/lib/macos/libcblite.3.dylib new file mode 100755 index 0000000..e7fc53a Binary files /dev/null and b/libcblite_enterprise/lib/macos/libcblite.3.dylib differ diff --git a/libcblite_enterprise/lib/x86_64-linux-android/libcblite.so b/libcblite_enterprise/lib/x86_64-linux-android/libcblite.so new file mode 100644 index 0000000..ba51bad Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-linux-android/libcblite.so differ diff --git a/libcblite_enterprise/lib/x86_64-linux-android/libcblite.stripped.so b/libcblite_enterprise/lib/x86_64-linux-android/libcblite.stripped.so new file mode 100755 index 0000000..e867847 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-linux-android/libcblite.stripped.so differ diff --git a/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.dll b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.dll new file mode 100644 index 0000000..52a69b9 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.dll differ diff --git a/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.lib b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.lib new file mode 100644 index 0000000..37a9ced Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.lib differ diff --git a/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.stripped.dll b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.stripped.dll new file mode 100755 index 0000000..2ee9478 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-pc-windows-gnu/cblite.stripped.dll differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libcblite.so.3 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libcblite.so.3 new file mode 100644 index 0000000..4f44463 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libcblite.so.3 differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicudata.so.66 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicudata.so.66 new file mode 100644 index 0000000..b7392d4 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicudata.so.66 differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 new file mode 100644 index 0000000..c8d5c4f Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicui18n.so.66 differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuio.so.66 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuio.so.66 new file mode 100644 index 0000000..28161da Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuio.so.66 differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicutu.so.66 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicutu.so.66 new file mode 100644 index 0000000..44c0f1e Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicutu.so.66 differ diff --git a/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 new file mode 100644 index 0000000..c4d8625 Binary files /dev/null and b/libcblite_enterprise/lib/x86_64-unknown-linux-gnu/libicuuc.so.66 differ diff --git a/src/database.rs b/src/database.rs index a2d19e3..169d5d3 100644 --- a/src/database.rs +++ b/src/database.rs @@ -22,14 +22,13 @@ use crate::{ c_api::{ CBLDatabase, CBLDatabaseConfiguration, CBLDatabaseConfiguration_Default, CBLDatabase_AddChangeListener, CBLDatabase_BeginTransaction, - CBLDatabase_BufferNotifications, CBLDatabase_ChangeEncryptionKey, CBLDatabase_Close, - CBLDatabase_Count, CBLDatabase_Delete, CBLDatabase_EndTransaction, CBLDatabase_Name, - CBLDatabase_Open, CBLDatabase_Path, CBLDatabase_PerformMaintenance, - CBLDatabase_SendNotifications, CBLEncryptionKey, CBLError, CBL_DatabaseExists, - CBL_DeleteDatabase, CBLEncryptionKey_FromPassword, FLString, kCBLMaintenanceTypeCompact, - kCBLEncryptionAES256, kCBLEncryptionNone, kCBLMaintenanceTypeFullOptimize, - kCBLMaintenanceTypeIntegrityCheck, kCBLMaintenanceTypeOptimize, kCBLMaintenanceTypeReindex, - CBL_CopyDatabase, CBLDatabase_ScopeNames, CBLDatabase_CollectionNames, CBLDatabase_Scope, + CBLDatabase_BufferNotifications, CBLDatabase_Close, CBLDatabase_Count, CBLDatabase_Delete, + CBLDatabase_EndTransaction, CBLDatabase_Name, CBLDatabase_Open, CBLDatabase_Path, + CBLDatabase_PerformMaintenance, CBLDatabase_SendNotifications, CBLError, + CBL_DatabaseExists, CBL_DeleteDatabase, FLString, kCBLMaintenanceTypeCompact, + kCBLMaintenanceTypeFullOptimize, kCBLMaintenanceTypeIntegrityCheck, + kCBLMaintenanceTypeOptimize, kCBLMaintenanceTypeReindex, CBL_CopyDatabase, + CBLDatabase_ScopeNames, CBLDatabase_CollectionNames, CBLDatabase_Scope, CBLDatabase_Collection, CBLDatabase_CreateCollection, CBLDatabase_DeleteCollection, CBLDatabase_DefaultScope, CBLDatabase_DefaultCollection, }, @@ -38,9 +37,15 @@ use crate::{ scope::Scope, MutableArray, }; +#[cfg(feature = "enterprise")] +use crate::c_api::{ + CBLDatabase_ChangeEncryptionKey, CBLEncryptionKey, CBLEncryptionKey_FromPassword, + kCBLEncryptionAES256, kCBLEncryptionNone, +}; use std::path::{Path, PathBuf}; use std::ptr; +#[cfg(feature = "enterprise")] enum_from_primitive! { /// Database encryption algorithms #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -55,10 +60,12 @@ pub const ENCRYPTION_KEY_SIZE_AES256: i64 = 32; /// Encryption key specified in a DatabaseConfiguration #[derive(Debug, Clone)] +#[cfg(feature = "enterprise")] pub struct EncryptionKey { cbl_ref: Box, } +#[cfg(feature = "enterprise")] impl EncryptionKey { /// Derives an encryption key from a password. If your UI uses passwords, call this function to /// create the key used to encrypt the database. It is designed for security, and deliberately @@ -85,6 +92,7 @@ impl EncryptionKey { } } +#[cfg(feature = "enterprise")] impl CblRef for EncryptionKey { type Output = *const CBLEncryptionKey; fn get_ref(&self) -> Self::Output { @@ -96,6 +104,7 @@ impl CblRef for EncryptionKey { #[derive(Debug, Clone)] pub struct DatabaseConfiguration<'a> { pub directory: &'a std::path::Path, + #[cfg(feature = "enterprise")] pub encryption_key: Option, } @@ -192,6 +201,7 @@ impl Database { if let Some(cfg) = config { let mut c_config: CBLDatabaseConfiguration = CBLDatabaseConfiguration_Default(); c_config.directory = from_str(cfg.directory.to_str().unwrap()).get_ref(); + #[cfg(feature = "enterprise")] if let Some(encryption_key) = cfg.encryption_key { c_config.encryptionKey = *encryption_key.get_ref(); } @@ -241,6 +251,7 @@ impl Database { ) .get_ref(); + #[cfg(feature = "enterprise")] if let Some(encryption_key) = cfg.encryption_key { c_config.encryptionKey = unsafe { *encryption_key.get_ref() }; } @@ -337,6 +348,7 @@ impl Database { } /// Encrypts or decrypts a database, or changes its encryption key. + #[cfg(feature = "enterprise")] pub fn change_encryption_key(&mut self, encryption_key: &EncryptionKey) -> Result<()> { unsafe { check_bool(|error| { diff --git a/src/fleece.rs b/src/fleece.rs index 91144b9..7f7dd37 100644 --- a/src/fleece.rs +++ b/src/fleece.rs @@ -20,19 +20,23 @@ use crate::{ slice::{NULL_SLICE, from_bytes, from_str}, error::{Error, Result}, c_api::{ - CBLEncryptable, FLArray, FLArrayIterator, FLArrayIterator_Begin, FLArrayIterator_GetCount, + FLArray, FLArrayIterator, FLArrayIterator_Begin, FLArrayIterator_GetCount, FLArrayIterator_GetValue, FLArrayIterator_GetValueAt, FLArrayIterator_Next, FLArray_Count, FLArray_Get, FLArray_IsEmpty, FLDict, FLDictIterator, FLDictIterator_Begin, FLDictIterator_GetCount, FLDictIterator_GetKeyString, FLDictIterator_GetValue, FLDictIterator_Next, FLDictKey, FLDictKey_GetString, FLDictKey_Init, FLDict_Count, - FLDict_Get, FLDict_GetEncryptableValue, FLDict_GetWithKey, FLDict_IsBlob, FLDict_IsEmpty, - FLDict_IsEncryptableValue, FLDoc, FLDoc_FromJSON, FLDoc_FromResultData, FLDoc_GetData, - FLDoc_GetRoot, FLDoc_Release, FLDoc_Retain, FLError, FLError_kFLInvalidData, FLSlice_Copy, - FLValue, FLValue_AsArray, FLValue_AsBool, FLValue_AsData, FLValue_AsDict, FLValue_AsDouble, - FLValue_AsFloat, FLValue_AsInt, FLValue_AsString, FLValue_AsTimestamp, FLValue_AsUnsigned, - FLValue_GetType, FLValue_IsEqual, FLValue_IsInteger, FLValue_IsUnsigned, FLValue_IsDouble, + FLDict_Get, FLDict_GetWithKey, FLDict_IsBlob, FLDict_IsEmpty, FLDoc, FLDoc_FromJSON, + FLDoc_FromResultData, FLDoc_GetData, FLDoc_GetRoot, FLDoc_Release, FLDoc_Retain, FLError, + FLError_kFLInvalidData, FLSlice_Copy, FLValue, FLValue_AsArray, FLValue_AsBool, + FLValue_AsData, FLValue_AsDict, FLValue_AsDouble, FLValue_AsFloat, FLValue_AsInt, + FLValue_AsString, FLValue_AsTimestamp, FLValue_AsUnsigned, FLValue_GetType, + FLValue_IsEqual, FLValue_IsInteger, FLValue_IsUnsigned, FLValue_IsDouble, FLValue_IsMutable, FLValue_ToJSON, _FLValue, FLValue_FindDoc, FLDictIterator_End, }, +}; +#[cfg(feature = "enterprise")] +use crate::{ + c_api::{CBLEncryptable, FLDict_GetEncryptableValue, FLDict_IsEncryptableValue}, encryptable::Encryptable, }; @@ -224,6 +228,7 @@ impl Value { unsafe { FLValue_IsMutable(self.get_ref()) } } + #[cfg(feature = "enterprise")] pub fn is_encryptable(&self) -> bool { unsafe { FLDict_IsEncryptableValue(FLValue_AsDict(self.get_ref())) } } @@ -314,6 +319,7 @@ impl Value { } } + #[cfg(feature = "enterprise")] pub fn get_encryptable_value(&self) -> Encryptable { unsafe { let encryptable = FLDict_GetEncryptableValue(FLValue_AsDict(self.get_ref())); @@ -567,6 +573,7 @@ impl Dict { unsafe { FLDict_IsEmpty(self.get_ref()) } } + #[cfg(feature = "enterprise")] pub fn is_encryptable(&self) -> bool { unsafe { FLDict_IsEncryptableValue(self.get_ref()) } } @@ -587,6 +594,7 @@ impl Dict { } } + #[cfg(feature = "enterprise")] pub fn get_encryptable_value(&self) -> Encryptable { unsafe { let encryptable = FLDict_GetEncryptableValue(self.get_ref()); diff --git a/src/fleece_mutable.rs b/src/fleece_mutable.rs index 5952789..47aa14b 100644 --- a/src/fleece_mutable.rs +++ b/src/fleece_mutable.rs @@ -16,20 +16,20 @@ // use crate::{ - CblRef, CouchbaseLiteError, Error, ErrorCode, Result, encryptable, + CblRef, CouchbaseLiteError, Error, ErrorCode, Result, slice::{from_bytes, from_str}, c_api::{ FLArray_AsMutable, FLArray_MutableCopy, FLDict_AsMutable, FLDict_MutableCopy, FLMutableArray, FLMutableArray_Append, FLMutableArray_Insert, FLMutableArray_IsChanged, FLMutableArray_New, FLMutableArray_Remove, FLMutableArray_Set, FLMutableDict, FLMutableDict_IsChanged, FLMutableDict_New, FLMutableDict_Remove, FLMutableDict_RemoveAll, - FLMutableDict_Set, FLSlot, FLSlot_SetBool, FLSlot_SetDouble, FLSlot_SetEncryptableValue, - FLSlot_SetInt, FLSlot_SetNull, FLSlot_SetString, FLSlot_SetValue, FLValue, FLValue_Release, - FLValue_Retain, + FLMutableDict_Set, FLSlot, FLSlot_SetBool, FLSlot_SetDouble, FLSlot_SetInt, FLSlot_SetNull, + FLSlot_SetString, FLSlot_SetValue, FLValue, FLValue_Release, FLValue_Retain, }, fleece::{Array, ArrayIterator, Dict, DictIterator, DictKey, FleeceReference, Value}, - encryptable::Encryptable, }; +#[cfg(feature = "enterprise")] +use crate::{c_api::FLSlot_SetEncryptableValue, encryptable::Encryptable}; use std::collections::HashMap; use std::fmt; @@ -314,6 +314,7 @@ impl MutableDict { .collect::>() } + #[cfg(feature = "enterprise")] pub fn set_encryptable_value(dict: &Self, key: &str, encryptable: &Encryptable) { unsafe { FLSlot_SetEncryptableValue( @@ -485,7 +486,8 @@ impl Slot<'_> { unsafe { FLSlot_SetValue(self.get_ref(), value._fleece_ref()) } } - pub fn put_encrypt(self, value: &encryptable::Encryptable) { + #[cfg(feature = "enterprise")] + pub fn put_encrypt(self, value: &Encryptable) { unsafe { FLSlot_SetEncryptableValue(self.get_ref(), value.get_ref()) } } } diff --git a/src/lib.rs b/src/lib.rs index 8b1bf35..10d1314 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,7 @@ pub mod blob; pub mod collection; pub mod database; pub mod document; +#[cfg(feature = "enterprise")] pub mod encryptable; pub mod error; pub mod fleece; diff --git a/src/main.rs b/src/main.rs index 12c4781..72b20e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ fn main() { let tmp_dir = TempDir::new("cbl_rust").expect("create temp dir"); let cfg = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: None, }; let mut db = Database::open("main_db", Some(cfg)).expect("open db"); diff --git a/src/replicator.rs b/src/replicator.rs index c2bc0ac..00684c2 100644 --- a/src/replicator.rs +++ b/src/replicator.rs @@ -24,28 +24,36 @@ use std::{ time::Duration, }; use crate::{ - CblRef, CouchbaseLiteError, Database, Dict, Document, Error, ErrorCode, ListenerToken, - MutableDict, Result, check_error, release, retain, - slice::{from_str, from_bytes, self}, + CblRef, Database, Dict, Document, Error, ListenerToken, MutableDict, Result, check_error, + release, retain, + slice::{from_str, self}, c_api::{ CBLListener_Remove, CBLAuth_CreatePassword, CBLAuth_CreateSession, CBLAuthenticator, - CBLDocument, CBLDocumentFlags, CBLEndpoint, CBLEndpoint_CreateWithLocalDB, - CBLEndpoint_CreateWithURL, CBLError, CBLProxySettings, CBLProxyType, CBLReplicatedDocument, - CBLReplicator, CBLReplicatorConfiguration, CBLReplicatorStatus, CBLReplicatorType, + CBLDocument, CBLDocumentFlags, CBLEndpoint, CBLEndpoint_CreateWithURL, CBLError, + CBLProxySettings, CBLProxyType, CBLReplicatedDocument, CBLReplicator, + CBLReplicatorConfiguration, CBLReplicatorStatus, CBLReplicatorType, CBLReplicator_AddChangeListener, CBLReplicator_AddDocumentReplicationListener, CBLReplicator_Create, CBLReplicator_IsDocumentPending, CBLReplicator_PendingDocumentIDs, CBLReplicator_SetHostReachable, CBLReplicator_SetSuspended, CBLReplicator_Start, - CBLReplicator_Status, CBLReplicator_Stop, FLDict, FLSlice, FLSliceResult, - FLSliceResult_New, FLSlice_Copy, FLString, FLStringResult, kCBLDocumentFlagsAccessRemoved, + CBLReplicator_Status, CBLReplicator_Stop, FLDict, FLString, kCBLDocumentFlagsAccessRemoved, kCBLDocumentFlagsDeleted, kCBLProxyHTTP, kCBLProxyHTTPS, kCBLReplicatorBusy, kCBLReplicatorConnecting, kCBLReplicatorIdle, kCBLReplicatorOffline, kCBLReplicatorStopped, kCBLReplicatorTypePull, kCBLReplicatorTypePush, kCBLReplicatorTypePushAndPull, CBLReplicator_IsDocumentPending2, CBLReplicator_PendingDocumentIDs2, CBLReplicationCollection, }, - MutableArray, Listener, error, + MutableArray, Listener, collection::Collection, }; +#[cfg(feature = "enterprise")] +use crate::{ + CouchbaseLiteError, ErrorCode, error, + c_api::{ + CBLEndpoint_CreateWithLocalDB, FLSlice, FLSliceResult, FLSliceResult_New, FLSlice_Copy, + FLStringResult, + }, + slice::from_bytes, +}; // WARNING: THIS API IS UNIMPLEMENTED SO FAR @@ -79,6 +87,7 @@ impl Endpoint { } } + #[cfg(feature = "enterprise")] pub fn new_with_local_db(db: &Database) -> Self { unsafe { Self { @@ -326,6 +335,7 @@ pub enum EncryptionError { replicate with the kCBLErrorCrypto error. For security reason, the encryption cannot be skipped. */ #[deprecated(note = "please use `CollectionPropertyEncryptor` on default collection instead")] +#[cfg(feature = "enterprise")] pub type DefaultCollectionPropertyEncryptor = fn( document_id: Option, properties: Dict, @@ -336,6 +346,7 @@ pub type DefaultCollectionPropertyEncryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] +#[cfg(feature = "enterprise")] pub extern "C" fn c_default_collection_property_encryptor( context: *mut ::std::os::raw::c_void, document_id: FLString, @@ -401,6 +412,7 @@ pub extern "C" fn c_default_collection_property_encryptor( \note If a null result or an error is returned, the document will be failed to replicate with the kCBLErrorCrypto error. For security reason, the encryption cannot be skipped. */ +#[cfg(feature = "enterprise")] pub type CollectionPropertyEncryptor = fn( scope: Option, collection: Option, @@ -413,6 +425,7 @@ pub type CollectionPropertyEncryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] +#[cfg(feature = "enterprise")] pub extern "C" fn c_collection_property_encryptor( context: *mut ::std::os::raw::c_void, scope: FLString, @@ -483,6 +496,7 @@ pub extern "C" fn c_collection_property_encryptor( without an error is returned. If an error is returned, the document will be failed to replicate with the kCBLErrorCrypto error. */ #[deprecated(note = "please use `CollectionPropertyDecryptor` on default collection instead")] +#[cfg(feature = "enterprise")] pub type DefaultCollectionPropertyDecryptor = fn( document_id: Option, properties: Dict, @@ -493,6 +507,7 @@ pub type DefaultCollectionPropertyDecryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] +#[cfg(feature = "enterprise")] pub extern "C" fn c_default_collection_property_decryptor( context: *mut ::std::os::raw::c_void, document_id: FLString, @@ -558,6 +573,7 @@ pub extern "C" fn c_default_collection_property_decryptor( \note The decryption will be skipped (the encrypted data will be kept) when a null result without an error is returned. If an error is returned, the document will be failed to replicate with the kCBLErrorCrypto error. */ +#[cfg(feature = "enterprise")] pub type CollectionPropertyDecryptor = fn( scope: Option, collection: Option, @@ -570,6 +586,7 @@ pub type CollectionPropertyDecryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] +#[cfg(feature = "enterprise")] pub extern "C" fn c_collection_property_decryptor( context: *mut ::std::os::raw::c_void, scope: FLString, @@ -640,9 +657,13 @@ pub struct ReplicationConfigurationContext { pub push_filter: Option, // TODO: deprecated pub pull_filter: Option, // TODO: deprecated pub conflict_resolver: Option, // TODO: deprecated + #[cfg(feature = "enterprise")] pub default_collection_property_encryptor: Option, // TODO: deprecated + #[cfg(feature = "enterprise")] pub default_collection_property_decryptor: Option, // TODO: deprecated + #[cfg(feature = "enterprise")] pub collection_property_encryptor: Option, + #[cfg(feature = "enterprise")] pub collection_property_decryptor: Option, } @@ -805,18 +826,22 @@ impl Replicator { .conflict_resolver .as_ref() .and(Some(c_replication_conflict_resolver)), + #[cfg(feature = "enterprise")] propertyEncryptor: context .default_collection_property_encryptor .as_ref() .and(Some(c_default_collection_property_encryptor)), + #[cfg(feature = "enterprise")] propertyDecryptor: context .default_collection_property_decryptor .as_ref() .and(Some(c_default_collection_property_decryptor)), + #[cfg(feature = "enterprise")] documentPropertyEncryptor: context .collection_property_encryptor .as_ref() .and(Some(c_collection_property_encryptor)), + #[cfg(feature = "enterprise")] documentPropertyDecryptor: context .collection_property_decryptor .as_ref() diff --git a/src/slice.rs b/src/slice.rs index 99cfe5a..5e34f35 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -17,8 +17,10 @@ use crate::{ CblRef, - c_api::{FLSlice, FLSlice_Copy, FLSliceResult, _FLBuf_Release, _FLBuf_Retain, FLData_Dump}, + c_api::{FLSlice, FLSliceResult, _FLBuf_Release, _FLBuf_Retain, FLData_Dump}, }; +#[cfg(feature = "enterprise")] +use crate::c_api::FLSlice_Copy; use std::borrow::Cow; use std::ffi::{CStr, CString, c_void}; @@ -168,6 +170,7 @@ impl std::ops::Not for FLSlice { } impl FLSliceResult { + #[cfg(feature = "enterprise")] pub fn null() -> FLSliceResult { let s = FLSlice { buf: ptr::null(), diff --git a/tests/database_tests.rs b/tests/database_tests.rs index c62cf2f..2eb449a 100644 --- a/tests/database_tests.rs +++ b/tests/database_tests.rs @@ -48,6 +48,7 @@ fn delete_file() { let tmp_dir = TempDir::new("cbl_rust").expect("create temp dir"); let cfg = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: None, }; if let Err(_) = Database::open(DB_NAME, Some(cfg)) { @@ -70,6 +71,7 @@ fn copy_file() { let tmp_dir = TempDir::new("cbl_rust").expect("create temp dir"); let cfg = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: None, }; match Database::open(DB_NAME, Some(cfg.clone())) { @@ -143,16 +145,19 @@ fn db_properties() { } #[test] +#[cfg(feature = "enterprise")] fn db_encryption_key() { let tmp_dir = TempDir::new("cbl_rust").expect("create temp dir"); let cfg_no_encryption = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: None, }; let encryption_key = EncryptionKey::new_from_password(EncryptionAlgorithm::None, "password1").unwrap(); let cfg_encryption1 = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: Some(encryption_key.clone()), }; diff --git a/tests/document_tests.rs b/tests/document_tests.rs index 2825b95..8aac1d0 100644 --- a/tests/document_tests.rs +++ b/tests/document_tests.rs @@ -234,6 +234,7 @@ fn database_add_document_change_listener() { } #[test] +#[cfg(feature = "enterprise")] fn database_delete_document() { let (sender, receiver) = std::sync::mpsc::channel(); diff --git a/tests/replicator_tests.rs b/tests/replicator_tests.rs index 6388e72..1d64c54 100644 --- a/tests/replicator_tests.rs +++ b/tests/replicator_tests.rs @@ -17,8 +17,11 @@ extern crate couchbase_lite; +#[cfg(feature = "enterprise")] use self::couchbase_lite::*; +#[cfg(feature = "enterprise")] use encryptable::Encryptable; +#[cfg(feature = "enterprise")] use std::{time::Duration, thread}; pub mod utils; @@ -26,6 +29,7 @@ pub mod utils; //////// TESTS: #[test] +#[cfg(feature = "enterprise")] fn push_replication() { let mut tester = utils::ReplicationTwoDbsTester::new( utils::ReplicationTestConfiguration::default(), @@ -45,6 +49,7 @@ fn push_replication() { } #[test] +#[cfg(feature = "enterprise")] fn pull_replication() { let mut tester = utils::ReplicationTwoDbsTester::new( utils::ReplicationTestConfiguration::default(), @@ -64,6 +69,7 @@ fn pull_replication() { } #[test] +#[cfg(feature = "enterprise")] fn push_pull_replication() { let mut tester = utils::ReplicationThreeDbsTester::new( utils::ReplicationTestConfiguration::default(), @@ -91,6 +97,7 @@ fn push_pull_replication() { } #[test] +#[cfg(feature = "enterprise")] fn pull_type_not_pushing() { let config = utils::ReplicationTestConfiguration { replicator_type: ReplicatorType::Pull, @@ -115,6 +122,7 @@ fn pull_type_not_pushing() { } #[test] +#[cfg(feature = "enterprise")] fn push_type_not_pulling() { let config = utils::ReplicationTestConfiguration { replicator_type: ReplicatorType::Push, @@ -139,6 +147,7 @@ fn push_type_not_pulling() { } #[test] +#[cfg(feature = "enterprise")] fn document_ids() { let mut document_ids = MutableArray::new(); document_ids.append().put_string("foo"); @@ -172,6 +181,7 @@ fn document_ids() { } #[test] +#[cfg(feature = "enterprise")] fn push_and_pull_filter() { let context1 = ReplicationConfigurationContext { push_filter: Some(Box::new(|document, _is_deleted, _is_access_removed| { @@ -227,6 +237,7 @@ fn push_and_pull_filter() { } #[test] +#[cfg(feature = "enterprise")] fn conflict_resolver() { let (sender, receiver) = std::sync::mpsc::channel(); @@ -316,6 +327,7 @@ fn conflict_resolver() { } #[test] +#[cfg(feature = "enterprise")] fn conflict_resolver_save_keep_local() { let mut tester = utils::ReplicationTwoDbsTester::new( utils::ReplicationTestConfiguration::default(), @@ -397,6 +409,7 @@ fn conflict_resolver_save_keep_local() { } #[test] +#[cfg(feature = "enterprise")] fn conflict_resolver_save_keep_remote() { let mut tester = utils::ReplicationTwoDbsTester::new( utils::ReplicationTestConfiguration::default(), @@ -479,6 +492,7 @@ fn conflict_resolver_save_keep_remote() { // Encryption/Decryption +#[cfg(feature = "enterprise")] fn encryptor( _document_id: Option, _properties: Dict, @@ -490,6 +504,7 @@ fn encryptor( ) -> std::result::Result, EncryptionError> { Ok(input.iter().map(|u| u ^ 48).collect()) } +#[cfg(feature = "enterprise")] fn decryptor( _document_id: Option, _properties: Dict, @@ -501,6 +516,7 @@ fn decryptor( ) -> std::result::Result, EncryptionError> { Ok(input.iter().map(|u| u ^ 48).collect()) } +#[cfg(feature = "enterprise")] fn encryptor_err_temporary( _document_id: Option, _properties: Dict, @@ -512,6 +528,7 @@ fn encryptor_err_temporary( ) -> std::result::Result, EncryptionError> { Err(EncryptionError::Temporary) } +#[cfg(feature = "enterprise")] fn decryptor_err_temporary( _document_id: Option, _properties: Dict, @@ -523,6 +540,7 @@ fn decryptor_err_temporary( ) -> std::result::Result, EncryptionError> { Err(EncryptionError::Temporary) } +#[cfg(feature = "enterprise")] fn encryptor_err_permanent( _document_id: Option, _properties: Dict, @@ -534,6 +552,7 @@ fn encryptor_err_permanent( ) -> std::result::Result, EncryptionError> { Err(EncryptionError::Permanent) } +#[cfg(feature = "enterprise")] fn decryptor_err_permanent( _document_id: Option, _properties: Dict, @@ -547,6 +566,7 @@ fn decryptor_err_permanent( } #[test] +#[cfg(feature = "enterprise")] fn encryption_ok_decryption_ok() { let context1 = ReplicationConfigurationContext { default_collection_property_encryptor: Some(encryptor), @@ -612,6 +632,7 @@ fn encryption_ok_decryption_ok() { } #[test] +#[cfg(feature = "enterprise")] fn encryption_error_temporary() { let config = utils::ReplicationTestConfiguration { continuous: false, @@ -674,6 +695,7 @@ fn encryption_error_temporary() { } #[test] +#[cfg(feature = "enterprise")] fn decryption_error_temporary() { let config = utils::ReplicationTestConfiguration { continuous: false, @@ -736,6 +758,7 @@ fn decryption_error_temporary() { } #[test] +#[cfg(feature = "enterprise")] fn encryption_error_permanent() { let config = utils::ReplicationTestConfiguration { continuous: false, @@ -818,6 +841,7 @@ fn encryption_error_permanent() { } #[test] +#[cfg(feature = "enterprise")] fn decryption_error_permanent() { let config = utils::ReplicationTestConfiguration { continuous: false, @@ -904,6 +928,7 @@ mod unsafe_test { use super::*; #[test] + #[cfg(feature = "enterprise")] fn continuous() { let config = utils::ReplicationTestConfiguration { continuous: false, diff --git a/tests/utils.rs b/tests/utils.rs index 2f4140f..ddc2d84 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -5,10 +5,11 @@ use self::couchbase_lite::*; use self::tempdir::TempDir; use std::{ - collections::HashMap, sync::{Arc, Mutex, MutexGuard}, thread, time, }; +#[cfg(feature = "enterprise")] +use std::collections::HashMap; // Enables check for leaks of native CBL objects after `with_db()` finishes. // WARNING: These checks only work if one test method runs at a time, i.e. testing is single @@ -46,6 +47,7 @@ where let tmp_dir = TempDir::new("cbl_rust").expect("create temp dir"); let cfg = DatabaseConfiguration { directory: tmp_dir.path(), + #[cfg(feature = "enterprise")] encryption_key: None, }; let mut db = Database::open(DB_NAME, Some(cfg)).expect("open db"); @@ -90,6 +92,7 @@ impl Default for ReplicationTestConfiguration { } } +#[cfg(feature = "enterprise")] fn generate_replication_configuration( local_db: &Database, central_db: &Database, @@ -116,6 +119,7 @@ fn generate_replication_configuration( } } +#[cfg(feature = "enterprise")] pub struct ReplicationTwoDbsTester { _tmp_dir: TempDir, pub local_database: Database, @@ -124,6 +128,7 @@ pub struct ReplicationTwoDbsTester { replicator_continuous: bool, } +#[cfg(feature = "enterprise")] impl ReplicationTwoDbsTester { pub fn new( replication_configuration: ReplicationTestConfiguration, @@ -227,6 +232,7 @@ impl ReplicationTwoDbsTester { } } +#[cfg(feature = "enterprise")] impl Drop for ReplicationTwoDbsTester { fn drop(&mut self) { self.stop_replicator(); @@ -236,6 +242,7 @@ impl Drop for ReplicationTwoDbsTester { } } +#[cfg(feature = "enterprise")] pub struct ReplicationThreeDbsTester { _tmp_dir: TempDir, local_database_1: Database, @@ -247,6 +254,7 @@ pub struct ReplicationThreeDbsTester { replicator_2_continuous: bool, } +#[cfg(feature = "enterprise")] impl ReplicationThreeDbsTester { pub fn new( replication_configuration_1: ReplicationTestConfiguration, @@ -408,6 +416,7 @@ impl ReplicationThreeDbsTester { } } +#[cfg(feature = "enterprise")] impl Drop for ReplicationThreeDbsTester { fn drop(&mut self) { self.stop_replicators(); diff --git a/update_cblite_c.sh b/update_cblite_c.sh index d8fdea7..be0bb3a 100755 --- a/update_cblite_c.sh +++ b/update_cblite_c.sh @@ -2,8 +2,12 @@ set -e +# Uncomment this line to debug the scipt +#set -x + RED="\e[31m" GREEN="\e[32m" +BLUE="\e[34m" ENDCOLOR="\e[0m" function echoGreen() { @@ -14,8 +18,15 @@ function echoRed() { echo -e "${RED}$1${ENDCOLOR}" } +function echoBlue { + echo -e "${BLUE}$1${ENDCOLOR}" +} + scriptDir=$(dirname "$0") echo "Script directory: $scriptDir" +echo + +cd $scriptDir # ####### # # Options # @@ -52,21 +63,13 @@ then help exit 1 else - echoGreen "All good, let's start with CBlite $version :-)" + echoGreen "Let's start updating to CBlite $version :-)" + echo fi tmpFolder=$(mktemp -d) echo "Temporary directory ${tmpFolder}" - -# ################################## # -# Download couchbase-lite-C packages # -# ################################## # - -echoGreen "Start downloading" - -tmpDownloadFolder="${tmpFolder}/download" -mkdir $tmpDownloadFolder -echo "Temporary download directory ${tmpFolder}" +echo declare -A platforms=( [linux]=linux-x86_64.tar.gz @@ -76,174 +79,208 @@ declare -A platforms=( [ios]=ios.zip ) -function download() { - local suffix="$1" +variants=("community" "enterprise") - local url="https://packages.couchbase.com/releases/couchbase-lite-c/${version}/couchbase-lite-c-enterprise-${version}-${suffix}" - local file="${tmpDownloadFolder}/${suffix}" +for variant in ${variants[@]} +do + echoBlue "Start variant $variant" + echo - wget --quiet --show-progress --output-document "${file}" "${url}" -} + mkdir $tmpFolder/$variant -for platform in "${!platforms[@]}" -do - echo "Downloading ${platform} package" + # ################################## # + # Download couchbase-lite-C packages # + # ################################## # - fileName=${platforms[$platform]} - download $fileName -done + echoGreen "Start downloading" -echoGreen "Downloading successful" + tmpDownloadFolder="${tmpFolder}/${variant}/download" + mkdir $tmpDownloadFolder + echo "Temporary download directory ${tmpDownloadFolder}" -# ############## # -# Unzip packages # -# ############## # + function download() { + local platformName="$1" + local variant="$2" -echoGreen "Start unzipping" + local url="https://packages.couchbase.com/releases/couchbase-lite-c/${version}/couchbase-lite-c-${variant}-${version}-${platformName}" + local file="${tmpDownloadFolder}/${platformName}" -tmpUnzipFolder="${tmpFolder}/unzip" -mkdir $tmpUnzipFolder -echo "Temporary unzip directory ${tmpUnzipFolder}" + wget --quiet --show-progress --output-document "${file}" "${url}" + } -for platform in "${!platforms[@]}" -do - echo "Unzipping ${platform} package" - fileName=${platforms[$platform]} - zippedPath="$tmpDownloadFolder/$fileName" - unzipPlatformFolder="${tmpUnzipFolder}/$platform" - mkdir $unzipPlatformFolder + for platform in "${!platforms[@]}" + do + echo "Downloading ${platform} package" - tar -x -f $zippedPath --directory $unzipPlatformFolder -done + platformName=${platforms[$platform]} + download $platformName $variant + done -echoGreen "Unzipping successful" + echoGreen "Downloading successful" + echo -# ######################## # -# Package libcblite folder # -# ######################## # + # ############## # + # Unzip packages # + # ############## # -echoGreen "Package libcblite" + echoGreen "Start unzipping" -tmpLibcbliteFolder="${tmpFolder}/libcblite" -mkdir $tmpLibcbliteFolder -echo "Temporary libcblite directory ${tmpLibcbliteFolder}" + tmpUnzipFolder="${tmpFolder}/${variant}/unzip" + mkdir $tmpUnzipFolder + echo "Temporary unzip directory ${tmpUnzipFolder}" -libFolder="${tmpLibcbliteFolder}/lib" -mkdir $libFolder + for platform in "${!platforms[@]}" + do + echo "Unzipping ${platform} package" -for platform in "${!platforms[@]}" -do - echo "Packaging ${platform}" + fileName=${platforms[$platform]} + zippedPath="$tmpDownloadFolder/$fileName" - unzipPlatformFolder="${tmpUnzipFolder}/$platform" + unzipPlatformFolder="${tmpUnzipFolder}/$platform" + mkdir $unzipPlatformFolder - case $platform in + tar -x -f $zippedPath --directory $unzipPlatformFolder + done - linux) - platformFolder="${libFolder}/x86_64-unknown-linux-gnu" - mkdir $platformFolder + echoGreen "Unzipping successful" + echo - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/x86_64-linux-gnu/libcblite.so.${version}" - libDestinationFile="${platformFolder}/libcblite.so.3" - cp $libFile $libDestinationFile + # ######################## # + # Package libcblite folder # + # ######################## # - # There are required ICU libs already present in the existing package - cp $scriptDir/libcblite/lib/x86_64-unknown-linux-gnu/libicu* $platformFolder + echoGreen "Start packaging libcblite_${variant}" - ;; + tmpLibcbliteFolder="${tmpFolder}/libcblite_${variant}" + mkdir $tmpLibcbliteFolder + echo "Temporary libcblite directory ${tmpLibcbliteFolder}" - windows) - platformFolder="${libFolder}/x86_64-pc-windows-gnu" - mkdir $platformFolder + libFolder="${tmpLibcbliteFolder}/lib" + mkdir $libFolder - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/cblite.lib" - cp $libFile $platformFolder + for platform in "${!platforms[@]}" + do + echo "Packaging ${platform}" - binFile="${unzipPlatformFolder}/libcblite-${version}/bin/cblite.dll" - cp $binFile $platformFolder + unzipPlatformFolder="${tmpUnzipFolder}/$platform" - ;; + case $platform in - macos) - platformFolder="${libFolder}/macos" - mkdir $platformFolder + linux) + platformFolder="${libFolder}/x86_64-unknown-linux-gnu" + mkdir $platformFolder - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/libcblite.${version}.dylib" - libDestinationFile="${platformFolder}/libcblite.3.dylib" - cp $libFile $libDestinationFile + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/x86_64-linux-gnu/libcblite.so.${version}" + libDestinationFile="${platformFolder}/libcblite.so.3" + cp $libFile $libDestinationFile - ;; + # There are required ICU libs already present in the existing package + cp libcblite_$variant/lib/x86_64-unknown-linux-gnu/libicu* $platformFolder - android) - # aarch64 - platformFolder="${libFolder}/aarch64-linux-android" - mkdir $platformFolder + ;; - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/aarch64-linux-android/libcblite.so" - cp $libFile $platformFolder + windows) + platformFolder="${libFolder}/x86_64-pc-windows-gnu" + mkdir $platformFolder - # arm - platformFolder="${libFolder}/arm-linux-androideabi" - mkdir $platformFolder + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/cblite.lib" + cp $libFile $platformFolder - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/arm-linux-androideabi/libcblite.so" - cp $libFile $platformFolder + binFile="${unzipPlatformFolder}/libcblite-${version}/bin/cblite.dll" + cp $binFile $platformFolder - # i686 - platformFolder="${libFolder}/i686-linux-android" - mkdir $platformFolder + ;; - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/i686-linux-android/libcblite.so" - cp $libFile $platformFolder + macos) + platformFolder="${libFolder}/macos" + mkdir $platformFolder - # x86_64 - platformFolder="${libFolder}/x86_64-linux-android" - mkdir $platformFolder + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/libcblite.${version}.dylib" + libDestinationFile="${platformFolder}/libcblite.3.dylib" + cp $libFile $libDestinationFile - libFile="${unzipPlatformFolder}/libcblite-${version}/lib/x86_64-linux-android/libcblite.so" - cp $libFile $platformFolder + ;; - # Some files/directories must be moved only once for all platforms: include directory & LICENSE.txt - cp -R "${unzipPlatformFolder}/libcblite-${version}/include" $tmpLibcbliteFolder + android) + # aarch64 + platformFolder="${libFolder}/aarch64-linux-android" + mkdir $platformFolder - cp "${unzipPlatformFolder}/libcblite-${version}/LICENSE.txt" $tmpLibcbliteFolder + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/aarch64-linux-android/libcblite.so" + cp $libFile $platformFolder - ;; + # arm + platformFolder="${libFolder}/arm-linux-androideabi" + mkdir $platformFolder - ios) - platformFolder="${libFolder}/ios" - mkdir $platformFolder + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/arm-linux-androideabi/libcblite.so" + cp $libFile $platformFolder - cp -R "${unzipPlatformFolder}/CouchbaseLite.xcframework" $platformFolder + # i686 + platformFolder="${libFolder}/i686-linux-android" + mkdir $platformFolder - ;; - esac -done + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/i686-linux-android/libcblite.so" + cp $libFile $platformFolder -echoGreen "Packaging libcblite successful" + # x86_64 + platformFolder="${libFolder}/x86_64-linux-android" + mkdir $platformFolder -# ######################## # -# Replace libcblite folder # -# ######################## # + libFile="${unzipPlatformFolder}/libcblite-${version}/lib/x86_64-linux-android/libcblite.so" + cp $libFile $platformFolder -echoGreen "Replace libcblite directory by newly package one" + # Some files/directories must be moved only once for all platforms: include directory & LICENSE.txt + cp -R "${unzipPlatformFolder}/libcblite-${version}/include" $tmpLibcbliteFolder -rm -rf $scriptDir/libcblite + cp "${unzipPlatformFolder}/libcblite-${version}/LICENSE.txt" $tmpLibcbliteFolder -cp -R $tmpLibcbliteFolder $scriptDir + ;; -rm -rf $tmpFolder + ios) + platformFolder="${libFolder}/ios" + mkdir $platformFolder + + cp -R "${unzipPlatformFolder}/CouchbaseLite.xcframework" $platformFolder + + ;; + esac + done + + echoGreen "Packaging libcblite_${variant} successful" + echo -echoGreen "Replacing libcblite successful" + # ######################## # + # Replace libcblite folder # + # ######################## # -# ################### # -# Strip the libraries # -# ################### # + echoGreen "Replace libcblite_${variant} directory by newly packaged one" + + rm -rf libcblite_$variant + + cp -R $tmpLibcbliteFolder ./ + + echoGreen "Replacing libcblite_${variant} successful" + echo -echoGreen "Strip libraries" + # ################### # + # Strip the libraries # + # ################### # -DOCKER_BUILDKIT=1 docker build --file $scriptDir/Dockerfile -t strip --output $scriptDir/libcblite $scriptDir + echoGreen "Strip libraries" + + DOCKER_BUILDKIT=1 docker build --file Dockerfile --build-arg DIRNAME=libcblite_$variant -t strip --output . . + + echoGreen "Stripping libraries successful" + echo + + echoBlue "End variant $variant" + echo +done + +rm -rf $tmpFolder -echoGreen "Stripping libcblite successful" +echoGreen "All good :-)" +echoGreen "Next steps: build OK, tests OK & create a pull request"