diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/.DS_Store b/.DS_Store similarity index 64% rename from libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/.DS_Store rename to .DS_Store index dd1b2e4..8af7bba 100644 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/.DS_Store and b/.DS_Store differ diff --git a/Cargo.toml b/Cargo.toml index 8664d50..f88c1a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "couchbase_lite" -version = "3.0.17-0" +version = "3.1.7-0" # The first three numbers correspond to the Couchbase Lite C release, the fourth number corresponds to the Doctolib release [dependencies] diff --git a/Dockerfile b/Dockerfile index b02c2fc..10eddae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ 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/armv7-linux-androideabi/libcblite.so -o /build/libcblite/lib/armv7-linux-androideabi/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 FROM scratch AS strip diff --git a/README.md b/README.md index 6256d19..941bdee 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Install strip: Strip: ``$ cd /build/libcblite-3.0.3/lib/aarch64-linux-android $ strip libcblite.so -o libcblite.stripped.so - $ cd /build/libcblite-3.0.3/lib/armv7-linux-androideabi + $ cd /build/libcblite-3.0.3/lib/arm-linux-androideabi $ strip libcblite.so -o libcblite.stripped.so`` diff --git a/libcblite-3.0.3/.DS_Store b/libcblite-3.0.3/.DS_Store index 85b3a72..c1d4748 100644 Binary files a/libcblite-3.0.3/.DS_Store and b/libcblite-3.0.3/.DS_Store differ diff --git a/libcblite-3.0.3/include/.DS_Store b/libcblite-3.0.3/include/.DS_Store index a7e04a5..63198da 100644 Binary files a/libcblite-3.0.3/include/.DS_Store and b/libcblite-3.0.3/include/.DS_Store differ diff --git a/libcblite-3.0.3/include/cbl++/Base.hh b/libcblite-3.0.3/include/cbl++/Base.hh new file mode 100644 index 0000000..b876102 --- /dev/null +++ b/libcblite-3.0.3/include/cbl++/Base.hh @@ -0,0 +1,172 @@ +// +// 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 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-3.0.3/include/cbl++/Blob.hh b/libcblite-3.0.3/include/cbl++/Blob.hh new file mode 100644 index 0000000..31e94bd --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/cbl++/Collection.hh b/libcblite-3.0.3/include/cbl++/Collection.hh new file mode 100644 index 0000000..65de32a --- /dev/null +++ b/libcblite-3.0.3/include/cbl++/Collection.hh @@ -0,0 +1,327 @@ +// +// 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/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; + + /** 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 name. */ + std::string name() const {return asString(CBLCollection_Name(ref()));} + + /** The scope name. */ + std::string scopeName() const { + auto scope = CBLCollection_Scope(ref()); + auto scopeName = asString(CBLScope_Name(scope)); + CBLScope_Release(scope); + return scopeName; + } + + /** 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); + } + + /** 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; + } + + // 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; + + 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; + }; +} + +/** 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-3.0.3/include/cbl++/CouchbaseLite.hh b/libcblite-3.0.3/include/cbl++/CouchbaseLite.hh new file mode 100644 index 0000000..9b4981f --- /dev/null +++ b/libcblite-3.0.3/include/cbl++/CouchbaseLite.hh @@ -0,0 +1,28 @@ +// +// 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 "Query.hh" +#include "Replicator.hh" diff --git a/libcblite-3.0.3/include/cbl++/Database.hh b/libcblite-3.0.3/include/cbl++/Database.hh new file mode 100644 index 0000000..c0db522 --- /dev/null +++ b/libcblite-3.0.3/include/cbl++/Database.hh @@ -0,0 +1,581 @@ +// +// 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; + + /** 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. + The default scope is exceptional in that it will always exists even there are no collections under it. + @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 { + CBLError error {}; + return Collection::adopt(CBLDatabase_Collection(ref(), collectionName, scopeName, &error), &error) ; + } + + /** 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) { + CBLError error {}; + return Collection::adopt(CBLDatabase_CreateCollection(ref(), collectionName, scopeName, &error), &error) ; + } + + /** Delete an existing collection. + @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. + @note The default collection may not exist if it was deleted. + Also, the default collection cannot be recreated after being deleted. + @return A \ref Collection instance, or NULL if the default collection doesn't exist, or throws if an error occurred. */ + inline Collection getDefaultCollection() const { + CBLError error {}; + return Collection::adopt(CBLDatabase_DefaultCollection(ref(), &error), &error) ; + } + + // 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(); + } + + 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; + + CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(Database, RefCounted, CBLDatabase) + + 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-3.0.3/include/cbl++/Document.hh b/libcblite-3.0.3/include/cbl++/Document.hh new file mode 100644 index 0000000..d28e37e --- /dev/null +++ b/libcblite-3.0.3/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: + 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; + } + + friend class Collection; + friend class Database; + friend class Replicator; + + 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-3.0.3/include/cbl++/Query.hh b/libcblite-3.0.3/include/cbl++/Query.hh new file mode 100644 index 0000000..3314bba --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/cbl++/Replicator.hh b/libcblite-3.0.3/include/cbl++/Replicator.hh new file mode 100644 index 0000000..3fd2286 --- /dev/null +++ b/libcblite-3.0.3/include/cbl++/Replicator.hh @@ -0,0 +1,584 @@ +// +// 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. + @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-3.0.3/include/cbl/CBLBase.h b/libcblite-3.0.3/include/cbl/CBLBase.h index 49af0bd..f7d9ef0 100644 --- a/libcblite-3.0.3/include/cbl/CBLBase.h +++ b/libcblite-3.0.3/include/cbl/CBLBase.h @@ -23,7 +23,7 @@ #include "CBL_Edition.h" #include "CBL_Compat.h" -#include "fleece/FLSlice.h" +#include "fleece/Fleece.h" #include #include @@ -182,6 +182,18 @@ void CBL_DumpInstances(void) CBLAPI; 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. diff --git a/libcblite-3.0.3/include/cbl/CBLBlob.h b/libcblite-3.0.3/include/cbl/CBLBlob.h index 2b53735..06daf8a 100644 --- a/libcblite-3.0.3/include/cbl/CBLBlob.h +++ b/libcblite-3.0.3/include/cbl/CBLBlob.h @@ -18,7 +18,6 @@ #pragma once #include "CBLBase.h" -#include "fleece/Fleece.h" CBL_CAPI_BEGIN @@ -82,12 +81,12 @@ CBL_CAPI_BEGIN /** Returns the length in bytes of a blob's content (from its `length` property). */ uint64_t CBLBlob_Length(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 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; @@ -100,7 +99,7 @@ CBL_CAPI_BEGIN #pragma mark - READING: #endif - /** Reads the blob's contents into memory and returns them. + /** 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, @@ -251,10 +250,7 @@ CBL_CAPI_BEGIN #pragma mark - BINDING DEV SUPPORT FOR BLOB: #endif - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + /** 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 @@ -271,10 +267,7 @@ CBL_CAPI_BEGIN const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, CBLError* _cbl_nullable outError) CBLAPI; - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Save a new \ref CBLBlob object into the database without associating it with + /** 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. diff --git a/libcblite-3.0.3/include/cbl/CBLCollection.h b/libcblite-3.0.3/include/cbl/CBLCollection.h new file mode 100644 index 0000000..070702c --- /dev/null +++ b/libcblite-3.0.3/include/cbl/CBLCollection.h @@ -0,0 +1,467 @@ +// +// 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 "CBLQuery.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. + The default scope is exceptional in that it will always exists even there are no collections under it. + @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. + The default scope is exception in that it will always exists even there are no collections under it. + @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 The default scope always exist even there are no collections under it. + @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 The default collection may not exist if it was deleted. + Also, the default collection cannot be recreated after being deleted. + @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 the default collection doesn't exist or 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 scope of the collection. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return A \ref CBLScope instance. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(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; + +/** 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; + +/** @} */ + +/** \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. - @note The encryption key is not filled in, for security reasons. */ +/** Returns the database's configuration, as given when it was opened. */ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; /** @} */ @@ -232,16 +240,17 @@ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; #endif /** \name Database listeners @{ - A database change listener lets you detect changes made to all documents in a database. + 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 database change listener callback, invoked after one or more documents are changed on disk. +/** 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. + 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) @@ -251,13 +260,13 @@ typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, unsigned numDocs, FLString docIDs[_cbl_nonnull]); -/** Registers a database change listener callback. It will be called after one or more +/** 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.*/ + @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, @@ -303,7 +312,7 @@ typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, @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 callback, + CBLNotificationsReadyCallback _cbl_nullable callback, void* _cbl_nullable context) CBLAPI; /** Immediately issues all pending notifications for this database, by calling their listener diff --git a/libcblite-3.0.3/include/cbl/CBLDefaults.h b/libcblite-3.0.3/include/cbl/CBLDefaults.h new file mode 100644 index 0000000..2ab890d --- /dev/null +++ b/libcblite-3.0.3/include/cbl/CBLDefaults.h @@ -0,0 +1,94 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2023-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" + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +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 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; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite-3.0.3/include/cbl/CBLDocument.h b/libcblite-3.0.3/include/cbl/CBLDocument.h index 2dba05f..6f7c3a8 100644 --- a/libcblite-3.0.3/include/cbl/CBLDocument.h +++ b/libcblite-3.0.3/include/cbl/CBLDocument.h @@ -18,7 +18,6 @@ #pragma once #include "CBLBase.h" -#include "fleece/Fleece.h" CBL_CAPI_BEGIN @@ -59,10 +58,11 @@ typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, const CBLDocument* _cbl_nullable conflictingDocument); -/** Reads a document from the database, creating a new (immutable) \ref CBLDocument object. +/** 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 @@ -75,12 +75,13 @@ const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* data CBL_REFCOUNTED(CBLDocument*, Document); -/** Saves a (mutable) document to the database. - \warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by +/** 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. - @param db The database to save to. + @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. */ @@ -88,12 +89,13 @@ bool CBLDatabase_SaveDocument(CBLDatabase* db, CBLDocument* doc, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database. +/** 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. - @param db The database to save to. + @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. @@ -103,9 +105,10 @@ bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database, allowing for custom conflict handling in the event +/** 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. - @param db The database to save to. + @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. @@ -117,9 +120,10 @@ bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, void* _cbl_nullable context, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. */ @@ -127,9 +131,10 @@ bool CBLDatabase_DeleteDocument(CBLDatabase *db, const CBLDocument* document, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. @@ -139,28 +144,29 @@ bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Purges a document. This removes all traces of the document from the database. +/** 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 containing the document. - @param document The document to delete. + @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, given only its ID. +/** 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. - */ + @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; @@ -176,9 +182,10 @@ bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, in place and then call \ref CBLDatabase_SaveDocument to persist the changes. */ -/** Reads a document from the database, in mutable form that can be updated and saved. +/** 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 @@ -237,6 +244,9 @@ FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; 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. @@ -280,6 +290,7 @@ bool CBLDocument_SetJSON(CBLDocument*, /** 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. @@ -291,6 +302,7 @@ CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, 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), @@ -318,6 +330,7 @@ bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, @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. */ @@ -327,12 +340,12 @@ typedef void (*CBLDocumentChangeListener)(void *context, /** 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.*/ + @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, diff --git a/libcblite-3.0.3/include/cbl/CBLEncryptable.h b/libcblite-3.0.3/include/cbl/CBLEncryptable.h index 4bdcce0..a3142ec 100644 --- a/libcblite-3.0.3/include/cbl/CBLEncryptable.h +++ b/libcblite-3.0.3/include/cbl/CBLEncryptable.h @@ -18,7 +18,6 @@ #pragma once #include "CBLBase.h" -#include "fleece/Fleece.h" #ifdef COUCHBASE_ENTERPRISE diff --git a/libcblite-3.0.3/include/cbl/CBLLog.h b/libcblite-3.0.3/include/cbl/CBLLog.h index dac6701..1792734 100644 --- a/libcblite-3.0.3/include/cbl/CBLLog.h +++ b/libcblite-3.0.3/include/cbl/CBLLog.h @@ -115,11 +115,21 @@ void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; @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 - FLString directory; ///< The directory where log files will be created. - uint32_t maxRotateCount; ///< Max number of older log files to keep (in addition to current one.) - size_t maxSize; ///< The size in bytes at which a file will be rotated out (best effort). - bool usePlaintext; ///< Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + 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. */ diff --git a/libcblite-3.0.3/include/cbl/CBLQuery.h b/libcblite-3.0.3/include/cbl/CBLQuery.h index e101b18..ee26c79 100644 --- a/libcblite-3.0.3/include/cbl/CBLQuery.h +++ b/libcblite-3.0.3/include/cbl/CBLQuery.h @@ -18,7 +18,6 @@ #pragma once #include "CBLBase.h" -#include "fleece/Fleece.h" CBL_CAPI_BEGIN @@ -103,7 +102,6 @@ CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, 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; @@ -276,7 +274,8 @@ typedef struct { /** 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. */ + 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, @@ -285,15 +284,16 @@ bool CBLDatabase_CreateValueIndex(CBLDatabase *db, /** Full-Text Index Configuration. */ typedef struct { - /** The language used in the expressions. */ + /** 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. */ + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ FLString expressions; /** Should diacritical marks (accents) be ignored? - Defaults to false. Generally this should be left `false` for non-English text. */ + 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. @@ -313,19 +313,22 @@ typedef struct { /** 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. */ + 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. */ +/** 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. */ + @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; diff --git a/libcblite-3.0.3/include/cbl/CBLReplicator.h b/libcblite-3.0.3/include/cbl/CBLReplicator.h index ae42b52..8492550 100644 --- a/libcblite-3.0.3/include/cbl/CBLReplicator.h +++ b/libcblite-3.0.3/include/cbl/CBLReplicator.h @@ -18,7 +18,6 @@ #pragma once #include "CBLBase.h" -#include "fleece/Fleece.h" CBL_CAPI_BEGIN @@ -151,6 +150,74 @@ typedef struct { #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. @@ -172,8 +239,10 @@ typedef struct { 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 (*CBLPropertyEncryptor) ( +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 @@ -184,8 +253,8 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( ); /** 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. + 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 : @@ -206,8 +275,10 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( @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 (*CBLPropertyDecryptor) ( +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 @@ -219,50 +290,144 @@ typedef FLSliceResult (*CBLPropertyDecryptor) ( #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 { - CBLDatabase* database; ///< The database to replicate - CBLEndpoint* endpoint; ///< The address of the other database to replicate with - CBLReplicatorType replicatorType; ///< Push, pull or both - bool continuous; ///< Continuous replication? + /** 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. - - IMPORTANT: For performance reasons, the document listeners must be added *before* the replicator is started - or they will not receive the events. + + /** 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; + bool disableAutoPurge; + //-- Retry Logic: - unsigned maxAttempts; ///< 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 maxAttemptWaitTime; ///< Max wait time between retry attempts in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 kCBLDefaultReplicatorMaxAttemptWaitTime. */ + unsigned maxAttemptWaitTime; + //-- WebSocket: - unsigned heartbeat; ///< The heartbeat interval in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 + + 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: - FLSlice pinnedServerCertificate; ///< An X.509 cert to "pin" TLS connections to (PEM or DER) - FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + /** 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: - FLArray _cbl_nullable channels; ///< Optional set of channels to pull from - FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate - CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed - CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs - CBLConflictResolver _cbl_nullable conflictResolver;///< Optional conflict-resolver callback - void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + + /** 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 - CBLPropertyEncryptor _cbl_nullable propertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. - CBLPropertyDecryptor _cbl_nullable propertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. + /** 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; + + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. #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 @@ -271,11 +436,12 @@ typedef struct { 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. */ + 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; + /** @} */ @@ -325,7 +491,6 @@ void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; /** @} */ - /** \name Status and Progress @{ */ @@ -344,7 +509,7 @@ typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { 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; /// Very-approximate fractional completion, from 0.0 to 1.0 + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ _cbl_warn_unused -FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, - CBLError* _cbl_nullable outError) CBLAPI; +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; -/** Indicates whether the document with the given ID has local changes that have not yet been - pushed to the server by this replicator. +/** 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. */ + @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. - @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. + @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. */ @@ -399,7 +593,7 @@ typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, CBLReplicator *replicator, const CBLReplicatorStatus *status); -/** Adds a listener that will be called when the replicator's status changes. */ +/** Registers a listener that will be called when the replicator's status changes. */ _cbl_warn_unused CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, CBLReplicatorChangeListener, @@ -408,15 +602,17 @@ CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, /** 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 + 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; /// /* for CF_ENUM and CF_OPTIONS macros */ #define CBL_ENUM CF_ENUM @@ -57,11 +63,11 @@ #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) enum _name : _type _name; enum _name : _type + #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 : _type + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type #else - #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type + #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 diff --git a/libcblite-3.0.3/include/cbl/CBL_Edition.h b/libcblite-3.0.3/include/cbl/CBL_Edition.h index c590c03..e4a3934 100644 --- a/libcblite-3.0.3/include/cbl/CBL_Edition.h +++ b/libcblite-3.0.3/include/cbl/CBL_Edition.h @@ -20,8 +20,8 @@ #define COUCHBASE_ENTERPRISE #endif -#define CBLITE_VERSION "3.0.17" -#define CBLITE_VERSION_NUMBER 3000017 -#define CBLITE_BUILD_NUMBER 1 -#define CBLITE_SOURCE_ID "3becb76+fd69ae2" -#define CBLITE_BUILD_TIMESTAMP "2023-12-15T19:49:52Z" +#define CBLITE_VERSION "3.1.7" +#define CBLITE_VERSION_NUMBER 3001007 +#define CBLITE_BUILD_NUMBER 5 +#define CBLITE_SOURCE_ID "036da58+b89b125" +#define CBLITE_BUILD_TIMESTAMP "2024-04-23T18:33:20Z" diff --git a/libcblite-3.0.3/include/cbl/CouchbaseLite.h b/libcblite-3.0.3/include/cbl/CouchbaseLite.h index fb9142a..80f2dd5 100644 --- a/libcblite-3.0.3/include/cbl/CouchbaseLite.h +++ b/libcblite-3.0.3/include/cbl/CouchbaseLite.h @@ -19,10 +19,13 @@ #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 "CBLQuery.h" #include "CBLReplicator.h" +#include "CBLScope.h" diff --git a/libcblite-3.0.3/include/fleece/Base.h b/libcblite-3.0.3/include/fleece/CompilerSupport.h similarity index 82% rename from libcblite-3.0.3/include/fleece/Base.h rename to libcblite-3.0.3/include/fleece/CompilerSupport.h index fab3644..8098543 100644 --- a/libcblite-3.0.3/include/fleece/Base.h +++ b/libcblite-3.0.3/include/fleece/CompilerSupport.h @@ -1,5 +1,5 @@ // -// Base.h +// CompilerSupport.h // // Copyright 2018-Present Couchbase, Inc. // @@ -11,8 +11,8 @@ // #pragma once -#ifndef FLEECE_BASE_H -#define FLEECE_BASE_H +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H // The __has_xxx() macros are only(?) implemented by Clang. (Except GCC has __has_attribute...) // Define them to return 0 on other compilers. @@ -57,11 +57,32 @@ #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. #ifdef __clang__ #define NONNULL __attribute__((nonnull)) #else @@ -204,7 +225,28 @@ #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_BASE_H +#else // _FLEECE_COMPILER_SUPPORT_H #warn "Compiler is not honoring #pragma once" #endif diff --git a/libcblite-3.0.3/include/fleece/Expert.hh b/libcblite-3.0.3/include/fleece/Expert.hh new file mode 100644 index 0000000..8350b67 --- /dev/null +++ b/libcblite-3.0.3/include/fleece/Expert.hh @@ -0,0 +1,204 @@ +// +// 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); + + static inline alloc_slice apply(Value old, + slice jsonDelta, + FLError* FL_NULLABLE error); + 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);} + 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);} + + 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-3.0.3/include/fleece/FLBase.h b/libcblite-3.0.3/include/fleece/FLBase.h new file mode 100644 index 0000000..d968f71 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/fleece/FLCollections.h b/libcblite-3.0.3/include/fleece/FLCollections.h new file mode 100644 index 0000000..3ed1822 --- /dev/null +++ b/libcblite-3.0.3/include/fleece/FLCollections.h @@ -0,0 +1,220 @@ +// +// 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. */ + 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 FLArrayIteratorNext. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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 FLDictIterator_Next. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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-3.0.3/include/fleece/FLDeepIterator.h b/libcblite-3.0.3/include/fleece/FLDeepIterator.h new file mode 100644 index 0000000..2e57999 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/fleece/FLDoc.h b/libcblite-3.0.3/include/fleece/FLDoc.h new file mode 100644 index 0000000..2292ec0 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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!! */ + 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-3.0.3/include/fleece/FLEncoder.h b/libcblite-3.0.3/include/fleece/FLEncoder.h new file mode 100644 index 0000000..f3fefc6 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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) */ + 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. */ + 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. */ + MUST_USE_RESULT + 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. */ + MUST_USE_RESULT + 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-3.0.3/include/fleece/FLExpert.h b/libcblite-3.0.3/include/fleece/FLExpert.h new file mode 100644 index 0000000..00d8c97 --- /dev/null +++ b/libcblite-3.0.3/include/fleece/FLExpert.h @@ -0,0 +1,303 @@ +// +// 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 + @{ */ + + + /** \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. */ + 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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + 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.) */ + FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ + 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. */ + 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; + + /** Increments the reference count of an FLSharedKeys. */ + 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. */ + 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. */ + 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. */ + 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; + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning 0) 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. */ + FLEECE_PUBLIC void 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. */ + FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + 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-3.0.3/include/fleece/FLJSON.h b/libcblite-3.0.3/include/fleece/FLJSON.h new file mode 100644 index 0000000..91e7d52 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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-3.0.3/include/fleece/FLKeyPath.h b/libcblite-3.0.3/include/fleece/FLKeyPath.h new file mode 100644 index 0000000..84fb3cf --- /dev/null +++ b/libcblite-3.0.3/include/fleece/FLKeyPath.h @@ -0,0 +1,85 @@ +// +// 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 '$') at the start of a + property name (but not yet in the middle of a name.) + */ + +#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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + 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-3.0.3/include/fleece/FLMutable.h b/libcblite-3.0.3/include/fleece/FLMutable.h new file mode 100644 index 0000000..58971c1 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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. */ + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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-3.0.3/include/fleece/FLSlice.h b/libcblite-3.0.3/include/fleece/FLSlice.h index ec1c40f..7ac3d9a 100644 --- a/libcblite-3.0.3/include/fleece/FLSlice.h +++ b/libcblite-3.0.3/include/fleece/FLSlice.h @@ -16,7 +16,7 @@ #ifndef _FLSLICE_H #define _FLSLICE_H -#include "Base.h" +#include "CompilerSupport.h" #include #include #include @@ -25,13 +25,12 @@ #ifdef __cplusplus #include - #define FLAPI noexcept namespace fleece { struct alloc_slice; } -#else - #define FLAPI #endif +FL_ASSUME_NONNULL_BEGIN + #ifdef __cplusplus extern "C" { #endif @@ -44,7 +43,7 @@ extern "C" { /** 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 *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -62,7 +61,7 @@ typedef struct FLSlice { adopt the reference, and release it in its destructor. For example: `alloc_slice foo( CopyFoo() );` */ typedef struct FLSliceResult { - const void *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -80,7 +79,7 @@ typedef struct FLSliceResult { struct FLHeapSlice : public FLSlice { constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } private: - constexpr FLHeapSlice(const void *b, size_t s) noexcept :FLSlice{b, s} { } + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } friend struct fleece::alloc_slice; }; #else @@ -103,7 +102,9 @@ typedef FLSliceResult FLStringResult; /** 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 *a, const void *b, size_t size) FLAPI { +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); @@ -111,7 +112,7 @@ static inline FLPURE int FLMemCmp(const void *a, const void *b, size_t size) FLA /** 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 *dst, const void *src, size_t size) FLAPI { +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); } @@ -121,7 +122,7 @@ static inline void FLMemCpy(void *dst, const void *src, size_t size) FLAPI { 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 *str) FLAPI { +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { FLSlice foo = { str, str ? strlen(str) : 0 }; return foo; } @@ -136,14 +137,14 @@ static inline FLSlice FLStr(const char *str) FLAPI { /** Equality test of two slices. */ -bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; +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. */ -int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; +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. */ -uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; +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 @@ -152,24 +153,24 @@ uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; @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. */ -bool FLSlice_ToCString(FLSlice s, char* buffer NONNULL, size_t capacity) FLAPI; +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; /** Allocates an FLSliceResult of the given size, without initializing the buffer. */ -FLSliceResult FLSliceResult_New(size_t) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; /** Allocates an FLSliceResult, copying the given slice. */ -FLSliceResult FLSlice_Copy(FLSlice) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; /** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ -static inline FLSliceResult FLSliceResult_CreateWith(const void *bytes, size_t size) FLAPI { +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { FLSlice s = {bytes, size}; return FLSlice_Copy(s); } -void _FLBuf_Retain(const void*) FLAPI; // internal; do not call -void _FLBuf_Release(const void*) FLAPI; // internal; do not call +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 { @@ -184,14 +185,16 @@ static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { /** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { - return *(FLSlice*)&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. */ -void FL_WipeMemory(void *dst, size_t size) FLAPI; +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; /** @} */ @@ -213,4 +216,5 @@ void FL_WipeMemory(void *dst, size_t size) FLAPI; } #endif +FL_ASSUME_NONNULL_END #endif // _FLSLICE_H diff --git a/libcblite-3.0.3/include/fleece/FLValue.h b/libcblite-3.0.3/include/fleece/FLValue.h new file mode 100644 index 0000000..9de1662 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/fleece/Fleece+CoreFoundation.h b/libcblite-3.0.3/include/fleece/Fleece+CoreFoundation.h index c5a0d32..d4a4214 100644 --- a/libcblite-3.0.3/include/fleece/Fleece+CoreFoundation.h +++ b/libcblite-3.0.3/include/fleece/Fleece+CoreFoundation.h @@ -12,7 +12,13 @@ #pragma once #include -#include "Fleece.h" +#include "fleece/FLCollections.h" + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { @@ -23,50 +29,48 @@ extern "C" { /** Writes a Core Foundation (or Objective-C) object to an Encoder. Supports all the JSON types, as well as CFData. */ - bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; /** Returns a Value as a corresponding CoreFoundation object. Caller must CFRelease the result. */ - CFTypeRef FLValue_CopyCFObject(FLValue) FLAPI; + FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; /** Same as FLDictGet, but takes the key as a CFStringRef. */ - FLValue FLDict_GetWithCFString(FLDict, CFStringRef) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; #ifdef __OBJC__ -#import - // 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. */ - bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ - NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; /** Returns a Value as a corresponding (autoreleased) Foundation object. */ - id FLValue_GetNSObject(FLValue, NSMapTable *sharedStrings) FLAPI; + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; /** Same as FLDictGet, but takes the key as an NSString. */ - FLValue FLDict_GetWithNSString(FLDict, NSString*) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; /** Returns an FLDictIterator's current key as an NSString. */ - NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, - NSMapTable *sharedStrings) FLAPI; + 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. */ - NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError**) FLAPI; + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; /** NSError domain string for Fleece errors */ - extern NSString* const FLErrorDomain; + FLEECE_PUBLIC extern NSString* const FLErrorDomain; @interface NSObject (Fleece) @@ -76,8 +80,6 @@ extern "C" { a single object (which may of course be an array or dictionary.) */ - (void) fl_encodeToFLEncoder: (FLEncoder)enc; @end - - #endif /** @} */ @@ -85,3 +87,5 @@ extern "C" { #ifdef __cplusplus } #endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite-3.0.3/include/fleece/Fleece.h b/libcblite-3.0.3/include/fleece/Fleece.h index b0452f8..86ffc9f 100644 --- a/libcblite-3.0.3/include/fleece/Fleece.h +++ b/libcblite-3.0.3/include/fleece/Fleece.h @@ -14,1454 +14,23 @@ #ifndef _FLEECE_H #define _FLEECE_H -#include "FLSlice.h" -#include +// This "umbrella header" includes the commonly-used parts of the Fleece C API. -// 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 -#endif - -#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. -#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; - - - //////// DOCUMENT - - - /** @} */ - /** \defgroup reading Reading Fleece Data - @{ - \name FLDoc - @{ - An FLDoc points to (and often owns) Fleece-encoded data and provides access to its - Fleece values. - */ - -#ifndef FL_IMPL - typedef struct _FLDoc* FLDoc; ///< A reference to a document. - typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. -#endif - - /** 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; - - - /** 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. */ - FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, FLSharedKeys, FLSlice externData) FLAPI; - - /** 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. */ - FLDoc FLDoc_FromJSON(FLSlice json, FLError *outError) FLAPI; - - /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ - void FLDoc_Release(FLDoc) FLAPI; - - /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you - call FLRelease to remove the reference. */ - FLDoc FLDoc_Retain(FLDoc) FLAPI; - - /** Returns the encoded Fleece data backing the document. */ - FLSlice FLDoc_GetData(FLDoc) FLAPI FLPURE; - - /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ - FLSliceResult FLDoc_GetAllocedData(FLDoc) FLAPI FLPURE; - - /** Returns the root value in the FLDoc, usually an FLDict. */ - FLValue FLDoc_GetRoot(FLDoc) FLAPI FLPURE; - - /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ - FLSharedKeys FLDoc_GetSharedKeys(FLDoc) 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. */ - bool FLDoc_SetAssociated(FLDoc doc, void *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. */ - void* FLDoc_GetAssociated(FLDoc doc, const char *type) FLAPI FLPURE; - - /** Looks up the Doc containing the Value, or NULL if the Value was created without a Doc. - @note Caller must release the FLDoc reference!! */ - FLDoc FLValue_FindDoc(FLValue) FLAPI FLPURE; - - - /** @} */ - /** \name Parsing And Converting Values Directly - @{ */ - - /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. - The FLValue, and all values found through it, are only valid as long as the encoded data - remains intact and unchanged. */ - FLValue FLValue_FromData(FLSlice data, FLTrust) FLAPI FLPURE; - - /** Directly converts JSON data to Fleece-encoded data. - You can then call FLValue_FromData (in kFLTrusted mode) to get the root as a Value. */ - FLSliceResult FLData_ConvertJSON(FLSlice json, FLError *outError) FLAPI; - - /** Produces a human-readable dump of the Value encoded in the data. - This is only useful if you already know, or want to learn, the encoding format. */ - FLStringResult FLData_Dump(FLSlice data) FLAPI; - - - /** @} */ - /** @} */ - /** \defgroup json Converting Fleece To JSON - @{ - These are convenience functions that directly return JSON-encoded output. - For more control over the encoding, use an FLEncoder. */ - - /** Encodes a Fleece value as JSON (or a JSON fragment.) - Any Data values will become base64-encoded JSON strings. */ - FLStringResult FLValue_ToJSON(FLValue) 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. */ - FLStringResult FLValue_ToJSON5(FLValue v) FLAPI; - - /** Most general Fleece to JSON converter. */ - FLStringResult FLValue_ToJSONX(FLValue v, - bool json5, - bool canonicalForm) FLAPI; - - /** 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. */ - FLStringResult FLJSON5_ToJSON(FLString json5, - FLStringResult *outErrorMessage, - size_t *outErrorPos, - FLError *outError) FLAPI; - - /** \name Debugging Functions - @{ */ - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDump(FLValue) FLAPI; - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDumpData(FLSlice data) FLAPI; - - /** @} */ - - - //////// VALUE - - - /** @} */ - /** \defgroup FLValue Fleece Value Accessors - @{ - 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.) - - It's always safe to pass a NULL value to an accessor; that goes for FLDict and FLArray - as well as FLValue. The result will be a default value of that type, e.g. false or 0 - or NULL, unless otherwise specified. */ - - /** 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 a value created by 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 - } FLValueType; - - - /** A timestamp, 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 the data type of an arbitrary Value. - (If the parameter is a NULL pointer, returns `kFLUndefined`.) */ - FLValueType FLValue_GetType(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents an integer. */ - bool FLValue_IsInteger(FLValue) 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. */ - bool FLValue_IsUnsigned(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ - bool FLValue_IsDouble(FLValue) FLAPI; - - /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), - null, false, or zero. */ - bool FLValue_AsBool(FLValue) 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`. */ - int64_t FLValue_AsInt(FLValue) 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. */ - uint64_t FLValue_AsUnsigned(FLValue) 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. */ - float FLValue_AsFloat(FLValue) 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. */ - double FLValue_AsDouble(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a string value, or null for all other types. */ - FLString FLValue_AsString(FLValue) 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. */ - FLTimestamp FLValue_AsTimestamp(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a data value, or null for all other types. */ - FLSlice FLValue_AsData(FLValue) FLAPI FLPURE; - - /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ - FLArray FLValue_AsArray(FLValue) FLAPI FLPURE; - - /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ - FLDict FLValue_AsDict(FLValue) 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. */ - FLStringResult FLValue_ToString(FLValue) FLAPI; - - /** Compares two values for equality. This is a deep recursive comparison. */ - bool FLValue_IsEqual(FLValue v1, FLValue v2) FLAPI FLPURE; - - /** Returns true if the value is mutable. */ - bool FLValue_IsMutable(FLValue) FLAPI FLPURE; - - /** \name Ref-counting (mutable values only) - @{ */ - - /** If this value is mutable (and thus heap-based) its ref-count is incremented. - Otherwise, this call does nothing. */ - FLValue FLValue_Retain(FLValue) FLAPI; - - /** If this value is mutable (and thus heap-based) its ref-count is decremented, and if it - reaches zero the value is freed. - If the value is not mutable, this call does nothing. */ - void FLValue_Release(FLValue) FLAPI; - - static inline FLArray FLArray_Retain(FLArray v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLArray_Release(FLArray v) {FLValue_Release((FLValue)v);} - static inline FLDict FLDict_Retain(FLDict v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLDict_Release(FLDict v) {FLValue_Release((FLValue)v);} - - /** @} */ - - /** 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. */ - FLValue 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. */ - FLValue FLValue_NewData(FLSlice) FLAPI; - - /** A constant null value (not a NULL pointer!) */ - FLEECE_PUBLIC extern const FLValue kFLNullValue; - - /** A constant undefined value */ - FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; - - - //////// 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. - */ - - /** Returns the number of items in an array, or 0 if the pointer is NULL. */ - uint32_t FLArray_Count(FLArray) 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` */ - bool FLArray_IsEmpty(FLArray) FLAPI FLPURE; - - /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ - FLMutableArray FLArray_AsMutable(FLArray) FLAPI FLPURE; - - /** Returns an value at an array index, or NULL if the index is out of range. */ - FLValue FLArray_Get(FLArray, uint32_t index) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLArray kFLEmptyArray; - - /** \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 FLArrayIteratorNext. */ - void FLArrayIterator_Begin(FLArray, FLArrayIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLArrayIterator_GetValue(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Returns a value in the array at the given offset from the current value. */ - FLValue FLArrayIterator_GetValueAt(const FLArrayIterator* NONNULL, uint32_t offset) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLArrayIterator_GetCount(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLArrayIterator_Next(FLArrayIterator* NONNULL) FLAPI; - - /** @} */ - - - //////// MUTABLE ARRAY - - - /** \name Mutable Arrays - @{ */ - - typedef enum { - kFLDefaultCopy = 0, - kFLDeepCopy = 1, - kFLCopyImmutables = 2, - kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), - } FLCopyFlags; - - - /** Creates a new mutable Array that's a copy of the source Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. - - Copying an immutable Array is very cheap (only one small allocation) unless the flag - kFLCopyImmutables is set. - - Copying a mutable Array is cheap if it's a shallow copy, but if `deepCopy` is true, - nested mutable Arrays and Dicts are also copied, recursively; if kFLCopyImmutables is - also set, immutable values are also copied. - - If the source Array is NULL, then NULL is returned. */ - FLMutableArray FLArray_MutableCopy(FLArray, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_New(void) FLAPI; - - /** Creates a new mutable Array from JSON. The input json must represent a JSON array or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_NewFromJSON(FLString json, FLError* outError) FLAPI; - - /** Increments the ref-count of a mutable Array. */ - static inline FLMutableArray FLMutableArray_Retain(FLMutableArray d) { - return (FLMutableArray)FLValue_Retain((FLValue)d); - } - /** Decrements the refcount of (and possibly frees) a mutable Array. */ - static inline void FLMutableArray_Release(FLMutableArray d) { - FLValue_Release((FLValue)d); - } - - /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ - FLArray FLMutableArray_GetSource(FLMutableArray) FLAPI; - - /** Returns true if the Array has been changed from the source it was copied from. */ - bool FLMutableArray_IsChanged(FLMutableArray) FLAPI; - - /** Sets or clears the mutable Array's "changed" flag. */ - void FLMutableArray_SetChanged(FLMutableArray, bool) 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. */ - void FLMutableArray_Insert(FLMutableArray 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. */ - void FLMutableArray_Remove(FLMutableArray 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. */ - void FLMutableArray_Resize(FLMutableArray 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. */ - FLMutableArray FLMutableArray_GetMutableArray(FLMutableArray, 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. */ - FLMutableDict FLMutableArray_GetMutableDict(FLMutableArray, uint32_t index) FLAPI; - - - /// Stores a JSON null value into an array. - static inline void FLMutableArray_SetNull(FLMutableArray NONNULL, uint32_t index); - /// Stores a boolean value into an array. - static inline void FLMutableArray_SetBool(FLMutableArray NONNULL, uint32_t index, bool); - /// Stores an integer into an array. - static inline void FLMutableArray_SetInt(FLMutableArray NONNULL, 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 NONNULL, uint32_t index, uint64_t); - /// Stores a 32-bit floating-point number into an array. - static inline void FLMutableArray_SetFloat(FLMutableArray NONNULL, uint32_t index, float); - /// Stores a 64-bit floating point number into an array. - static inline void FLMutableArray_SetDouble(FLMutableArray NONNULL, uint32_t index, double); - /// Stores a UTF-8-encoded string into an array. - static inline void FLMutableArray_SetString(FLMutableArray NONNULL, uint32_t index, FLString); - /// Stores a binary data blob into an array. - static inline void FLMutableArray_SetData(FLMutableArray NONNULL, uint32_t index, FLSlice); - /// Stores a Fleece value into an array. - static inline void FLMutableArray_SetValue(FLMutableArray NONNULL, uint32_t index, FLValue); - /// Stores a Fleece array into an array - static inline void FLMutableArray_SetArray(FLMutableArray NONNULL, uint32_t index, FLArray); - /// Stores a Fleece dictionary into an array - static inline void FLMutableArray_SetDict(FLMutableArray NONNULL, uint32_t index, FLDict); - - /// Appends a JSON null value to an array. - static inline void FLMutableArray_AppendNull(FLMutableArray NONNULL); - /// Appends a boolean value to an array. - static inline void FLMutableArray_AppendBool(FLMutableArray NONNULL, bool); - /// Appends an integer to an array. - static inline void FLMutableArray_AppendInt(FLMutableArray NONNULL, 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 NONNULL, uint64_t); - /// Appends a 32-bit floating-point number to an array. - static inline void FLMutableArray_AppendFloat(FLMutableArray NONNULL, float); - /// Appends a 64-bit floating point number to an array. - static inline void FLMutableArray_AppendDouble(FLMutableArray NONNULL, double); - /// Appends a UTF-8-encoded string to an array. - static inline void FLMutableArray_AppendString(FLMutableArray NONNULL, FLString); - /// Appends a binary data blob to an array. - static inline void FLMutableArray_AppendData(FLMutableArray NONNULL, FLSlice); - /// Appends a Fleece value to an array. - static inline void FLMutableArray_AppendValue(FLMutableArray NONNULL, FLValue); - /// Appends a Fleece array to an array - static inline void FLMutableArray_AppendArray(FLMutableArray NONNULL, FLArray); - /// Appends a Fleece dictionary to an array - static inline void FLMutableArray_AppendDict(FLMutableArray NONNULL, FLDict); - - - /** @} */ - - - //////// DICT - - - /** @} */ - /** \defgroup FLDict Fleece Dictionaries - @{ */ - - /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ - uint32_t FLDict_Count(FLDict) 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` */ - bool FLDict_IsEmpty(FLDict) FLAPI FLPURE; - - /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ - FLMutableDict FLDict_AsMutable(FLDict) 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. */ - FLValue FLDict_Get(FLDict, FLSlice keyString) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLDict kFLEmptyDict; - - /** \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[4]; - int _private5; -#endif - } FLDictIterator; - - /** Initializes a FLDictIterator struct to iterate over a dictionary. - Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, - then FLDictIterator_Next. */ - void FLDictIterator_Begin(FLDict, FLDictIterator* NONNULL) FLAPI; - - /** Returns the current key being iterated over. This Value will be a string or an integer. */ - FLValue FLDictIterator_GetKey(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the current key's string value. */ - FLString FLDictIterator_GetKeyString(const FLDictIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLDictIterator_GetValue(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLDictIterator_GetCount(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDictIterator_Next(FLDictIterator* NONNULL) 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.) */ - void FLDictIterator_End(FLDictIterator* NONNULL) 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. */ - FLDictKey FLDictKey_Init(FLSlice string) FLAPI; - - /** Returns the string value of the key (which it was initialized with.) */ - FLString FLDictKey_GetString(const FLDictKey * NONNULL) 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. */ - FLValue FLDict_GetWithKey(FLDict, FLDictKey* NONNULL) FLAPI; - - - //////// 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. */ - FLMutableDict FLDict_MutableCopy(FLDict source, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Dict. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_New(void) FLAPI; - - /** Creates a new mutable Dict from json. The input JSON must represent a JSON array, or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_NewFromJSON(FLString json, FLError *outError) FLAPI; - - /** Increments the ref-count of a mutable Dict. */ - static inline FLMutableDict FLMutableDict_Retain(FLMutableDict d) { - return (FLMutableDict)FLValue_Retain((FLValue)d); - } - - /** Decrements the refcount of (and possibly frees) a mutable Dict. */ - static inline void FLMutableDict_Release(FLMutableDict d) { - FLValue_Release((FLValue)d); - } - - /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ - FLDict FLMutableDict_GetSource(FLMutableDict) FLAPI; - - /** Returns true if the Dict has been changed from the source it was copied from. */ - bool FLMutableDict_IsChanged(FLMutableDict) FLAPI; - - /** Sets or clears the mutable Dict's "changed" flag. */ - void FLMutableDict_SetChanged(FLMutableDict, bool) FLAPI; - - /** Removes the value for a key. */ - void FLMutableDict_Remove(FLMutableDict, FLString key) FLAPI; - - /** Removes all keys and values. */ - void FLMutableDict_RemoveAll(FLMutableDict) 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. */ - FLMutableArray FLMutableDict_GetMutableArray(FLMutableDict, 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. */ - FLMutableDict FLMutableDict_GetMutableDict(FLMutableDict, FLString key) FLAPI; - - - /// Stores a JSON null value into a mutable dictionary. - static inline void FLMutableDict_SetNull(FLMutableDict NONNULL, FLString key); - /// Stores a boolean value into a mutable dictionary. - static inline void FLMutableDict_SetBool(FLMutableDict NONNULL, FLString key, bool); - /// Stores an integer into a mutable dictionary. - static inline void FLMutableDict_SetInt(FLMutableDict NONNULL, 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 NONNULL, FLString key, uint64_t); - /// Stores a 32-bit floating-point number into a mutable dictionary. - static inline void FLMutableDict_SetFloat(FLMutableDict NONNULL, FLString key, float); - /// Stores a 64-bit floating point number into a mutable dictionary. - static inline void FLMutableDict_SetDouble(FLMutableDict NONNULL, FLString key, double); - /// Stores a UTF-8-encoded string into a mutable dictionary. - static inline void FLMutableDict_SetString(FLMutableDict NONNULL, FLString key, FLString); - /// Stores a binary data blob into a mutable dictionary. - static inline void FLMutableDict_SetData(FLMutableDict NONNULL, FLString key, FLSlice); - /// Stores a Fleece value into a mutable dictionary. - static inline void FLMutableDict_SetValue(FLMutableDict NONNULL, FLString key, FLValue); - /// Stores a Fleece array into a mutable dictionary. - static inline void FLMutableDict_SetArray(FLMutableDict NONNULL, FLString key, FLArray); - /// Stores a Fleece dictionary into a mutable dictionary. - static inline void FLMutableDict_SetDict(FLMutableDict NONNULL, FLString key, FLDict); - - - /** @} */ - - - //////// DEEP ITERATOR - - - /** @} */ - /** \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 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. */ - FLDeepIterator FLDeepIterator_New(FLValue) FLAPI; - - void FLDeepIterator_Free(FLDeepIterator) FLAPI; - - /** Returns the current value being iterated over. or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetValue(FLDeepIterator NONNULL) FLAPI; - - /** Returns the parent/container of the current value, or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetParent(FLDeepIterator NONNULL) FLAPI; - - /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ - FLSlice FLDeepIterator_GetKey(FLDeepIterator NONNULL) FLAPI; - - /** Returns the array index of the current value in its parent, or 0 if not in an array. */ - uint32_t FLDeepIterator_GetIndex(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ - size_t FLDeepIterator_GetDepth(FLDeepIterator NONNULL) FLAPI; - - /** Tells the iterator to skip the children of the current value. */ - void FLDeepIterator_SkipChildren(FLDeepIterator NONNULL) FLAPI; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDeepIterator_Next(FLDeepIterator NONNULL) 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. */ - void FLDeepIterator_GetPath(FLDeepIterator NONNULL, - FLPathComponent* * NONNULL outPath, - size_t* NONNULL outDepth) FLAPI; - - /** Returns the current path in JavaScript format. */ - FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current path in JSONPointer format (RFC 6901). */ - FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator NONNULL) FLAPI; - - - //////// PATH - - - /** @} */ - /** \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 '$') at the start of a - property name (but not yet in the middle of a name.) - */ - -#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. */ - FLKeyPath FLKeyPath_New(FLSlice specifier, FLError *error) FLAPI; - - /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ - void FLKeyPath_Free(FLKeyPath) FLAPI; - - /** Evaluates a compiled key-path for a given Fleece root object. */ - FLValue FLKeyPath_Eval(FLKeyPath NONNULL, 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. */ - FLValue FLKeyPath_EvalOnce(FLSlice specifier, FLValue root NONNULL, FLError *error) FLAPI; - - /** Returns a path in string form. */ - FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; - - /** Equality test. */ - bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; - - /** Returns an element of a path, either a key or an array index. */ - bool FLKeyPath_GetElement(FLKeyPath NONNULL, - size_t i, - FLSlice *outDictKey NONNULL, - int32_t *outArrayIndex NONNULL) FLAPI; - - //////// SHARED KEYS - - - /** @} */ - /** \defgroup FLSharedKeys 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. */ - FLSharedKeys FLSharedKeys_New(void) FLAPI; - - typedef bool (*FLSharedKeysReadCallback)(void *context, FLSharedKeys); - - FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, - void *context) FLAPI; - - /** Returns a data blob containing the current state (all the keys and their integers.) */ - FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys NONNULL) FLAPI; - - /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ - 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. */ - void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; - - /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by - \ref FLSharedKeys_WriteState. */ - 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. */ - int FLSharedKeys_Encode(FLSharedKeys NONNULL, FLString, bool add) FLAPI; - - /** Returns the key string that maps to the given integer `key`, else NULL. */ - FLString FLSharedKeys_Decode(FLSharedKeys NONNULL, int key) FLAPI; - - /** Returns the number of keys in the mapping. This number increases whenever the mapping - is changed, and never decreases. */ - unsigned FLSharedKeys_Count(FLSharedKeys NONNULL) FLAPI; - - /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ - void FLSharedKeys_RevertToCount(FLSharedKeys NONNULL, unsigned oldCount) FLAPI; - - /** Increments the reference count of an FLSharedKeys. */ - FLSharedKeys FLSharedKeys_Retain(FLSharedKeys) FLAPI; - - /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ - void FLSharedKeys_Release(FLSharedKeys) FLAPI; - - - typedef struct _FLSharedKeyScope* FLSharedKeyScope; - FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; - void FLSharedKeyScope_Free(FLSharedKeyScope); - - - //////// ENCODER - - - /** @} */ - /** \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. */ - 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) */ - FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, - size_t reserveSize, - bool uniqueStrings) FLAPI; - - /** Creates a new Fleece encoder that writes to a file, not to memory. */ - FLEncoder FLEncoder_NewWritingToFile(FILE* NONNULL, bool uniqueStrings) FLAPI; - - /** Frees the space used by an encoder. */ - void FLEncoder_Free(FLEncoder) FLAPI; - - /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ - void FLEncoder_SetSharedKeys(FLEncoder NONNULL, FLSharedKeys) FLAPI; - - /** Associates an arbitrary user-defined value with the encoder. */ - void FLEncoder_SetExtraInfo(FLEncoder NONNULL, void *info) FLAPI; - - /** Returns the user-defined value associated with the encoder; NULL by default. */ - void* FLEncoder_GetExtraInfo(FLEncoder NONNULL) FLAPI; - - - /** 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. */ - void FLEncoder_Amend(FLEncoder e NONNULL, FLSlice base, - bool reuseStrings, bool externPointers) FLAPI; - - /** Returns the `base` value passed to FLEncoder_Amend. */ - FLSlice FLEncoder_GetBase(FLEncoder NONNULL) 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. */ - void FLEncoder_SuppressTrailer(FLEncoder NONNULL) FLAPI; - - /** Resets the state of an encoder without freeing it. It can then be reused to encode - another value. */ - void FLEncoder_Reset(FLEncoder NONNULL) FLAPI; - - /** Returns the number of bytes encoded so far. */ - size_t FLEncoder_BytesWritten(FLEncoder NONNULL) 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.) */ - size_t FLEncoder_GetNextWritePos(FLEncoder NONNULL) 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.) */ - bool FLEncoder_WriteNull(FLEncoder NONNULL) 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. */ - bool FLEncoder_WriteUndefined(FLEncoder NONNULL) FLAPI; - - /** Writes a boolean value (true or false) to an encoder. */ - bool FLEncoder_WriteBool(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteUInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteFloat(FLEncoder NONNULL, 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.) */ - bool FLEncoder_WriteDouble(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteString(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteDateString(FLEncoder NONNULL 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. */ - bool FLEncoder_WriteData(FLEncoder NONNULL, FLSlice) FLAPI; - - /** Writes raw data directly to the encoded output. - (This is not the same as 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. */ - bool FLEncoder_WriteRaw(FLEncoder NONNULL, FLSlice) 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. */ - bool FLEncoder_BeginArray(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Ends writing an array value; pops back the previous encoding state. */ - bool FLEncoder_EndArray(FLEncoder NONNULL) 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. */ - bool FLEncoder_BeginDict(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Specifies the key for the next value to be written to the current dictionary. */ - bool FLEncoder_WriteKey(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteKeyValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - /** Ends writing a dictionary value; pops back the previous encoding state. */ - bool FLEncoder_EndDict(FLEncoder NONNULL) FLAPI; - - - /** Writes a Fleece Value to an Encoder. */ - bool FLEncoder_WriteValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - - /** Returns an opaque reference to the last complete value written to the encoder, if possible. - Fails (returning 0) 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. */ - intptr_t FLEncoder_LastValueWritten(FLEncoder e); - - /** 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. */ - void FLEncoder_WriteValueAgain(FLEncoder e, intptr_t preWrittenValue); - - - /** 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. */ - FLSliceResult FLEncoder_Snip(FLEncoder e); - - - /** Parses JSON data and writes the object(s) to the encoder. (This acts as a single write, - like WriteInt; it's just that the value written is likely to be an entire dictionary of - array.) */ - bool FLEncoder_ConvertJSON(FLEncoder NONNULL, FLSlice json) FLAPI; - - /** @} */ - /** \name Finishing up - @{ */ - - /** Finishes encoding the current item, and returns its offset in the output data. */ - size_t FLEncoder_FinishItem(FLEncoder NONNULL) FLAPI; - - /** 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. */ - FLDoc FLEncoder_FinishDoc(FLEncoder NONNULL, FLError*) 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. */ - MUST_USE_RESULT - FLSliceResult FLEncoder_Finish(FLEncoder e, FLError *outError) FLAPI; - - /** @} */ - /** \name Error handling - @{ */ - - /** Returns the error code of an encoder, or NoError (0) if there's no error. */ - FLError FLEncoder_GetError(FLEncoder NONNULL) FLAPI; - - /** Returns the error message of an encoder, or NULL if there's no error. */ - const char* FLEncoder_GetErrorMessage(FLEncoder NONNULL) FLAPI; - - /** @} */ - /** @} */ - - - //////// JSON DELTA COMPRESSION - - - /** \defgroup delta Fleece 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. */ - FLSliceResult FLCreateJSONDelta(FLValue old, FLValue 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. */ - bool FLEncodeJSONDelta(FLValue old, FLValue nuu, FLEncoder NONNULL 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 error 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. */ - FLSliceResult FLApplyJSONDelta(FLValue old, - FLSlice jsonDelta, - FLError *error) 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. */ - bool FLEncodeApplyingJSONDelta(FLValue old, - FLSlice jsonDelta, - FLEncoder encoder) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Set(FLMutableArray NONNULL, 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Append(FLMutableArray NONNULL) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableDict_Set(FLMutableDict FL_NONNULL, FLString key) FLAPI; - - - void FLSlot_SetNull(FLSlot NONNULL) FLAPI; ///< Stores a JSON null into a slot. - void FLSlot_SetBool(FLSlot NONNULL, bool) FLAPI; ///< Stores a boolean into a slot. - void FLSlot_SetInt(FLSlot NONNULL, int64_t) FLAPI; ///< Stores an integer into a slot. - void FLSlot_SetUInt(FLSlot NONNULL, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. - void FLSlot_SetFloat(FLSlot NONNULL, float) FLAPI; ///< Stores a `float` into a slot. - void FLSlot_SetDouble(FLSlot NONNULL, double) FLAPI; ///< Stores a `double` into a slot. - void FLSlot_SetString(FLSlot NONNULL, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. - void FLSlot_SetData(FLSlot NONNULL, FLSlice) FLAPI; ///< Stores a data blob into a slot. - void FLSlot_SetValue(FLSlot NONNULL, FLValue) FLAPI; ///< Stores an FLValue into a slot. - - static inline void FLSlot_SetArray(FLSlot NONNULL slot, FLArray array) { - FLSlot_SetValue(slot, (FLValue)array); - } - - static inline void FLSlot_SetDict(FLSlot NONNULL 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 +#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" + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +# include "Fleece+CoreFoundation.h" #endif #endif // _FLEECE_H diff --git a/libcblite-3.0.3/include/fleece/Fleece.hh b/libcblite-3.0.3/include/fleece/Fleece.hh new file mode 100644 index 0000000..b024464 --- /dev/null +++ b/libcblite-3.0.3/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; + 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; + + inline MutableArray asMutable() const; + + 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; + 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; + + inline MutableDict asMutable() const; + + 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;} + + inline Doc finishDoc(FLError* FL_NULLABLE =nullptr); + 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-3.0.3/include/fleece/InstanceCounted.hh b/libcblite-3.0.3/include/fleece/InstanceCounted.hh new file mode 100644 index 0000000..56c04a5 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/fleece/Mutable.hh b/libcblite-3.0.3/include/fleece/Mutable.hh new file mode 100644 index 0000000..1fb285c --- /dev/null +++ b/libcblite-3.0.3/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 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 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-3.0.3/include/fleece/PlatformCompat.hh b/libcblite-3.0.3/include/fleece/PlatformCompat.hh new file mode 100644 index 0000000..38874ea --- /dev/null +++ b/libcblite-3.0.3/include/fleece/PlatformCompat.hh @@ -0,0 +1,87 @@ +// +// 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 + #ifdef __APPLE__ + #define LITECORE_UNUSED __unused + #else + #define LITECORE_UNUSED __attribute__((unused)) + #endif + + // Disables inlining a function. Use when the space savings are worth more than speed. + #define NOINLINE __attribute((noinline)) + + // 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. + #ifndef __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-3.0.3/include/fleece/RefCounted.hh b/libcblite-3.0.3/include/fleece/RefCounted.hh new file mode 100644 index 0000000..635fb39 --- /dev/null +++ b/libcblite-3.0.3/include/fleece/RefCounted.hh @@ -0,0 +1,285 @@ +// +// 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. + 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; + } + + 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 + inline Retained retained(REFCOUNTED *r) noexcept { + return Retained(r); + } + + /** Easy instantiation of a const ref-counted object: `auto f = retained(new Foo());`*/ + template + 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 + 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 + 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 + 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 + ALWAYS_INLINE const REFCOUNTED* retain(RetainedConst &&retained) noexcept { + return std::move(retained).detach(); + } + +} diff --git a/libcblite-3.0.3/include/fleece/function_ref.hh b/libcblite-3.0.3/include/fleece/function_ref.hh new file mode 100644 index 0000000..feea300 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/include/fleece/slice.hh b/libcblite-3.0.3/include/fleece/slice.hh new file mode 100644 index 0000000..3e3797d --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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-3.0.3/lib/.DS_Store b/libcblite-3.0.3/lib/.DS_Store index bbf3927..d35da3c 100644 Binary files a/libcblite-3.0.3/lib/.DS_Store and b/libcblite-3.0.3/lib/.DS_Store differ diff --git a/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.so b/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.so index fee0199..5951fbd 100644 Binary files a/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.so and b/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.so differ diff --git a/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.stripped.so b/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.stripped.so index 52fbc79..8df2eb6 100755 Binary files a/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.stripped.so and b/libcblite-3.0.3/lib/aarch64-linux-android/libcblite.stripped.so differ diff --git a/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.so b/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.so new file mode 100644 index 0000000..d84b9b7 Binary files /dev/null and b/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.so differ diff --git a/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.stripped.so b/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.stripped.so new file mode 100755 index 0000000..6fc76ad Binary files /dev/null and b/libcblite-3.0.3/lib/arm-linux-androideabi/libcblite.stripped.so differ diff --git a/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.so b/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.so deleted file mode 100644 index 7d9418c..0000000 Binary files a/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.so and /dev/null differ diff --git a/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.stripped.so b/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.stripped.so deleted file mode 100755 index 07c79f6..0000000 Binary files a/libcblite-3.0.3/lib/armv7-linux-androideabi/libcblite.stripped.so and /dev/null differ diff --git a/libcblite-3.0.3/lib/i686-linux-android/libcblite.so b/libcblite-3.0.3/lib/i686-linux-android/libcblite.so index 9478425..2d91024 100644 Binary files a/libcblite-3.0.3/lib/i686-linux-android/libcblite.so and b/libcblite-3.0.3/lib/i686-linux-android/libcblite.so differ diff --git a/libcblite-3.0.3/lib/i686-linux-android/libcblite.stripped.so b/libcblite-3.0.3/lib/i686-linux-android/libcblite.stripped.so index 7fd297b..9a78d21 100755 Binary files a/libcblite-3.0.3/lib/i686-linux-android/libcblite.stripped.so and b/libcblite-3.0.3/lib/i686-linux-android/libcblite.stripped.so differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite index 711e988..cb54ead 100755 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h index 60e3ff8..5da21cd 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBase.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -182,6 +182,18 @@ void CBL_DumpInstances(void) CBLAPI; 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. diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h index 7173859..a2d6eaa 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLBlob.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -82,12 +81,12 @@ CBL_CAPI_BEGIN /** Returns the length in bytes of a blob's content (from its `length` property). */ uint64_t CBLBlob_Length(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 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; @@ -100,7 +99,7 @@ CBL_CAPI_BEGIN #pragma mark - READING: #endif - /** Reads the blob's contents into memory and returns them. + /** 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, @@ -251,10 +250,7 @@ CBL_CAPI_BEGIN #pragma mark - BINDING DEV SUPPORT FOR BLOB: #endif - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + /** 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 @@ -271,10 +267,7 @@ CBL_CAPI_BEGIN const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, CBLError* _cbl_nullable outError) CBLAPI; - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Save a new \ref CBLBlob object into the database without associating it with + /** 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. diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..841c811 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,467 @@ +// +// 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 + +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. + The default scope is exceptional in that it will always exists even there are no collections under it. + @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. + The default scope is exception in that it will always exists even there are no collections under it. + @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 The default scope always exist even there are no collections under it. + @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 The default collection may not exist if it was deleted. + Also, the default collection cannot be recreated after being deleted. + @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 the default collection doesn't exist or 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 scope of the collection. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return A \ref CBLScope instance. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(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; + +/** 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; + +/** @} */ + +/** \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 @@ -72,6 +71,14 @@ CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; @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 /** @} */ @@ -96,7 +103,8 @@ bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; @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.*/ + @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, @@ -213,15 +221,15 @@ bool CBLDatabase_PerformMaintenance(CBLDatabase* db, /** Returns the database's name. */ FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; -/** Returns the database's full filesystem path. */ +/** 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. */ +/** 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. - @note The encryption key is not filled in, for security reasons. */ +/** Returns the database's configuration, as given when it was opened. */ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; /** @} */ @@ -232,16 +240,17 @@ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; #endif /** \name Database listeners @{ - A database change listener lets you detect changes made to all documents in a database. + 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 database change listener callback, invoked after one or more documents are changed on disk. +/** 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. + 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) @@ -251,13 +260,13 @@ typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, unsigned numDocs, FLString docIDs[_cbl_nonnull]); -/** Registers a database change listener callback. It will be called after one or more +/** 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.*/ + @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, @@ -303,7 +312,7 @@ typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, @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 callback, + CBLNotificationsReadyCallback _cbl_nullable callback, void* _cbl_nullable context) CBLAPI; /** Immediately issues all pending notifications for this database, by calling their listener diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d115a35 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,94 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2023-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 + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +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 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; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h index 8de5976..c42809b 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLDocument.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -59,10 +58,11 @@ typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, const CBLDocument* _cbl_nullable conflictingDocument); -/** Reads a document from the database, creating a new (immutable) \ref CBLDocument object. +/** 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 @@ -75,12 +75,13 @@ const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* data CBL_REFCOUNTED(CBLDocument*, Document); -/** Saves a (mutable) document to the database. - \warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by +/** 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. - @param db The database to save to. + @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. */ @@ -88,12 +89,13 @@ bool CBLDatabase_SaveDocument(CBLDatabase* db, CBLDocument* doc, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database. +/** 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. - @param db The database to save to. + @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. @@ -103,9 +105,10 @@ bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database, allowing for custom conflict handling in the event +/** 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. - @param db The database to save to. + @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. @@ -117,9 +120,10 @@ bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, void* _cbl_nullable context, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. */ @@ -127,9 +131,10 @@ bool CBLDatabase_DeleteDocument(CBLDatabase *db, const CBLDocument* document, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. @@ -139,28 +144,29 @@ bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Purges a document. This removes all traces of the document from the database. +/** 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 containing the document. - @param document The document to delete. + @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, given only its ID. +/** 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. - */ + @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; @@ -176,9 +182,10 @@ bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, in place and then call \ref CBLDatabase_SaveDocument to persist the changes. */ -/** Reads a document from the database, in mutable form that can be updated and saved. +/** 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 @@ -237,6 +244,9 @@ FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; 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. @@ -280,6 +290,7 @@ bool CBLDocument_SetJSON(CBLDocument*, /** 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. @@ -291,6 +302,7 @@ CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, 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), @@ -318,6 +330,7 @@ bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, @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. */ @@ -327,12 +340,12 @@ typedef void (*CBLDocumentChangeListener)(void *context, /** 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.*/ + @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, diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h index abe532b..4665b9a 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -18,7 +18,6 @@ #pragma once #include -#include #ifdef COUCHBASE_ENTERPRISE diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h index 1530c74..6298efa 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLLog.h @@ -115,11 +115,21 @@ void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; @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 - FLString directory; ///< The directory where log files will be created. - uint32_t maxRotateCount; ///< Max number of older log files to keep (in addition to current one.) - size_t maxSize; ///< The size in bytes at which a file will be rotated out (best effort). - bool usePlaintext; ///< Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + 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. */ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h index d672fc5..a4e10f1 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLQuery.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -103,7 +102,6 @@ CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, 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; @@ -276,7 +274,8 @@ typedef struct { /** 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. */ + 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, @@ -285,15 +284,16 @@ bool CBLDatabase_CreateValueIndex(CBLDatabase *db, /** Full-Text Index Configuration. */ typedef struct { - /** The language used in the expressions. */ + /** 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. */ + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ FLString expressions; /** Should diacritical marks (accents) be ignored? - Defaults to false. Generally this should be left `false` for non-English text. */ + 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. @@ -313,19 +313,22 @@ typedef struct { /** 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. */ + 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. */ +/** 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. */ + @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; diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h index 41eaf41..9d2a627 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -151,6 +150,74 @@ typedef struct { #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. @@ -172,8 +239,10 @@ typedef struct { 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 (*CBLPropertyEncryptor) ( +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 @@ -184,8 +253,8 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( ); /** 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. + 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 : @@ -206,8 +275,10 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( @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 (*CBLPropertyDecryptor) ( +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 @@ -219,50 +290,144 @@ typedef FLSliceResult (*CBLPropertyDecryptor) ( #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 { - CBLDatabase* database; ///< The database to replicate - CBLEndpoint* endpoint; ///< The address of the other database to replicate with - CBLReplicatorType replicatorType; ///< Push, pull or both - bool continuous; ///< Continuous replication? + /** 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. - - IMPORTANT: For performance reasons, the document listeners must be added *before* the replicator is started - or they will not receive the events. + + /** 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; + bool disableAutoPurge; + //-- Retry Logic: - unsigned maxAttempts; ///< 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 maxAttemptWaitTime; ///< Max wait time between retry attempts in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 kCBLDefaultReplicatorMaxAttemptWaitTime. */ + unsigned maxAttemptWaitTime; + //-- WebSocket: - unsigned heartbeat; ///< The heartbeat interval in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 + + 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: - FLSlice pinnedServerCertificate; ///< An X.509 cert to "pin" TLS connections to (PEM or DER) - FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + /** 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: - FLArray _cbl_nullable channels; ///< Optional set of channels to pull from - FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate - CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed - CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs - CBLConflictResolver _cbl_nullable conflictResolver;///< Optional conflict-resolver callback - void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + + /** 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 - CBLPropertyEncryptor _cbl_nullable propertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. - CBLPropertyDecryptor _cbl_nullable propertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. + /** 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; + + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. #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 @@ -271,11 +436,12 @@ typedef struct { 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. */ + 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; + /** @} */ @@ -325,7 +491,6 @@ void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; /** @} */ - /** \name Status and Progress @{ */ @@ -344,7 +509,7 @@ typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { 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; /// Very-approximate fractional completion, from 0.0 to 1.0 + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ _cbl_warn_unused -FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, - CBLError* _cbl_nullable outError) CBLAPI; +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; -/** Indicates whether the document with the given ID has local changes that have not yet been - pushed to the server by this replicator. +/** 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. */ + @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. - @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. + @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. */ @@ -399,7 +593,7 @@ typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, CBLReplicator *replicator, const CBLReplicatorStatus *status); -/** Adds a listener that will be called when the replicator's status changes. */ +/** Registers a listener that will be called when the replicator's status changes. */ _cbl_warn_unused CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, CBLReplicatorChangeListener, @@ -408,15 +602,17 @@ CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, /** 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 + 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; + +/** @} */ + +/** \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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h index 26a2773..0612778 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -35,11 +35,9 @@ #define CBLINLINE __forceinline #define _cbl_nonnull _In_ #define _cbl_warn_unused _Check_return_ - #define _cbl_deprecated #else #define CBLINLINE inline #define _cbl_warn_unused __attribute__((warn_unused_result)) - #define _cbl_deprecated __attribute__((deprecated())) #endif // Macros for defining typed enumerations and option flags. @@ -48,6 +46,14 @@ // 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 @@ -57,11 +63,11 @@ #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) enum _name : _type _name; enum _name : _type + #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 : _type + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type #else - #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type + #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 diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h index ea92b65..0388d74 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -20,8 +20,8 @@ #define COUCHBASE_ENTERPRISE #endif -#define CBLITE_VERSION "3.0.17" -#define CBLITE_VERSION_NUMBER 3000017 -#define CBLITE_BUILD_NUMBER 1 -#define CBLITE_SOURCE_ID "3becb76+fd69ae2" -#define CBLITE_BUILD_TIMESTAMP "2023-12-15T19:48:34Z" +#define CBLITE_VERSION "3.1.7" +#define CBLITE_VERSION_NUMBER 3001007 +#define CBLITE_BUILD_NUMBER 5 +#define CBLITE_SOURCE_ID "036da58+b89b125" +#define CBLITE_BUILD_TIMESTAMP "2024-04-23T18:55:12Z" diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Base.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h similarity index 82% rename from libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Base.h rename to libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h index fab3644..8098543 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Base.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -1,5 +1,5 @@ // -// Base.h +// CompilerSupport.h // // Copyright 2018-Present Couchbase, Inc. // @@ -11,8 +11,8 @@ // #pragma once -#ifndef FLEECE_BASE_H -#define FLEECE_BASE_H +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H // The __has_xxx() macros are only(?) implemented by Clang. (Except GCC has __has_attribute...) // Define them to return 0 on other compilers. @@ -57,11 +57,32 @@ #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. #ifdef __clang__ #define NONNULL __attribute__((nonnull)) #else @@ -204,7 +225,28 @@ #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_BASE_H +#else // _FLEECE_COMPILER_SUPPORT_H #warn "Compiler is not honoring #pragma once" #endif diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h index 92ccd2b..6802407 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -19,10 +19,13 @@ #pragma once #include #include +#include #include +#include #include #include #include #include #include #include +#include diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLBase.h new file mode 100644 index 0000000..5b57154 --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..f621c6b --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,220 @@ +// +// 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. */ + 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 FLArrayIteratorNext. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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 FLDictIterator_Next. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDeepIterator.h new file mode 100644 index 0000000..d1699bf --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..c2f631b --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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!! */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7aa1368 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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) */ + 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. */ + 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. */ + MUST_USE_RESULT + 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. */ + MUST_USE_RESULT + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..b52b77c --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,303 @@ +// +// 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 + @{ */ + + + /** \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. */ + 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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + 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.) */ + FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ + 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. */ + 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; + + /** Increments the reference count of an FLSharedKeys. */ + 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. */ + 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. */ + 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. */ + 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; + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning 0) 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. */ + FLEECE_PUBLIC void 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. */ + FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..5dbc78c --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..b448d77 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,85 @@ +// +// 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 '$') at the start of a + property name (but not yet in the middle of a name.) + */ + +#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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..7aea9f5 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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. */ + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h index 44f4298..2850115 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLSlice.h @@ -16,7 +16,7 @@ #ifndef _FLSLICE_H #define _FLSLICE_H -#include +#include #include #include #include @@ -25,13 +25,12 @@ #ifdef __cplusplus #include - #define FLAPI noexcept namespace fleece { struct alloc_slice; } -#else - #define FLAPI #endif +FL_ASSUME_NONNULL_BEGIN + #ifdef __cplusplus extern "C" { #endif @@ -44,7 +43,7 @@ extern "C" { /** 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 *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -62,7 +61,7 @@ typedef struct FLSlice { adopt the reference, and release it in its destructor. For example: `alloc_slice foo( CopyFoo() );` */ typedef struct FLSliceResult { - const void *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -80,7 +79,7 @@ typedef struct FLSliceResult { struct FLHeapSlice : public FLSlice { constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } private: - constexpr FLHeapSlice(const void *b, size_t s) noexcept :FLSlice{b, s} { } + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } friend struct fleece::alloc_slice; }; #else @@ -103,7 +102,9 @@ typedef FLSliceResult FLStringResult; /** 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 *a, const void *b, size_t size) FLAPI { +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); @@ -111,7 +112,7 @@ static inline FLPURE int FLMemCmp(const void *a, const void *b, size_t size) FLA /** 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 *dst, const void *src, size_t size) FLAPI { +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); } @@ -121,7 +122,7 @@ static inline void FLMemCpy(void *dst, const void *src, size_t size) FLAPI { 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 *str) FLAPI { +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { FLSlice foo = { str, str ? strlen(str) : 0 }; return foo; } @@ -136,14 +137,14 @@ static inline FLSlice FLStr(const char *str) FLAPI { /** Equality test of two slices. */ -bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; +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. */ -int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; +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. */ -uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; +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 @@ -152,24 +153,24 @@ uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; @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. */ -bool FLSlice_ToCString(FLSlice s, char* buffer NONNULL, size_t capacity) FLAPI; +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; /** Allocates an FLSliceResult of the given size, without initializing the buffer. */ -FLSliceResult FLSliceResult_New(size_t) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; /** Allocates an FLSliceResult, copying the given slice. */ -FLSliceResult FLSlice_Copy(FLSlice) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; /** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ -static inline FLSliceResult FLSliceResult_CreateWith(const void *bytes, size_t size) FLAPI { +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { FLSlice s = {bytes, size}; return FLSlice_Copy(s); } -void _FLBuf_Retain(const void*) FLAPI; // internal; do not call -void _FLBuf_Release(const void*) FLAPI; // internal; do not call +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 { @@ -184,14 +185,16 @@ static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { /** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { - return *(FLSlice*)&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. */ -void FL_WipeMemory(void *dst, size_t size) FLAPI; +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; /** @} */ @@ -213,4 +216,5 @@ void FL_WipeMemory(void *dst, size_t size) FLAPI; } #endif +FL_ASSUME_NONNULL_END #endif // _FLSLICE_H diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/FLValue.h new file mode 100644 index 0000000..874172f --- /dev/null +++ b/libcblite-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h index c5a0d32..585c528 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -12,7 +12,13 @@ #pragma once #include -#include "Fleece.h" +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { @@ -23,50 +29,48 @@ extern "C" { /** Writes a Core Foundation (or Objective-C) object to an Encoder. Supports all the JSON types, as well as CFData. */ - bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; /** Returns a Value as a corresponding CoreFoundation object. Caller must CFRelease the result. */ - CFTypeRef FLValue_CopyCFObject(FLValue) FLAPI; + FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; /** Same as FLDictGet, but takes the key as a CFStringRef. */ - FLValue FLDict_GetWithCFString(FLDict, CFStringRef) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; #ifdef __OBJC__ -#import - // 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. */ - bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ - NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; /** Returns a Value as a corresponding (autoreleased) Foundation object. */ - id FLValue_GetNSObject(FLValue, NSMapTable *sharedStrings) FLAPI; + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; /** Same as FLDictGet, but takes the key as an NSString. */ - FLValue FLDict_GetWithNSString(FLDict, NSString*) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; /** Returns an FLDictIterator's current key as an NSString. */ - NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, - NSMapTable *sharedStrings) FLAPI; + 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. */ - NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError**) FLAPI; + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; /** NSError domain string for Fleece errors */ - extern NSString* const FLErrorDomain; + FLEECE_PUBLIC extern NSString* const FLErrorDomain; @interface NSObject (Fleece) @@ -76,8 +80,6 @@ extern "C" { a single object (which may of course be an array or dictionary.) */ - (void) fl_encodeToFLEncoder: (FLEncoder)enc; @end - - #endif /** @} */ @@ -85,3 +87,5 @@ extern "C" { #ifdef __cplusplus } #endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h index 69655ff..6476347 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Headers/Fleece.h @@ -14,1454 +14,23 @@ #ifndef _FLEECE_H #define _FLEECE_H -#include -#include +// This "umbrella header" includes the commonly-used parts of the Fleece C API. -// 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 -#endif - -#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. -#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; - - - //////// DOCUMENT - - - /** @} */ - /** \defgroup reading Reading Fleece Data - @{ - \name FLDoc - @{ - An FLDoc points to (and often owns) Fleece-encoded data and provides access to its - Fleece values. - */ - -#ifndef FL_IMPL - typedef struct _FLDoc* FLDoc; ///< A reference to a document. - typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. -#endif - - /** 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; - - - /** 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. */ - FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, FLSharedKeys, FLSlice externData) FLAPI; - - /** 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. */ - FLDoc FLDoc_FromJSON(FLSlice json, FLError *outError) FLAPI; - - /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ - void FLDoc_Release(FLDoc) FLAPI; - - /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you - call FLRelease to remove the reference. */ - FLDoc FLDoc_Retain(FLDoc) FLAPI; - - /** Returns the encoded Fleece data backing the document. */ - FLSlice FLDoc_GetData(FLDoc) FLAPI FLPURE; - - /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ - FLSliceResult FLDoc_GetAllocedData(FLDoc) FLAPI FLPURE; - - /** Returns the root value in the FLDoc, usually an FLDict. */ - FLValue FLDoc_GetRoot(FLDoc) FLAPI FLPURE; - - /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ - FLSharedKeys FLDoc_GetSharedKeys(FLDoc) 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. */ - bool FLDoc_SetAssociated(FLDoc doc, void *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. */ - void* FLDoc_GetAssociated(FLDoc doc, const char *type) FLAPI FLPURE; - - /** Looks up the Doc containing the Value, or NULL if the Value was created without a Doc. - @note Caller must release the FLDoc reference!! */ - FLDoc FLValue_FindDoc(FLValue) FLAPI FLPURE; - - - /** @} */ - /** \name Parsing And Converting Values Directly - @{ */ - - /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. - The FLValue, and all values found through it, are only valid as long as the encoded data - remains intact and unchanged. */ - FLValue FLValue_FromData(FLSlice data, FLTrust) FLAPI FLPURE; - - /** Directly converts JSON data to Fleece-encoded data. - You can then call FLValue_FromData (in kFLTrusted mode) to get the root as a Value. */ - FLSliceResult FLData_ConvertJSON(FLSlice json, FLError *outError) FLAPI; - - /** Produces a human-readable dump of the Value encoded in the data. - This is only useful if you already know, or want to learn, the encoding format. */ - FLStringResult FLData_Dump(FLSlice data) FLAPI; - - - /** @} */ - /** @} */ - /** \defgroup json Converting Fleece To JSON - @{ - These are convenience functions that directly return JSON-encoded output. - For more control over the encoding, use an FLEncoder. */ - - /** Encodes a Fleece value as JSON (or a JSON fragment.) - Any Data values will become base64-encoded JSON strings. */ - FLStringResult FLValue_ToJSON(FLValue) 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. */ - FLStringResult FLValue_ToJSON5(FLValue v) FLAPI; - - /** Most general Fleece to JSON converter. */ - FLStringResult FLValue_ToJSONX(FLValue v, - bool json5, - bool canonicalForm) FLAPI; - - /** 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. */ - FLStringResult FLJSON5_ToJSON(FLString json5, - FLStringResult *outErrorMessage, - size_t *outErrorPos, - FLError *outError) FLAPI; - - /** \name Debugging Functions - @{ */ - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDump(FLValue) FLAPI; - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDumpData(FLSlice data) FLAPI; - - /** @} */ - - - //////// VALUE - - - /** @} */ - /** \defgroup FLValue Fleece Value Accessors - @{ - 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.) - - It's always safe to pass a NULL value to an accessor; that goes for FLDict and FLArray - as well as FLValue. The result will be a default value of that type, e.g. false or 0 - or NULL, unless otherwise specified. */ - - /** 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 a value created by 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 - } FLValueType; - - - /** A timestamp, 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 the data type of an arbitrary Value. - (If the parameter is a NULL pointer, returns `kFLUndefined`.) */ - FLValueType FLValue_GetType(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents an integer. */ - bool FLValue_IsInteger(FLValue) 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. */ - bool FLValue_IsUnsigned(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ - bool FLValue_IsDouble(FLValue) FLAPI; - - /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), - null, false, or zero. */ - bool FLValue_AsBool(FLValue) 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`. */ - int64_t FLValue_AsInt(FLValue) 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. */ - uint64_t FLValue_AsUnsigned(FLValue) 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. */ - float FLValue_AsFloat(FLValue) 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. */ - double FLValue_AsDouble(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a string value, or null for all other types. */ - FLString FLValue_AsString(FLValue) 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. */ - FLTimestamp FLValue_AsTimestamp(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a data value, or null for all other types. */ - FLSlice FLValue_AsData(FLValue) FLAPI FLPURE; - - /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ - FLArray FLValue_AsArray(FLValue) FLAPI FLPURE; - - /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ - FLDict FLValue_AsDict(FLValue) 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. */ - FLStringResult FLValue_ToString(FLValue) FLAPI; - - /** Compares two values for equality. This is a deep recursive comparison. */ - bool FLValue_IsEqual(FLValue v1, FLValue v2) FLAPI FLPURE; - - /** Returns true if the value is mutable. */ - bool FLValue_IsMutable(FLValue) FLAPI FLPURE; - - /** \name Ref-counting (mutable values only) - @{ */ - - /** If this value is mutable (and thus heap-based) its ref-count is incremented. - Otherwise, this call does nothing. */ - FLValue FLValue_Retain(FLValue) FLAPI; - - /** If this value is mutable (and thus heap-based) its ref-count is decremented, and if it - reaches zero the value is freed. - If the value is not mutable, this call does nothing. */ - void FLValue_Release(FLValue) FLAPI; - - static inline FLArray FLArray_Retain(FLArray v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLArray_Release(FLArray v) {FLValue_Release((FLValue)v);} - static inline FLDict FLDict_Retain(FLDict v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLDict_Release(FLDict v) {FLValue_Release((FLValue)v);} - - /** @} */ - - /** 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. */ - FLValue 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. */ - FLValue FLValue_NewData(FLSlice) FLAPI; - - /** A constant null value (not a NULL pointer!) */ - FLEECE_PUBLIC extern const FLValue kFLNullValue; - - /** A constant undefined value */ - FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; - - - //////// 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. - */ - - /** Returns the number of items in an array, or 0 if the pointer is NULL. */ - uint32_t FLArray_Count(FLArray) 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` */ - bool FLArray_IsEmpty(FLArray) FLAPI FLPURE; - - /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ - FLMutableArray FLArray_AsMutable(FLArray) FLAPI FLPURE; - - /** Returns an value at an array index, or NULL if the index is out of range. */ - FLValue FLArray_Get(FLArray, uint32_t index) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLArray kFLEmptyArray; - - /** \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 FLArrayIteratorNext. */ - void FLArrayIterator_Begin(FLArray, FLArrayIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLArrayIterator_GetValue(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Returns a value in the array at the given offset from the current value. */ - FLValue FLArrayIterator_GetValueAt(const FLArrayIterator* NONNULL, uint32_t offset) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLArrayIterator_GetCount(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLArrayIterator_Next(FLArrayIterator* NONNULL) FLAPI; - - /** @} */ - - - //////// MUTABLE ARRAY - - - /** \name Mutable Arrays - @{ */ - - typedef enum { - kFLDefaultCopy = 0, - kFLDeepCopy = 1, - kFLCopyImmutables = 2, - kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), - } FLCopyFlags; - - - /** Creates a new mutable Array that's a copy of the source Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. - - Copying an immutable Array is very cheap (only one small allocation) unless the flag - kFLCopyImmutables is set. - - Copying a mutable Array is cheap if it's a shallow copy, but if `deepCopy` is true, - nested mutable Arrays and Dicts are also copied, recursively; if kFLCopyImmutables is - also set, immutable values are also copied. - - If the source Array is NULL, then NULL is returned. */ - FLMutableArray FLArray_MutableCopy(FLArray, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_New(void) FLAPI; - - /** Creates a new mutable Array from JSON. The input json must represent a JSON array or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_NewFromJSON(FLString json, FLError* outError) FLAPI; - - /** Increments the ref-count of a mutable Array. */ - static inline FLMutableArray FLMutableArray_Retain(FLMutableArray d) { - return (FLMutableArray)FLValue_Retain((FLValue)d); - } - /** Decrements the refcount of (and possibly frees) a mutable Array. */ - static inline void FLMutableArray_Release(FLMutableArray d) { - FLValue_Release((FLValue)d); - } - - /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ - FLArray FLMutableArray_GetSource(FLMutableArray) FLAPI; - - /** Returns true if the Array has been changed from the source it was copied from. */ - bool FLMutableArray_IsChanged(FLMutableArray) FLAPI; - - /** Sets or clears the mutable Array's "changed" flag. */ - void FLMutableArray_SetChanged(FLMutableArray, bool) 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. */ - void FLMutableArray_Insert(FLMutableArray 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. */ - void FLMutableArray_Remove(FLMutableArray 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. */ - void FLMutableArray_Resize(FLMutableArray 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. */ - FLMutableArray FLMutableArray_GetMutableArray(FLMutableArray, 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. */ - FLMutableDict FLMutableArray_GetMutableDict(FLMutableArray, uint32_t index) FLAPI; - - - /// Stores a JSON null value into an array. - static inline void FLMutableArray_SetNull(FLMutableArray NONNULL, uint32_t index); - /// Stores a boolean value into an array. - static inline void FLMutableArray_SetBool(FLMutableArray NONNULL, uint32_t index, bool); - /// Stores an integer into an array. - static inline void FLMutableArray_SetInt(FLMutableArray NONNULL, 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 NONNULL, uint32_t index, uint64_t); - /// Stores a 32-bit floating-point number into an array. - static inline void FLMutableArray_SetFloat(FLMutableArray NONNULL, uint32_t index, float); - /// Stores a 64-bit floating point number into an array. - static inline void FLMutableArray_SetDouble(FLMutableArray NONNULL, uint32_t index, double); - /// Stores a UTF-8-encoded string into an array. - static inline void FLMutableArray_SetString(FLMutableArray NONNULL, uint32_t index, FLString); - /// Stores a binary data blob into an array. - static inline void FLMutableArray_SetData(FLMutableArray NONNULL, uint32_t index, FLSlice); - /// Stores a Fleece value into an array. - static inline void FLMutableArray_SetValue(FLMutableArray NONNULL, uint32_t index, FLValue); - /// Stores a Fleece array into an array - static inline void FLMutableArray_SetArray(FLMutableArray NONNULL, uint32_t index, FLArray); - /// Stores a Fleece dictionary into an array - static inline void FLMutableArray_SetDict(FLMutableArray NONNULL, uint32_t index, FLDict); - - /// Appends a JSON null value to an array. - static inline void FLMutableArray_AppendNull(FLMutableArray NONNULL); - /// Appends a boolean value to an array. - static inline void FLMutableArray_AppendBool(FLMutableArray NONNULL, bool); - /// Appends an integer to an array. - static inline void FLMutableArray_AppendInt(FLMutableArray NONNULL, 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 NONNULL, uint64_t); - /// Appends a 32-bit floating-point number to an array. - static inline void FLMutableArray_AppendFloat(FLMutableArray NONNULL, float); - /// Appends a 64-bit floating point number to an array. - static inline void FLMutableArray_AppendDouble(FLMutableArray NONNULL, double); - /// Appends a UTF-8-encoded string to an array. - static inline void FLMutableArray_AppendString(FLMutableArray NONNULL, FLString); - /// Appends a binary data blob to an array. - static inline void FLMutableArray_AppendData(FLMutableArray NONNULL, FLSlice); - /// Appends a Fleece value to an array. - static inline void FLMutableArray_AppendValue(FLMutableArray NONNULL, FLValue); - /// Appends a Fleece array to an array - static inline void FLMutableArray_AppendArray(FLMutableArray NONNULL, FLArray); - /// Appends a Fleece dictionary to an array - static inline void FLMutableArray_AppendDict(FLMutableArray NONNULL, FLDict); - - - /** @} */ - - - //////// DICT - - - /** @} */ - /** \defgroup FLDict Fleece Dictionaries - @{ */ - - /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ - uint32_t FLDict_Count(FLDict) 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` */ - bool FLDict_IsEmpty(FLDict) FLAPI FLPURE; - - /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ - FLMutableDict FLDict_AsMutable(FLDict) 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. */ - FLValue FLDict_Get(FLDict, FLSlice keyString) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLDict kFLEmptyDict; - - /** \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[4]; - int _private5; -#endif - } FLDictIterator; - - /** Initializes a FLDictIterator struct to iterate over a dictionary. - Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, - then FLDictIterator_Next. */ - void FLDictIterator_Begin(FLDict, FLDictIterator* NONNULL) FLAPI; - - /** Returns the current key being iterated over. This Value will be a string or an integer. */ - FLValue FLDictIterator_GetKey(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the current key's string value. */ - FLString FLDictIterator_GetKeyString(const FLDictIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLDictIterator_GetValue(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLDictIterator_GetCount(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDictIterator_Next(FLDictIterator* NONNULL) 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.) */ - void FLDictIterator_End(FLDictIterator* NONNULL) 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. */ - FLDictKey FLDictKey_Init(FLSlice string) FLAPI; - - /** Returns the string value of the key (which it was initialized with.) */ - FLString FLDictKey_GetString(const FLDictKey * NONNULL) 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. */ - FLValue FLDict_GetWithKey(FLDict, FLDictKey* NONNULL) FLAPI; - - - //////// 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. */ - FLMutableDict FLDict_MutableCopy(FLDict source, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Dict. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_New(void) FLAPI; - - /** Creates a new mutable Dict from json. The input JSON must represent a JSON array, or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_NewFromJSON(FLString json, FLError *outError) FLAPI; - - /** Increments the ref-count of a mutable Dict. */ - static inline FLMutableDict FLMutableDict_Retain(FLMutableDict d) { - return (FLMutableDict)FLValue_Retain((FLValue)d); - } - - /** Decrements the refcount of (and possibly frees) a mutable Dict. */ - static inline void FLMutableDict_Release(FLMutableDict d) { - FLValue_Release((FLValue)d); - } - - /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ - FLDict FLMutableDict_GetSource(FLMutableDict) FLAPI; - - /** Returns true if the Dict has been changed from the source it was copied from. */ - bool FLMutableDict_IsChanged(FLMutableDict) FLAPI; - - /** Sets or clears the mutable Dict's "changed" flag. */ - void FLMutableDict_SetChanged(FLMutableDict, bool) FLAPI; - - /** Removes the value for a key. */ - void FLMutableDict_Remove(FLMutableDict, FLString key) FLAPI; - - /** Removes all keys and values. */ - void FLMutableDict_RemoveAll(FLMutableDict) 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. */ - FLMutableArray FLMutableDict_GetMutableArray(FLMutableDict, 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. */ - FLMutableDict FLMutableDict_GetMutableDict(FLMutableDict, FLString key) FLAPI; - - - /// Stores a JSON null value into a mutable dictionary. - static inline void FLMutableDict_SetNull(FLMutableDict NONNULL, FLString key); - /// Stores a boolean value into a mutable dictionary. - static inline void FLMutableDict_SetBool(FLMutableDict NONNULL, FLString key, bool); - /// Stores an integer into a mutable dictionary. - static inline void FLMutableDict_SetInt(FLMutableDict NONNULL, 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 NONNULL, FLString key, uint64_t); - /// Stores a 32-bit floating-point number into a mutable dictionary. - static inline void FLMutableDict_SetFloat(FLMutableDict NONNULL, FLString key, float); - /// Stores a 64-bit floating point number into a mutable dictionary. - static inline void FLMutableDict_SetDouble(FLMutableDict NONNULL, FLString key, double); - /// Stores a UTF-8-encoded string into a mutable dictionary. - static inline void FLMutableDict_SetString(FLMutableDict NONNULL, FLString key, FLString); - /// Stores a binary data blob into a mutable dictionary. - static inline void FLMutableDict_SetData(FLMutableDict NONNULL, FLString key, FLSlice); - /// Stores a Fleece value into a mutable dictionary. - static inline void FLMutableDict_SetValue(FLMutableDict NONNULL, FLString key, FLValue); - /// Stores a Fleece array into a mutable dictionary. - static inline void FLMutableDict_SetArray(FLMutableDict NONNULL, FLString key, FLArray); - /// Stores a Fleece dictionary into a mutable dictionary. - static inline void FLMutableDict_SetDict(FLMutableDict NONNULL, FLString key, FLDict); - - - /** @} */ - - - //////// DEEP ITERATOR - - - /** @} */ - /** \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 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. */ - FLDeepIterator FLDeepIterator_New(FLValue) FLAPI; - - void FLDeepIterator_Free(FLDeepIterator) FLAPI; - - /** Returns the current value being iterated over. or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetValue(FLDeepIterator NONNULL) FLAPI; - - /** Returns the parent/container of the current value, or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetParent(FLDeepIterator NONNULL) FLAPI; - - /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ - FLSlice FLDeepIterator_GetKey(FLDeepIterator NONNULL) FLAPI; - - /** Returns the array index of the current value in its parent, or 0 if not in an array. */ - uint32_t FLDeepIterator_GetIndex(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ - size_t FLDeepIterator_GetDepth(FLDeepIterator NONNULL) FLAPI; - - /** Tells the iterator to skip the children of the current value. */ - void FLDeepIterator_SkipChildren(FLDeepIterator NONNULL) FLAPI; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDeepIterator_Next(FLDeepIterator NONNULL) 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. */ - void FLDeepIterator_GetPath(FLDeepIterator NONNULL, - FLPathComponent* * NONNULL outPath, - size_t* NONNULL outDepth) FLAPI; - - /** Returns the current path in JavaScript format. */ - FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current path in JSONPointer format (RFC 6901). */ - FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator NONNULL) FLAPI; - - - //////// PATH - - - /** @} */ - /** \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 '$') at the start of a - property name (but not yet in the middle of a name.) - */ - -#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. */ - FLKeyPath FLKeyPath_New(FLSlice specifier, FLError *error) FLAPI; - - /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ - void FLKeyPath_Free(FLKeyPath) FLAPI; - - /** Evaluates a compiled key-path for a given Fleece root object. */ - FLValue FLKeyPath_Eval(FLKeyPath NONNULL, 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. */ - FLValue FLKeyPath_EvalOnce(FLSlice specifier, FLValue root NONNULL, FLError *error) FLAPI; - - /** Returns a path in string form. */ - FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; - - /** Equality test. */ - bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; - - /** Returns an element of a path, either a key or an array index. */ - bool FLKeyPath_GetElement(FLKeyPath NONNULL, - size_t i, - FLSlice *outDictKey NONNULL, - int32_t *outArrayIndex NONNULL) FLAPI; - - //////// SHARED KEYS - - - /** @} */ - /** \defgroup FLSharedKeys 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. */ - FLSharedKeys FLSharedKeys_New(void) FLAPI; - - typedef bool (*FLSharedKeysReadCallback)(void *context, FLSharedKeys); - - FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, - void *context) FLAPI; - - /** Returns a data blob containing the current state (all the keys and their integers.) */ - FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys NONNULL) FLAPI; - - /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ - 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. */ - void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; - - /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by - \ref FLSharedKeys_WriteState. */ - 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. */ - int FLSharedKeys_Encode(FLSharedKeys NONNULL, FLString, bool add) FLAPI; - - /** Returns the key string that maps to the given integer `key`, else NULL. */ - FLString FLSharedKeys_Decode(FLSharedKeys NONNULL, int key) FLAPI; - - /** Returns the number of keys in the mapping. This number increases whenever the mapping - is changed, and never decreases. */ - unsigned FLSharedKeys_Count(FLSharedKeys NONNULL) FLAPI; - - /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ - void FLSharedKeys_RevertToCount(FLSharedKeys NONNULL, unsigned oldCount) FLAPI; - - /** Increments the reference count of an FLSharedKeys. */ - FLSharedKeys FLSharedKeys_Retain(FLSharedKeys) FLAPI; - - /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ - void FLSharedKeys_Release(FLSharedKeys) FLAPI; - - - typedef struct _FLSharedKeyScope* FLSharedKeyScope; - FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; - void FLSharedKeyScope_Free(FLSharedKeyScope); - - - //////// ENCODER - - - /** @} */ - /** \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. */ - 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) */ - FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, - size_t reserveSize, - bool uniqueStrings) FLAPI; - - /** Creates a new Fleece encoder that writes to a file, not to memory. */ - FLEncoder FLEncoder_NewWritingToFile(FILE* NONNULL, bool uniqueStrings) FLAPI; - - /** Frees the space used by an encoder. */ - void FLEncoder_Free(FLEncoder) FLAPI; - - /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ - void FLEncoder_SetSharedKeys(FLEncoder NONNULL, FLSharedKeys) FLAPI; - - /** Associates an arbitrary user-defined value with the encoder. */ - void FLEncoder_SetExtraInfo(FLEncoder NONNULL, void *info) FLAPI; - - /** Returns the user-defined value associated with the encoder; NULL by default. */ - void* FLEncoder_GetExtraInfo(FLEncoder NONNULL) FLAPI; - - - /** 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. */ - void FLEncoder_Amend(FLEncoder e NONNULL, FLSlice base, - bool reuseStrings, bool externPointers) FLAPI; - - /** Returns the `base` value passed to FLEncoder_Amend. */ - FLSlice FLEncoder_GetBase(FLEncoder NONNULL) 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. */ - void FLEncoder_SuppressTrailer(FLEncoder NONNULL) FLAPI; - - /** Resets the state of an encoder without freeing it. It can then be reused to encode - another value. */ - void FLEncoder_Reset(FLEncoder NONNULL) FLAPI; - - /** Returns the number of bytes encoded so far. */ - size_t FLEncoder_BytesWritten(FLEncoder NONNULL) 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.) */ - size_t FLEncoder_GetNextWritePos(FLEncoder NONNULL) 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.) */ - bool FLEncoder_WriteNull(FLEncoder NONNULL) 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. */ - bool FLEncoder_WriteUndefined(FLEncoder NONNULL) FLAPI; - - /** Writes a boolean value (true or false) to an encoder. */ - bool FLEncoder_WriteBool(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteUInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteFloat(FLEncoder NONNULL, 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.) */ - bool FLEncoder_WriteDouble(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteString(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteDateString(FLEncoder NONNULL 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. */ - bool FLEncoder_WriteData(FLEncoder NONNULL, FLSlice) FLAPI; - - /** Writes raw data directly to the encoded output. - (This is not the same as 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. */ - bool FLEncoder_WriteRaw(FLEncoder NONNULL, FLSlice) 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. */ - bool FLEncoder_BeginArray(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Ends writing an array value; pops back the previous encoding state. */ - bool FLEncoder_EndArray(FLEncoder NONNULL) 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. */ - bool FLEncoder_BeginDict(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Specifies the key for the next value to be written to the current dictionary. */ - bool FLEncoder_WriteKey(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteKeyValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - /** Ends writing a dictionary value; pops back the previous encoding state. */ - bool FLEncoder_EndDict(FLEncoder NONNULL) FLAPI; - - - /** Writes a Fleece Value to an Encoder. */ - bool FLEncoder_WriteValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - - /** Returns an opaque reference to the last complete value written to the encoder, if possible. - Fails (returning 0) 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. */ - intptr_t FLEncoder_LastValueWritten(FLEncoder e); - - /** 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. */ - void FLEncoder_WriteValueAgain(FLEncoder e, intptr_t preWrittenValue); - - - /** 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. */ - FLSliceResult FLEncoder_Snip(FLEncoder e); - - - /** Parses JSON data and writes the object(s) to the encoder. (This acts as a single write, - like WriteInt; it's just that the value written is likely to be an entire dictionary of - array.) */ - bool FLEncoder_ConvertJSON(FLEncoder NONNULL, FLSlice json) FLAPI; - - /** @} */ - /** \name Finishing up - @{ */ - - /** Finishes encoding the current item, and returns its offset in the output data. */ - size_t FLEncoder_FinishItem(FLEncoder NONNULL) FLAPI; - - /** 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. */ - FLDoc FLEncoder_FinishDoc(FLEncoder NONNULL, FLError*) 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. */ - MUST_USE_RESULT - FLSliceResult FLEncoder_Finish(FLEncoder e, FLError *outError) FLAPI; - - /** @} */ - /** \name Error handling - @{ */ - - /** Returns the error code of an encoder, or NoError (0) if there's no error. */ - FLError FLEncoder_GetError(FLEncoder NONNULL) FLAPI; - - /** Returns the error message of an encoder, or NULL if there's no error. */ - const char* FLEncoder_GetErrorMessage(FLEncoder NONNULL) FLAPI; - - /** @} */ - /** @} */ - - - //////// JSON DELTA COMPRESSION - - - /** \defgroup delta Fleece 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. */ - FLSliceResult FLCreateJSONDelta(FLValue old, FLValue 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. */ - bool FLEncodeJSONDelta(FLValue old, FLValue nuu, FLEncoder NONNULL 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 error 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. */ - FLSliceResult FLApplyJSONDelta(FLValue old, - FLSlice jsonDelta, - FLError *error) 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. */ - bool FLEncodeApplyingJSONDelta(FLValue old, - FLSlice jsonDelta, - FLEncoder encoder) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Set(FLMutableArray NONNULL, 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Append(FLMutableArray NONNULL) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableDict_Set(FLMutableDict FL_NONNULL, FLString key) FLAPI; - - - void FLSlot_SetNull(FLSlot NONNULL) FLAPI; ///< Stores a JSON null into a slot. - void FLSlot_SetBool(FLSlot NONNULL, bool) FLAPI; ///< Stores a boolean into a slot. - void FLSlot_SetInt(FLSlot NONNULL, int64_t) FLAPI; ///< Stores an integer into a slot. - void FLSlot_SetUInt(FLSlot NONNULL, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. - void FLSlot_SetFloat(FLSlot NONNULL, float) FLAPI; ///< Stores a `float` into a slot. - void FLSlot_SetDouble(FLSlot NONNULL, double) FLAPI; ///< Stores a `double` into a slot. - void FLSlot_SetString(FLSlot NONNULL, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. - void FLSlot_SetData(FLSlot NONNULL, FLSlice) FLAPI; ///< Stores a data blob into a slot. - void FLSlot_SetValue(FLSlot NONNULL, FLValue) FLAPI; ///< Stores an FLValue into a slot. - - static inline void FLSlot_SetArray(FLSlot NONNULL slot, FLArray array) { - FLSlot_SetValue(slot, (FLValue)array); - } - - static inline void FLSlot_SetDict(FLSlot NONNULL 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 +#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 "Fleece+CoreFoundation.h" + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include #endif #endif // _FLEECE_H diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist index d6e6d76..51bc0bf 100644 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap index 7e8d71f..157018d 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/Modules/module.modulemap @@ -1,24 +1,34 @@ framework module CouchbaseLite { header "CouchbaseLite.h" - header "CBLBase.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 "CBLPlatform.h" header "CBLLog.h" + header "CBLPlatform.h" header "CBLQuery.h" header "CBLReplicator.h" + header "CBLScope.h" module Fleece { - header "Base.h" header "Fleece.h" - header "FLSlice.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" } - - link "couchbase_lite" } - diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..fe840a0 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,17 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist index d86e1c0..ab0eaed 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -13,8 +13,8 @@ CFBundleSignature ???? CFBundleShortVersionString - 3.0.17 + 3.1.7 CFBundleVersion - 1 + 5 diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite index eaa590e..80d41b9 100644 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite index deadfff..9205f47 100755 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/CouchbaseLite differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h index 60e3ff8..5da21cd 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBase.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -182,6 +182,18 @@ void CBL_DumpInstances(void) CBLAPI; 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. diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h index 7173859..a2d6eaa 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLBlob.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -82,12 +81,12 @@ CBL_CAPI_BEGIN /** Returns the length in bytes of a blob's content (from its `length` property). */ uint64_t CBLBlob_Length(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 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; @@ -100,7 +99,7 @@ CBL_CAPI_BEGIN #pragma mark - READING: #endif - /** Reads the blob's contents into memory and returns them. + /** 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, @@ -251,10 +250,7 @@ CBL_CAPI_BEGIN #pragma mark - BINDING DEV SUPPORT FOR BLOB: #endif - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Get a \ref CBLBlob object from the database using the \ref CBLBlob properties. + /** 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 @@ -271,10 +267,7 @@ CBL_CAPI_BEGIN const CBLBlob* _cbl_nullable CBLDatabase_GetBlob(CBLDatabase* db, FLDict properties, CBLError* _cbl_nullable outError) CBLAPI; - /** (UNCOMMITTED) Use this API if you are developing Javascript language bindings. - If you are developing a native app, you must use the CBLBlob API. - - Save a new \ref CBLBlob object into the database without associating it with + /** 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. diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h new file mode 100644 index 0000000..841c811 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLCollection.h @@ -0,0 +1,467 @@ +// +// 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 + +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. + The default scope is exceptional in that it will always exists even there are no collections under it. + @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. + The default scope is exception in that it will always exists even there are no collections under it. + @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 The default scope always exist even there are no collections under it. + @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 The default collection may not exist if it was deleted. + Also, the default collection cannot be recreated after being deleted. + @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 the default collection doesn't exist or 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 scope of the collection. + @note You are responsible for releasing the returned scope. + @param collection The collection. + @return A \ref CBLScope instance. */ +CBLScope* CBLCollection_Scope(const CBLCollection* collection) CBLAPI; + +/** Returns the collection name. + @param collection The collection. + @return The name of the collection. */ +FLString CBLCollection_Name(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; + +/** 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; + +/** @} */ + +/** \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 @@ -72,6 +71,14 @@ CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void) CBLAPI; @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 /** @} */ @@ -96,7 +103,8 @@ bool CBL_DatabaseExists(FLString name, FLString inDirectory) CBLAPI; @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.*/ + @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, @@ -213,15 +221,15 @@ bool CBLDatabase_PerformMaintenance(CBLDatabase* db, /** Returns the database's name. */ FLString CBLDatabase_Name(const CBLDatabase*) CBLAPI; -/** Returns the database's full filesystem path. */ +/** 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. */ +/** 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. - @note The encryption key is not filled in, for security reasons. */ +/** Returns the database's configuration, as given when it was opened. */ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; /** @} */ @@ -232,16 +240,17 @@ const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase*) CBLAPI; #endif /** \name Database listeners @{ - A database change listener lets you detect changes made to all documents in a database. + 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 database change listener callback, invoked after one or more documents are changed on disk. +/** 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. + 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) @@ -251,13 +260,13 @@ typedef void (*CBLDatabaseChangeListener)(void* _cbl_nullable context, unsigned numDocs, FLString docIDs[_cbl_nonnull]); -/** Registers a database change listener callback. It will be called after one or more +/** 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.*/ + @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, @@ -303,7 +312,7 @@ typedef void (*CBLNotificationsReadyCallback)(void* _cbl_nullable context, @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 callback, + CBLNotificationsReadyCallback _cbl_nullable callback, void* _cbl_nullable context) CBLAPI; /** Immediately issues all pending notifications for this database, by calling their listener diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h new file mode 100644 index 0000000..d115a35 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDefaults.h @@ -0,0 +1,94 @@ +// +// CBLDefaults.h +// CouchbaseLite +// +// Copyright (c) 2023-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 + +CBL_CAPI_BEGIN + +/** \defgroup constants Constants + + @{ + + Constants for default configuration values. */ + +/** \name CBLLogFileConfiguration + @{ +*/ + +/** [false] Plaintext is not used, and instead binary encoding is used in log files */ +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 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; + +/** @} */ + +/** @} */ + +CBL_CAPI_END diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h index 8de5976..c42809b 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLDocument.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -59,10 +58,11 @@ typedef bool (*CBLConflictHandler)(void* _cbl_nullable context, const CBLDocument* _cbl_nullable conflictingDocument); -/** Reads a document from the database, creating a new (immutable) \ref CBLDocument object. +/** 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 @@ -75,12 +75,13 @@ const CBLDocument* _cbl_nullable CBLDatabase_GetDocument(const CBLDatabase* data CBL_REFCOUNTED(CBLDocument*, Document); -/** Saves a (mutable) document to the database. - \warning If a newer revision has been saved since \p doc was loaded, it will be overwritten by +/** 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. - @param db The database to save to. + @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. */ @@ -88,12 +89,13 @@ bool CBLDatabase_SaveDocument(CBLDatabase* db, CBLDocument* doc, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database. +/** 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. - @param db The database to save to. + @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. @@ -103,9 +105,10 @@ bool CBLDatabase_SaveDocumentWithConcurrencyControl(CBLDatabase* db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Saves a (mutable) document to the database, allowing for custom conflict handling in the event +/** 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. - @param db The database to save to. + @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. @@ -117,9 +120,10 @@ bool CBLDatabase_SaveDocumentWithConflictHandler(CBLDatabase* db, void* _cbl_nullable context, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. */ @@ -127,9 +131,10 @@ bool CBLDatabase_DeleteDocument(CBLDatabase *db, const CBLDocument* document, CBLError* _cbl_nullable outError) CBLAPI; -/** Deletes a document from the database. Deletions are replicated. +/** Deletes a document from the default collection. Deletions are replicated. @warning You are still responsible for releasing the CBLDocument. - @param db The database containing the document. + @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. @@ -139,28 +144,29 @@ bool CBLDatabase_DeleteDocumentWithConcurrencyControl(CBLDatabase *db, CBLConcurrencyControl concurrency, CBLError* _cbl_nullable outError) CBLAPI; -/** Purges a document. This removes all traces of the document from the database. +/** 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 containing the document. - @param document The document to delete. + @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, given only its ID. +/** 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. - */ + @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; @@ -176,9 +182,10 @@ bool CBLDatabase_PurgeDocumentByID(CBLDatabase* database, in place and then call \ref CBLDatabase_SaveDocument to persist the changes. */ -/** Reads a document from the database, in mutable form that can be updated and saved. +/** 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 @@ -237,6 +244,9 @@ FLString CBLDocument_RevisionID(const CBLDocument*) CBLAPI; 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. @@ -280,6 +290,7 @@ bool CBLDocument_SetJSON(CBLDocument*, /** 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. @@ -291,6 +302,7 @@ CBLTimestamp CBLDatabase_GetDocumentExpiration(CBLDatabase* db, 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), @@ -318,6 +330,7 @@ bool CBLDatabase_SetDocumentExpiration(CBLDatabase* db, @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. */ @@ -327,12 +340,12 @@ typedef void (*CBLDocumentChangeListener)(void *context, /** 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.*/ + @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, diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h index abe532b..4665b9a 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLEncryptable.h @@ -18,7 +18,6 @@ #pragma once #include -#include #ifdef COUCHBASE_ENTERPRISE diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h index 1530c74..6298efa 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLLog.h @@ -115,11 +115,21 @@ void CBLLog_SetCallback(CBLLogCallback _cbl_nullable callback) CBLAPI; @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 - FLString directory; ///< The directory where log files will be created. - uint32_t maxRotateCount; ///< Max number of older log files to keep (in addition to current one.) - size_t maxSize; ///< The size in bytes at which a file will be rotated out (best effort). - bool usePlaintext; ///< Whether or not to log in plaintext (as opposed to binary.) Plaintext logging is slower and bigger. + 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. */ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h index d672fc5..a4e10f1 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLQuery.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -103,7 +102,6 @@ CBLResultSet* _cbl_nullable CBLQuery_Execute(CBLQuery*, 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; @@ -276,7 +274,8 @@ typedef struct { /** 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. */ + 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, @@ -285,15 +284,16 @@ bool CBLDatabase_CreateValueIndex(CBLDatabase *db, /** Full-Text Index Configuration. */ typedef struct { - /** The language used in the expressions. */ + /** 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. */ + in a JSON Array or in N1QL syntax using comma delimiter. (Required) */ FLString expressions; /** Should diacritical marks (accents) be ignored? - Defaults to false. Generally this should be left `false` for non-English text. */ + 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. @@ -313,19 +313,22 @@ typedef struct { /** 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. */ + 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. */ +/** 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. */ + @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; diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h index 41eaf41..9d2a627 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBLReplicator.h @@ -18,7 +18,6 @@ #pragma once #include -#include CBL_CAPI_BEGIN @@ -151,6 +150,74 @@ typedef struct { #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. @@ -172,8 +239,10 @@ typedef struct { 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 (*CBLPropertyEncryptor) ( +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 @@ -184,8 +253,8 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( ); /** 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. + 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 : @@ -206,8 +275,10 @@ typedef FLSliceResult (*CBLPropertyEncryptor) ( @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 (*CBLPropertyDecryptor) ( +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 @@ -219,50 +290,144 @@ typedef FLSliceResult (*CBLPropertyDecryptor) ( #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 { - CBLDatabase* database; ///< The database to replicate - CBLEndpoint* endpoint; ///< The address of the other database to replicate with - CBLReplicatorType replicatorType; ///< Push, pull or both - bool continuous; ///< Continuous replication? + /** 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. - - IMPORTANT: For performance reasons, the document listeners must be added *before* the replicator is started - or they will not receive the events. + + /** 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; + bool disableAutoPurge; + //-- Retry Logic: - unsigned maxAttempts; ///< 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 maxAttemptWaitTime; ///< Max wait time between retry attempts in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 kCBLDefaultReplicatorMaxAttemptWaitTime. */ + unsigned maxAttemptWaitTime; + //-- WebSocket: - unsigned heartbeat; ///< The heartbeat interval in seconds. Specify 0 to use the default value of 300 seconds. + + /** 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 + + 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: - FLSlice pinnedServerCertificate; ///< An X.509 cert to "pin" TLS connections to (PEM or DER) - FLSlice trustedRootCertificates; ///< Set of anchor certs (PEM format) + + /** 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: - FLArray _cbl_nullable channels; ///< Optional set of channels to pull from - FLArray _cbl_nullable documentIDs; ///< Optional set of document IDs to replicate - CBLReplicationFilter _cbl_nullable pushFilter; ///< Optional callback to filter which docs are pushed - CBLReplicationFilter _cbl_nullable pullFilter; ///< Optional callback to validate incoming docs - CBLConflictResolver _cbl_nullable conflictResolver;///< Optional conflict-resolver callback - void* _cbl_nullable context; ///< Arbitrary value that will be passed to callbacks + + /** 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 - CBLPropertyEncryptor _cbl_nullable propertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. - CBLPropertyDecryptor _cbl_nullable propertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. + /** 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; + + CBLDocumentPropertyEncryptor _cbl_nullable documentPropertyEncryptor; ///< Optional callback to encrypt \ref CBLEncryptable values. + CBLDocumentPropertyDecryptor _cbl_nullable documentPropertyDecryptor; ///< Optional callback to decrypt encrypted \ref CBLEncryptable values. #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 @@ -271,11 +436,12 @@ typedef struct { 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. */ + 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; + /** @} */ @@ -325,7 +491,6 @@ void CBLReplicator_SetSuspended(CBLReplicator* repl, bool suspended) CBLAPI; /** @} */ - /** \name Status and Progress @{ */ @@ -344,7 +509,7 @@ typedef CBL_ENUM(uint8_t, CBLReplicatorActivityLevel) { 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; /// Very-approximate fractional completion, from 0.0 to 1.0 + float complete; ///Deprecated : Use CBLReplicator_PendingDocumentIDs2 instead. */ _cbl_warn_unused -FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, - CBLError* _cbl_nullable outError) CBLAPI; +FLDict _cbl_nullable CBLReplicator_PendingDocumentIDs(CBLReplicator*, CBLError* _cbl_nullable outError) CBLAPI; -/** Indicates whether the document with the given ID has local changes that have not yet been - pushed to the server by this replicator. +/** 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. */ + @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. - @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. + @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. */ @@ -399,7 +593,7 @@ typedef void (*CBLReplicatorChangeListener)(void* _cbl_nullable context, CBLReplicator *replicator, const CBLReplicatorStatus *status); -/** Adds a listener that will be called when the replicator's status changes. */ +/** Registers a listener that will be called when the replicator's status changes. */ _cbl_warn_unused CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, CBLReplicatorChangeListener, @@ -408,15 +602,17 @@ CBLListenerToken* CBLReplicator_AddChangeListener(CBLReplicator*, /** 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 + 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; + +/** @} */ + +/** \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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h index 26a2773..0612778 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Compat.h @@ -35,11 +35,9 @@ #define CBLINLINE __forceinline #define _cbl_nonnull _In_ #define _cbl_warn_unused _Check_return_ - #define _cbl_deprecated #else #define CBLINLINE inline #define _cbl_warn_unused __attribute__((warn_unused_result)) - #define _cbl_deprecated __attribute__((deprecated())) #endif // Macros for defining typed enumerations and option flags. @@ -48,6 +46,14 @@ // 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 @@ -57,11 +63,11 @@ #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) enum _name : _type _name; enum _name : _type + #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 : _type + #define CBL_OPTIONS(_type, _name) _type _name; enum __CBL_OPTIONS_ATTRIBUTES : _type #else - #define CBL_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type + #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 diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h index 1712e3a..7fe18c1 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CBL_Edition.h @@ -20,8 +20,8 @@ #define COUCHBASE_ENTERPRISE #endif -#define CBLITE_VERSION "3.0.17" -#define CBLITE_VERSION_NUMBER 3000017 -#define CBLITE_BUILD_NUMBER 1 -#define CBLITE_SOURCE_ID "3becb76+fd69ae2" -#define CBLITE_BUILD_TIMESTAMP "2023-12-15T19:46:00Z" +#define CBLITE_VERSION "3.1.7" +#define CBLITE_VERSION_NUMBER 3001007 +#define CBLITE_BUILD_NUMBER 5 +#define CBLITE_SOURCE_ID "036da58+b89b125" +#define CBLITE_BUILD_TIMESTAMP "2024-04-23T18:52:22Z" diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Base.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h similarity index 82% rename from libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Base.h rename to libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h index fab3644..8098543 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Base.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CompilerSupport.h @@ -1,5 +1,5 @@ // -// Base.h +// CompilerSupport.h // // Copyright 2018-Present Couchbase, Inc. // @@ -11,8 +11,8 @@ // #pragma once -#ifndef FLEECE_BASE_H -#define FLEECE_BASE_H +#ifndef _FLEECE_COMPILER_SUPPORT_H +#define _FLEECE_COMPILER_SUPPORT_H // The __has_xxx() macros are only(?) implemented by Clang. (Except GCC has __has_attribute...) // Define them to return 0 on other compilers. @@ -57,11 +57,32 @@ #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. #ifdef __clang__ #define NONNULL __attribute__((nonnull)) #else @@ -204,7 +225,28 @@ #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_BASE_H +#else // _FLEECE_COMPILER_SUPPORT_H #warn "Compiler is not honoring #pragma once" #endif diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h index 92ccd2b..6802407 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/CouchbaseLite.h @@ -19,10 +19,13 @@ #pragma once #include #include +#include #include +#include #include #include #include #include #include #include +#include diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLBase.h b/libcblite-3.0.3/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-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h new file mode 100644 index 0000000..f621c6b --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLCollections.h @@ -0,0 +1,220 @@ +// +// 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. */ + 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 FLArrayIteratorNext. */ + FLEECE_PUBLIC void FLArrayIterator_Begin(FLArray FL_NULLABLE, FLArrayIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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 FLDictIterator_Next. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLDictIterator_GetKey(const FLDictIterator*) FLAPI FLPURE; + + /** Returns the current key's string value. */ + FLEECE_PUBLIC FLString FLDictIterator_GetKeyString(const FLDictIterator*) FLAPI; + + /** Returns the current value being iterated over. */ + 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, or returns false if at the end. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDeepIterator.h b/libcblite-3.0.3/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-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLDoc.h new file mode 100644 index 0000000..c2f631b --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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!! */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLEncoder.h new file mode 100644 index 0000000..7aa1368 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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) */ + 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. */ + 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. */ + MUST_USE_RESULT + 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. */ + MUST_USE_RESULT + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h new file mode 100644 index 0000000..b52b77c --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLExpert.h @@ -0,0 +1,303 @@ +// +// 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 + @{ */ + + + /** \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. */ + 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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLSharedKeys FLSharedKeys_New(void) FLAPI; + + typedef bool (*FLSharedKeysReadCallback)(void* FL_NULLABLE context, FLSharedKeys); + + 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.) */ + FLEECE_PUBLIC FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys) FLAPI; + + /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ + 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. */ + 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; + + /** Increments the reference count of an FLSharedKeys. */ + 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. */ + 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. */ + 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. */ + 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; + + /** Returns an opaque reference to the last complete value written to the encoder, if possible. + Fails (returning 0) 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. */ + FLEECE_PUBLIC void 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. */ + FLEECE_PUBLIC FLSliceResult FLEncoder_Snip(FLEncoder) FLAPI; + + /** Finishes encoding the current item, and returns its offset in the output data. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLJSON.h new file mode 100644 index 0000000..5dbc78c --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h new file mode 100644 index 0000000..b448d77 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLKeyPath.h @@ -0,0 +1,85 @@ +// +// 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 '$') at the start of a + property name (but not yet in the middle of a name.) + */ + +#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. */ + 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. */ + 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. */ + FLEECE_PUBLIC FLValue FL_NULLABLE FLKeyPath_EvalOnce(FLSlice specifier, FLValue root, + FLError* FL_NULLABLE outError) FLAPI; + + /** Returns a path in string form. */ + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLMutable.h new file mode 100644 index 0000000..7aea9f5 --- /dev/null +++ b/libcblite-3.0.3/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. */ + 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. */ + 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. */ + 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. */ + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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.*/ + MUST_USE_RESULT + 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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h index 44f4298..2850115 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLSlice.h @@ -16,7 +16,7 @@ #ifndef _FLSLICE_H #define _FLSLICE_H -#include +#include #include #include #include @@ -25,13 +25,12 @@ #ifdef __cplusplus #include - #define FLAPI noexcept namespace fleece { struct alloc_slice; } -#else - #define FLAPI #endif +FL_ASSUME_NONNULL_BEGIN + #ifdef __cplusplus extern "C" { #endif @@ -44,7 +43,7 @@ extern "C" { /** 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 *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -62,7 +61,7 @@ typedef struct FLSlice { adopt the reference, and release it in its destructor. For example: `alloc_slice foo( CopyFoo() );` */ typedef struct FLSliceResult { - const void *buf; + const void* FL_NULLABLE buf; size_t size; #ifdef __cplusplus @@ -80,7 +79,7 @@ typedef struct FLSliceResult { struct FLHeapSlice : public FLSlice { constexpr FLHeapSlice() noexcept :FLSlice{nullptr, 0} { } private: - constexpr FLHeapSlice(const void *b, size_t s) noexcept :FLSlice{b, s} { } + constexpr FLHeapSlice(const void *FL_NULLABLE b, size_t s) noexcept :FLSlice{b, s} { } friend struct fleece::alloc_slice; }; #else @@ -103,7 +102,9 @@ typedef FLSliceResult FLStringResult; /** 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 *a, const void *b, size_t size) FLAPI { +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); @@ -111,7 +112,7 @@ static inline FLPURE int FLMemCmp(const void *a, const void *b, size_t size) FLA /** 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 *dst, const void *src, size_t size) FLAPI { +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); } @@ -121,7 +122,7 @@ static inline void FLMemCpy(void *dst, const void *src, size_t size) FLAPI { 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 *str) FLAPI { +static inline FLSlice FLStr(const char* FL_NULLABLE str) FLAPI { FLSlice foo = { str, str ? strlen(str) : 0 }; return foo; } @@ -136,14 +137,14 @@ static inline FLSlice FLStr(const char *str) FLAPI { /** Equality test of two slices. */ -bool FLSlice_Equal(FLSlice a, FLSlice b) FLAPI FLPURE; +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. */ -int FLSlice_Compare(FLSlice, FLSlice) FLAPI FLPURE; +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. */ -uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; +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 @@ -152,24 +153,24 @@ uint32_t FLSlice_Hash(FLSlice s) FLAPI FLPURE; @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. */ -bool FLSlice_ToCString(FLSlice s, char* buffer NONNULL, size_t capacity) FLAPI; +FLEECE_PUBLIC bool FLSlice_ToCString(FLSlice s, char* buffer, size_t capacity) FLAPI; /** Allocates an FLSliceResult of the given size, without initializing the buffer. */ -FLSliceResult FLSliceResult_New(size_t) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSliceResult_New(size_t) FLAPI; /** Allocates an FLSliceResult, copying the given slice. */ -FLSliceResult FLSlice_Copy(FLSlice) FLAPI; +FLEECE_PUBLIC FLSliceResult FLSlice_Copy(FLSlice) FLAPI; /** Allocates an FLSliceResult, copying `size` bytes starting at `buf`. */ -static inline FLSliceResult FLSliceResult_CreateWith(const void *bytes, size_t size) FLAPI { +static inline FLSliceResult FLSliceResult_CreateWith(const void* FL_NULLABLE bytes, size_t size) FLAPI { FLSlice s = {bytes, size}; return FLSlice_Copy(s); } -void _FLBuf_Retain(const void*) FLAPI; // internal; do not call -void _FLBuf_Release(const void*) FLAPI; // internal; do not call +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 { @@ -184,14 +185,16 @@ static inline void FLSliceResult_Release(FLSliceResult s) FLAPI { /** Type-casts a FLSliceResult to FLSlice, since C doesn't know it's a subclass. */ static inline FLSlice FLSliceResult_AsSlice(FLSliceResult sr) { - return *(FLSlice*)&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. */ -void FL_WipeMemory(void *dst, size_t size) FLAPI; +FLEECE_PUBLIC void FL_WipeMemory(void *dst, size_t size) FLAPI; /** @} */ @@ -213,4 +216,5 @@ void FL_WipeMemory(void *dst, size_t size) FLAPI; } #endif +FL_ASSUME_NONNULL_END #endif // _FLSLICE_H diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/FLValue.h b/libcblite-3.0.3/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-3.0.3/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-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h index c5a0d32..585c528 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece+CoreFoundation.h @@ -12,7 +12,13 @@ #pragma once #include -#include "Fleece.h" +#include + +#ifdef __OBJC__ +#import +#endif + +FL_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { @@ -23,50 +29,48 @@ extern "C" { /** Writes a Core Foundation (or Objective-C) object to an Encoder. Supports all the JSON types, as well as CFData. */ - bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteCFObject(FLEncoder, CFTypeRef) FLAPI; /** Returns a Value as a corresponding CoreFoundation object. Caller must CFRelease the result. */ - CFTypeRef FLValue_CopyCFObject(FLValue) FLAPI; + FLEECE_PUBLIC CFTypeRef FLValue_CopyCFObject(FLValue FL_NULLABLE) FLAPI; /** Same as FLDictGet, but takes the key as a CFStringRef. */ - FLValue FLDict_GetWithCFString(FLDict, CFStringRef) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithCFString(FLDict FL_NULLABLE, CFStringRef) FLAPI; #ifdef __OBJC__ -#import - // 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. */ - bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; + FLEECE_PUBLIC bool FLEncoder_WriteNSObject(FLEncoder, id) FLAPI; /** Creates an NSMapTable configured for storing shared NSStrings for Fleece decoding. */ - NSMapTable* FLCreateSharedStringsTable(void) FLAPI; + FLEECE_PUBLIC NSMapTable* FLCreateSharedStringsTable(void) FLAPI; /** Returns a Value as a corresponding (autoreleased) Foundation object. */ - id FLValue_GetNSObject(FLValue, NSMapTable *sharedStrings) FLAPI; + FLEECE_PUBLIC id FLValue_GetNSObject(FLValue FL_NULLABLE, NSMapTable* FL_NULLABLE sharedStrings) FLAPI; /** Same as FLDictGet, but takes the key as an NSString. */ - FLValue FLDict_GetWithNSString(FLDict, NSString*) FLAPI; + FLEECE_PUBLIC FLValue FLDict_GetWithNSString(FLDict FL_NULLABLE, NSString*) FLAPI; /** Returns an FLDictIterator's current key as an NSString. */ - NSString* FLDictIterator_GetKeyAsNSString(const FLDictIterator *i, - NSMapTable *sharedStrings) FLAPI; + 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. */ - NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError**) FLAPI; + FLEECE_PUBLIC NSData* FLEncoder_FinishWithNSData(FLEncoder, NSError** FL_NULLABLE) FLAPI; /** NSError domain string for Fleece errors */ - extern NSString* const FLErrorDomain; + FLEECE_PUBLIC extern NSString* const FLErrorDomain; @interface NSObject (Fleece) @@ -76,8 +80,6 @@ extern "C" { a single object (which may of course be an array or dictionary.) */ - (void) fl_encodeToFLEncoder: (FLEncoder)enc; @end - - #endif /** @} */ @@ -85,3 +87,5 @@ extern "C" { #ifdef __cplusplus } #endif + +FL_ASSUME_NONNULL_END diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h index 69655ff..6476347 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Headers/Fleece.h @@ -14,1454 +14,23 @@ #ifndef _FLEECE_H #define _FLEECE_H -#include -#include +// This "umbrella header" includes the commonly-used parts of the Fleece C API. -// 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 -#endif - -#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. -#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; - - - //////// DOCUMENT - - - /** @} */ - /** \defgroup reading Reading Fleece Data - @{ - \name FLDoc - @{ - An FLDoc points to (and often owns) Fleece-encoded data and provides access to its - Fleece values. - */ - -#ifndef FL_IMPL - typedef struct _FLDoc* FLDoc; ///< A reference to a document. - typedef struct _FLSharedKeys* FLSharedKeys; ///< A reference to a shared-keys mapping. -#endif - - /** 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; - - - /** 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. */ - FLDoc FLDoc_FromResultData(FLSliceResult data, FLTrust, FLSharedKeys, FLSlice externData) FLAPI; - - /** 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. */ - FLDoc FLDoc_FromJSON(FLSlice json, FLError *outError) FLAPI; - - /** Releases a reference to an FLDoc. This must be called once to free an FLDoc you created. */ - void FLDoc_Release(FLDoc) FLAPI; - - /** Adds a reference to an FLDoc. This extends its lifespan until at least such time as you - call FLRelease to remove the reference. */ - FLDoc FLDoc_Retain(FLDoc) FLAPI; - - /** Returns the encoded Fleece data backing the document. */ - FLSlice FLDoc_GetData(FLDoc) FLAPI FLPURE; - - /** Returns the FLSliceResult data owned by the document, if any, else a null slice. */ - FLSliceResult FLDoc_GetAllocedData(FLDoc) FLAPI FLPURE; - - /** Returns the root value in the FLDoc, usually an FLDict. */ - FLValue FLDoc_GetRoot(FLDoc) FLAPI FLPURE; - - /** Returns the FLSharedKeys used by this FLDoc, as specified when it was created. */ - FLSharedKeys FLDoc_GetSharedKeys(FLDoc) 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. */ - bool FLDoc_SetAssociated(FLDoc doc, void *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. */ - void* FLDoc_GetAssociated(FLDoc doc, const char *type) FLAPI FLPURE; - - /** Looks up the Doc containing the Value, or NULL if the Value was created without a Doc. - @note Caller must release the FLDoc reference!! */ - FLDoc FLValue_FindDoc(FLValue) FLAPI FLPURE; - - - /** @} */ - /** \name Parsing And Converting Values Directly - @{ */ - - /** Returns a pointer to the root value in the encoded data, or NULL if validation failed. - The FLValue, and all values found through it, are only valid as long as the encoded data - remains intact and unchanged. */ - FLValue FLValue_FromData(FLSlice data, FLTrust) FLAPI FLPURE; - - /** Directly converts JSON data to Fleece-encoded data. - You can then call FLValue_FromData (in kFLTrusted mode) to get the root as a Value. */ - FLSliceResult FLData_ConvertJSON(FLSlice json, FLError *outError) FLAPI; - - /** Produces a human-readable dump of the Value encoded in the data. - This is only useful if you already know, or want to learn, the encoding format. */ - FLStringResult FLData_Dump(FLSlice data) FLAPI; - - - /** @} */ - /** @} */ - /** \defgroup json Converting Fleece To JSON - @{ - These are convenience functions that directly return JSON-encoded output. - For more control over the encoding, use an FLEncoder. */ - - /** Encodes a Fleece value as JSON (or a JSON fragment.) - Any Data values will become base64-encoded JSON strings. */ - FLStringResult FLValue_ToJSON(FLValue) 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. */ - FLStringResult FLValue_ToJSON5(FLValue v) FLAPI; - - /** Most general Fleece to JSON converter. */ - FLStringResult FLValue_ToJSONX(FLValue v, - bool json5, - bool canonicalForm) FLAPI; - - /** 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. */ - FLStringResult FLJSON5_ToJSON(FLString json5, - FLStringResult *outErrorMessage, - size_t *outErrorPos, - FLError *outError) FLAPI; - - /** \name Debugging Functions - @{ */ - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDump(FLValue) FLAPI; - /** Debugging function that returns a C string of JSON. Does not free the string's memory! */ - const char* FLDumpData(FLSlice data) FLAPI; - - /** @} */ - - - //////// VALUE - - - /** @} */ - /** \defgroup FLValue Fleece Value Accessors - @{ - 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.) - - It's always safe to pass a NULL value to an accessor; that goes for FLDict and FLArray - as well as FLValue. The result will be a default value of that type, e.g. false or 0 - or NULL, unless otherwise specified. */ - - /** 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 a value created by 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 - } FLValueType; - - - /** A timestamp, 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 the data type of an arbitrary Value. - (If the parameter is a NULL pointer, returns `kFLUndefined`.) */ - FLValueType FLValue_GetType(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents an integer. */ - bool FLValue_IsInteger(FLValue) 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. */ - bool FLValue_IsUnsigned(FLValue) FLAPI FLPURE; - - /** Returns true if the value is non-NULL and represents a 64-bit floating-point number. */ - bool FLValue_IsDouble(FLValue) FLAPI; - - /** Returns a value coerced to boolean. This will be true unless the value is NULL (undefined), - null, false, or zero. */ - bool FLValue_AsBool(FLValue) 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`. */ - int64_t FLValue_AsInt(FLValue) 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. */ - uint64_t FLValue_AsUnsigned(FLValue) 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. */ - float FLValue_AsFloat(FLValue) 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. */ - double FLValue_AsDouble(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a string value, or null for all other types. */ - FLString FLValue_AsString(FLValue) 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. */ - FLTimestamp FLValue_AsTimestamp(FLValue) FLAPI FLPURE; - - /** Returns the exact contents of a data value, or null for all other types. */ - FLSlice FLValue_AsData(FLValue) FLAPI FLPURE; - - /** If a FLValue represents an array, returns it cast to FLArray, else NULL. */ - FLArray FLValue_AsArray(FLValue) FLAPI FLPURE; - - /** If a FLValue represents a dictionary, returns it as an FLDict, else NULL. */ - FLDict FLValue_AsDict(FLValue) 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. */ - FLStringResult FLValue_ToString(FLValue) FLAPI; - - /** Compares two values for equality. This is a deep recursive comparison. */ - bool FLValue_IsEqual(FLValue v1, FLValue v2) FLAPI FLPURE; - - /** Returns true if the value is mutable. */ - bool FLValue_IsMutable(FLValue) FLAPI FLPURE; - - /** \name Ref-counting (mutable values only) - @{ */ - - /** If this value is mutable (and thus heap-based) its ref-count is incremented. - Otherwise, this call does nothing. */ - FLValue FLValue_Retain(FLValue) FLAPI; - - /** If this value is mutable (and thus heap-based) its ref-count is decremented, and if it - reaches zero the value is freed. - If the value is not mutable, this call does nothing. */ - void FLValue_Release(FLValue) FLAPI; - - static inline FLArray FLArray_Retain(FLArray v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLArray_Release(FLArray v) {FLValue_Release((FLValue)v);} - static inline FLDict FLDict_Retain(FLDict v) {FLValue_Retain((FLValue)v); return v;} - static inline void FLDict_Release(FLDict v) {FLValue_Release((FLValue)v);} - - /** @} */ - - /** 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. */ - FLValue 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. */ - FLValue FLValue_NewData(FLSlice) FLAPI; - - /** A constant null value (not a NULL pointer!) */ - FLEECE_PUBLIC extern const FLValue kFLNullValue; - - /** A constant undefined value */ - FLEECE_PUBLIC extern const FLValue kFLUndefinedValue; - - - //////// 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. - */ - - /** Returns the number of items in an array, or 0 if the pointer is NULL. */ - uint32_t FLArray_Count(FLArray) 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` */ - bool FLArray_IsEmpty(FLArray) FLAPI FLPURE; - - /** If the array is mutable, returns it cast to FLMutableArray, else NULL. */ - FLMutableArray FLArray_AsMutable(FLArray) FLAPI FLPURE; - - /** Returns an value at an array index, or NULL if the index is out of range. */ - FLValue FLArray_Get(FLArray, uint32_t index) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLArray kFLEmptyArray; - - /** \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 FLArrayIteratorNext. */ - void FLArrayIterator_Begin(FLArray, FLArrayIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLArrayIterator_GetValue(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Returns a value in the array at the given offset from the current value. */ - FLValue FLArrayIterator_GetValueAt(const FLArrayIterator* NONNULL, uint32_t offset) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLArrayIterator_GetCount(const FLArrayIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLArrayIterator_Next(FLArrayIterator* NONNULL) FLAPI; - - /** @} */ - - - //////// MUTABLE ARRAY - - - /** \name Mutable Arrays - @{ */ - - typedef enum { - kFLDefaultCopy = 0, - kFLDeepCopy = 1, - kFLCopyImmutables = 2, - kFLDeepCopyImmutables = (kFLDeepCopy | kFLCopyImmutables), - } FLCopyFlags; - - - /** Creates a new mutable Array that's a copy of the source Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. - - Copying an immutable Array is very cheap (only one small allocation) unless the flag - kFLCopyImmutables is set. - - Copying a mutable Array is cheap if it's a shallow copy, but if `deepCopy` is true, - nested mutable Arrays and Dicts are also copied, recursively; if kFLCopyImmutables is - also set, immutable values are also copied. - - If the source Array is NULL, then NULL is returned. */ - FLMutableArray FLArray_MutableCopy(FLArray, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Array. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_New(void) FLAPI; - - /** Creates a new mutable Array from JSON. The input json must represent a JSON array or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableArray_Release will free it. */ - FLMutableArray FLMutableArray_NewFromJSON(FLString json, FLError* outError) FLAPI; - - /** Increments the ref-count of a mutable Array. */ - static inline FLMutableArray FLMutableArray_Retain(FLMutableArray d) { - return (FLMutableArray)FLValue_Retain((FLValue)d); - } - /** Decrements the refcount of (and possibly frees) a mutable Array. */ - static inline void FLMutableArray_Release(FLMutableArray d) { - FLValue_Release((FLValue)d); - } - - /** If the Array was created by FLArray_MutableCopy, returns the original source Array. */ - FLArray FLMutableArray_GetSource(FLMutableArray) FLAPI; - - /** Returns true if the Array has been changed from the source it was copied from. */ - bool FLMutableArray_IsChanged(FLMutableArray) FLAPI; - - /** Sets or clears the mutable Array's "changed" flag. */ - void FLMutableArray_SetChanged(FLMutableArray, bool) 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. */ - void FLMutableArray_Insert(FLMutableArray 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. */ - void FLMutableArray_Remove(FLMutableArray 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. */ - void FLMutableArray_Resize(FLMutableArray 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. */ - FLMutableArray FLMutableArray_GetMutableArray(FLMutableArray, 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. */ - FLMutableDict FLMutableArray_GetMutableDict(FLMutableArray, uint32_t index) FLAPI; - - - /// Stores a JSON null value into an array. - static inline void FLMutableArray_SetNull(FLMutableArray NONNULL, uint32_t index); - /// Stores a boolean value into an array. - static inline void FLMutableArray_SetBool(FLMutableArray NONNULL, uint32_t index, bool); - /// Stores an integer into an array. - static inline void FLMutableArray_SetInt(FLMutableArray NONNULL, 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 NONNULL, uint32_t index, uint64_t); - /// Stores a 32-bit floating-point number into an array. - static inline void FLMutableArray_SetFloat(FLMutableArray NONNULL, uint32_t index, float); - /// Stores a 64-bit floating point number into an array. - static inline void FLMutableArray_SetDouble(FLMutableArray NONNULL, uint32_t index, double); - /// Stores a UTF-8-encoded string into an array. - static inline void FLMutableArray_SetString(FLMutableArray NONNULL, uint32_t index, FLString); - /// Stores a binary data blob into an array. - static inline void FLMutableArray_SetData(FLMutableArray NONNULL, uint32_t index, FLSlice); - /// Stores a Fleece value into an array. - static inline void FLMutableArray_SetValue(FLMutableArray NONNULL, uint32_t index, FLValue); - /// Stores a Fleece array into an array - static inline void FLMutableArray_SetArray(FLMutableArray NONNULL, uint32_t index, FLArray); - /// Stores a Fleece dictionary into an array - static inline void FLMutableArray_SetDict(FLMutableArray NONNULL, uint32_t index, FLDict); - - /// Appends a JSON null value to an array. - static inline void FLMutableArray_AppendNull(FLMutableArray NONNULL); - /// Appends a boolean value to an array. - static inline void FLMutableArray_AppendBool(FLMutableArray NONNULL, bool); - /// Appends an integer to an array. - static inline void FLMutableArray_AppendInt(FLMutableArray NONNULL, 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 NONNULL, uint64_t); - /// Appends a 32-bit floating-point number to an array. - static inline void FLMutableArray_AppendFloat(FLMutableArray NONNULL, float); - /// Appends a 64-bit floating point number to an array. - static inline void FLMutableArray_AppendDouble(FLMutableArray NONNULL, double); - /// Appends a UTF-8-encoded string to an array. - static inline void FLMutableArray_AppendString(FLMutableArray NONNULL, FLString); - /// Appends a binary data blob to an array. - static inline void FLMutableArray_AppendData(FLMutableArray NONNULL, FLSlice); - /// Appends a Fleece value to an array. - static inline void FLMutableArray_AppendValue(FLMutableArray NONNULL, FLValue); - /// Appends a Fleece array to an array - static inline void FLMutableArray_AppendArray(FLMutableArray NONNULL, FLArray); - /// Appends a Fleece dictionary to an array - static inline void FLMutableArray_AppendDict(FLMutableArray NONNULL, FLDict); - - - /** @} */ - - - //////// DICT - - - /** @} */ - /** \defgroup FLDict Fleece Dictionaries - @{ */ - - /** Returns the number of items in a dictionary, or 0 if the pointer is NULL. */ - uint32_t FLDict_Count(FLDict) 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` */ - bool FLDict_IsEmpty(FLDict) FLAPI FLPURE; - - /** If the dictionary is mutable, returns it cast to FLMutableDict, else NULL. */ - FLMutableDict FLDict_AsMutable(FLDict) 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. */ - FLValue FLDict_Get(FLDict, FLSlice keyString) FLAPI FLPURE; - - FLEECE_PUBLIC extern const FLDict kFLEmptyDict; - - /** \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[4]; - int _private5; -#endif - } FLDictIterator; - - /** Initializes a FLDictIterator struct to iterate over a dictionary. - Call FLDictIterator_GetKey and FLDictIterator_GetValue to get the first item, - then FLDictIterator_Next. */ - void FLDictIterator_Begin(FLDict, FLDictIterator* NONNULL) FLAPI; - - /** Returns the current key being iterated over. This Value will be a string or an integer. */ - FLValue FLDictIterator_GetKey(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the current key's string value. */ - FLString FLDictIterator_GetKeyString(const FLDictIterator* NONNULL) FLAPI; - - /** Returns the current value being iterated over. */ - FLValue FLDictIterator_GetValue(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Returns the number of items remaining to be iterated, including the current one. */ - uint32_t FLDictIterator_GetCount(const FLDictIterator* NONNULL) FLAPI FLPURE; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDictIterator_Next(FLDictIterator* NONNULL) 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.) */ - void FLDictIterator_End(FLDictIterator* NONNULL) 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. */ - FLDictKey FLDictKey_Init(FLSlice string) FLAPI; - - /** Returns the string value of the key (which it was initialized with.) */ - FLString FLDictKey_GetString(const FLDictKey * NONNULL) 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. */ - FLValue FLDict_GetWithKey(FLDict, FLDictKey* NONNULL) FLAPI; - - - //////// 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. */ - FLMutableDict FLDict_MutableCopy(FLDict source, FLCopyFlags) FLAPI; - - /** Creates a new empty mutable Dict. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_New(void) FLAPI; - - /** Creates a new mutable Dict from json. The input JSON must represent a JSON array, or NULL will be returned. - Its initial ref-count is 1, so a call to FLMutableDict_Release will free it. */ - FLMutableDict FLMutableDict_NewFromJSON(FLString json, FLError *outError) FLAPI; - - /** Increments the ref-count of a mutable Dict. */ - static inline FLMutableDict FLMutableDict_Retain(FLMutableDict d) { - return (FLMutableDict)FLValue_Retain((FLValue)d); - } - - /** Decrements the refcount of (and possibly frees) a mutable Dict. */ - static inline void FLMutableDict_Release(FLMutableDict d) { - FLValue_Release((FLValue)d); - } - - /** If the Dict was created by FLDict_MutableCopy, returns the original source Dict. */ - FLDict FLMutableDict_GetSource(FLMutableDict) FLAPI; - - /** Returns true if the Dict has been changed from the source it was copied from. */ - bool FLMutableDict_IsChanged(FLMutableDict) FLAPI; - - /** Sets or clears the mutable Dict's "changed" flag. */ - void FLMutableDict_SetChanged(FLMutableDict, bool) FLAPI; - - /** Removes the value for a key. */ - void FLMutableDict_Remove(FLMutableDict, FLString key) FLAPI; - - /** Removes all keys and values. */ - void FLMutableDict_RemoveAll(FLMutableDict) 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. */ - FLMutableArray FLMutableDict_GetMutableArray(FLMutableDict, 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. */ - FLMutableDict FLMutableDict_GetMutableDict(FLMutableDict, FLString key) FLAPI; - - - /// Stores a JSON null value into a mutable dictionary. - static inline void FLMutableDict_SetNull(FLMutableDict NONNULL, FLString key); - /// Stores a boolean value into a mutable dictionary. - static inline void FLMutableDict_SetBool(FLMutableDict NONNULL, FLString key, bool); - /// Stores an integer into a mutable dictionary. - static inline void FLMutableDict_SetInt(FLMutableDict NONNULL, 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 NONNULL, FLString key, uint64_t); - /// Stores a 32-bit floating-point number into a mutable dictionary. - static inline void FLMutableDict_SetFloat(FLMutableDict NONNULL, FLString key, float); - /// Stores a 64-bit floating point number into a mutable dictionary. - static inline void FLMutableDict_SetDouble(FLMutableDict NONNULL, FLString key, double); - /// Stores a UTF-8-encoded string into a mutable dictionary. - static inline void FLMutableDict_SetString(FLMutableDict NONNULL, FLString key, FLString); - /// Stores a binary data blob into a mutable dictionary. - static inline void FLMutableDict_SetData(FLMutableDict NONNULL, FLString key, FLSlice); - /// Stores a Fleece value into a mutable dictionary. - static inline void FLMutableDict_SetValue(FLMutableDict NONNULL, FLString key, FLValue); - /// Stores a Fleece array into a mutable dictionary. - static inline void FLMutableDict_SetArray(FLMutableDict NONNULL, FLString key, FLArray); - /// Stores a Fleece dictionary into a mutable dictionary. - static inline void FLMutableDict_SetDict(FLMutableDict NONNULL, FLString key, FLDict); - - - /** @} */ - - - //////// DEEP ITERATOR - - - /** @} */ - /** \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 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. */ - FLDeepIterator FLDeepIterator_New(FLValue) FLAPI; - - void FLDeepIterator_Free(FLDeepIterator) FLAPI; - - /** Returns the current value being iterated over. or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetValue(FLDeepIterator NONNULL) FLAPI; - - /** Returns the parent/container of the current value, or NULL at the end of iteration. */ - FLValue FLDeepIterator_GetParent(FLDeepIterator NONNULL) FLAPI; - - /** Returns the key of the current value in its parent, or an empty slice if not in a dictionary. */ - FLSlice FLDeepIterator_GetKey(FLDeepIterator NONNULL) FLAPI; - - /** Returns the array index of the current value in its parent, or 0 if not in an array. */ - uint32_t FLDeepIterator_GetIndex(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current depth in the hierarchy, starting at 1 for the top-level children. */ - size_t FLDeepIterator_GetDepth(FLDeepIterator NONNULL) FLAPI; - - /** Tells the iterator to skip the children of the current value. */ - void FLDeepIterator_SkipChildren(FLDeepIterator NONNULL) FLAPI; - - /** Advances the iterator to the next value, or returns false if at the end. */ - bool FLDeepIterator_Next(FLDeepIterator NONNULL) 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. */ - void FLDeepIterator_GetPath(FLDeepIterator NONNULL, - FLPathComponent* * NONNULL outPath, - size_t* NONNULL outDepth) FLAPI; - - /** Returns the current path in JavaScript format. */ - FLSliceResult FLDeepIterator_GetPathString(FLDeepIterator NONNULL) FLAPI; - - /** Returns the current path in JSONPointer format (RFC 6901). */ - FLSliceResult FLDeepIterator_GetJSONPointer(FLDeepIterator NONNULL) FLAPI; - - - //////// PATH - - - /** @} */ - /** \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 '$') at the start of a - property name (but not yet in the middle of a name.) - */ - -#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. */ - FLKeyPath FLKeyPath_New(FLSlice specifier, FLError *error) FLAPI; - - /** Frees a compiled FLKeyPath object. (It's ok to pass NULL.) */ - void FLKeyPath_Free(FLKeyPath) FLAPI; - - /** Evaluates a compiled key-path for a given Fleece root object. */ - FLValue FLKeyPath_Eval(FLKeyPath NONNULL, 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. */ - FLValue FLKeyPath_EvalOnce(FLSlice specifier, FLValue root NONNULL, FLError *error) FLAPI; - - /** Returns a path in string form. */ - FLStringResult FLKeyPath_ToString(FLKeyPath path) FLAPI; - - /** Equality test. */ - bool FLKeyPath_Equals(FLKeyPath path1, FLKeyPath path2) FLAPI; - - /** Returns an element of a path, either a key or an array index. */ - bool FLKeyPath_GetElement(FLKeyPath NONNULL, - size_t i, - FLSlice *outDictKey NONNULL, - int32_t *outArrayIndex NONNULL) FLAPI; - - //////// SHARED KEYS - - - /** @} */ - /** \defgroup FLSharedKeys 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. */ - FLSharedKeys FLSharedKeys_New(void) FLAPI; - - typedef bool (*FLSharedKeysReadCallback)(void *context, FLSharedKeys); - - FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback, - void *context) FLAPI; - - /** Returns a data blob containing the current state (all the keys and their integers.) */ - FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys NONNULL) FLAPI; - - /** Updates an FLSharedKeys with saved state data created by \ref FLSharedKeys_GetStateData. */ - 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. */ - void FLSharedKeys_WriteState(FLSharedKeys, FLEncoder) FLAPI; - - /** Updates an FLSharedKeys object with saved state, a Fleece value previously written by - \ref FLSharedKeys_WriteState. */ - 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. */ - int FLSharedKeys_Encode(FLSharedKeys NONNULL, FLString, bool add) FLAPI; - - /** Returns the key string that maps to the given integer `key`, else NULL. */ - FLString FLSharedKeys_Decode(FLSharedKeys NONNULL, int key) FLAPI; - - /** Returns the number of keys in the mapping. This number increases whenever the mapping - is changed, and never decreases. */ - unsigned FLSharedKeys_Count(FLSharedKeys NONNULL) FLAPI; - - /** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */ - void FLSharedKeys_RevertToCount(FLSharedKeys NONNULL, unsigned oldCount) FLAPI; - - /** Increments the reference count of an FLSharedKeys. */ - FLSharedKeys FLSharedKeys_Retain(FLSharedKeys) FLAPI; - - /** Decrements the reference count of an FLSharedKeys, freeing it when it reaches zero. */ - void FLSharedKeys_Release(FLSharedKeys) FLAPI; - - - typedef struct _FLSharedKeyScope* FLSharedKeyScope; - FLSharedKeyScope FLSharedKeyScope_WithRange(FLSlice range, FLSharedKeys) FLAPI; - void FLSharedKeyScope_Free(FLSharedKeyScope); - - - //////// ENCODER - - - /** @} */ - /** \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. */ - 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) */ - FLEncoder FLEncoder_NewWithOptions(FLEncoderFormat format, - size_t reserveSize, - bool uniqueStrings) FLAPI; - - /** Creates a new Fleece encoder that writes to a file, not to memory. */ - FLEncoder FLEncoder_NewWritingToFile(FILE* NONNULL, bool uniqueStrings) FLAPI; - - /** Frees the space used by an encoder. */ - void FLEncoder_Free(FLEncoder) FLAPI; - - /** Tells the encoder to use a shared-keys mapping when encoding dictionary keys. */ - void FLEncoder_SetSharedKeys(FLEncoder NONNULL, FLSharedKeys) FLAPI; - - /** Associates an arbitrary user-defined value with the encoder. */ - void FLEncoder_SetExtraInfo(FLEncoder NONNULL, void *info) FLAPI; - - /** Returns the user-defined value associated with the encoder; NULL by default. */ - void* FLEncoder_GetExtraInfo(FLEncoder NONNULL) FLAPI; - - - /** 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. */ - void FLEncoder_Amend(FLEncoder e NONNULL, FLSlice base, - bool reuseStrings, bool externPointers) FLAPI; - - /** Returns the `base` value passed to FLEncoder_Amend. */ - FLSlice FLEncoder_GetBase(FLEncoder NONNULL) 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. */ - void FLEncoder_SuppressTrailer(FLEncoder NONNULL) FLAPI; - - /** Resets the state of an encoder without freeing it. It can then be reused to encode - another value. */ - void FLEncoder_Reset(FLEncoder NONNULL) FLAPI; - - /** Returns the number of bytes encoded so far. */ - size_t FLEncoder_BytesWritten(FLEncoder NONNULL) 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.) */ - size_t FLEncoder_GetNextWritePos(FLEncoder NONNULL) 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.) */ - bool FLEncoder_WriteNull(FLEncoder NONNULL) 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. */ - bool FLEncoder_WriteUndefined(FLEncoder NONNULL) FLAPI; - - /** Writes a boolean value (true or false) to an encoder. */ - bool FLEncoder_WriteBool(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteUInt(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteFloat(FLEncoder NONNULL, 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.) */ - bool FLEncoder_WriteDouble(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteString(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteDateString(FLEncoder NONNULL 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. */ - bool FLEncoder_WriteData(FLEncoder NONNULL, FLSlice) FLAPI; - - /** Writes raw data directly to the encoded output. - (This is not the same as 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. */ - bool FLEncoder_WriteRaw(FLEncoder NONNULL, FLSlice) 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. */ - bool FLEncoder_BeginArray(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Ends writing an array value; pops back the previous encoding state. */ - bool FLEncoder_EndArray(FLEncoder NONNULL) 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. */ - bool FLEncoder_BeginDict(FLEncoder NONNULL, size_t reserveCount) FLAPI; - - /** Specifies the key for the next value to be written to the current dictionary. */ - bool FLEncoder_WriteKey(FLEncoder NONNULL, 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. */ - bool FLEncoder_WriteKeyValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - /** Ends writing a dictionary value; pops back the previous encoding state. */ - bool FLEncoder_EndDict(FLEncoder NONNULL) FLAPI; - - - /** Writes a Fleece Value to an Encoder. */ - bool FLEncoder_WriteValue(FLEncoder NONNULL, FLValue NONNULL) FLAPI; - - - /** Returns an opaque reference to the last complete value written to the encoder, if possible. - Fails (returning 0) 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. */ - intptr_t FLEncoder_LastValueWritten(FLEncoder e); - - /** 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. */ - void FLEncoder_WriteValueAgain(FLEncoder e, intptr_t preWrittenValue); - - - /** 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. */ - FLSliceResult FLEncoder_Snip(FLEncoder e); - - - /** Parses JSON data and writes the object(s) to the encoder. (This acts as a single write, - like WriteInt; it's just that the value written is likely to be an entire dictionary of - array.) */ - bool FLEncoder_ConvertJSON(FLEncoder NONNULL, FLSlice json) FLAPI; - - /** @} */ - /** \name Finishing up - @{ */ - - /** Finishes encoding the current item, and returns its offset in the output data. */ - size_t FLEncoder_FinishItem(FLEncoder NONNULL) FLAPI; - - /** 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. */ - FLDoc FLEncoder_FinishDoc(FLEncoder NONNULL, FLError*) 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. */ - MUST_USE_RESULT - FLSliceResult FLEncoder_Finish(FLEncoder e, FLError *outError) FLAPI; - - /** @} */ - /** \name Error handling - @{ */ - - /** Returns the error code of an encoder, or NoError (0) if there's no error. */ - FLError FLEncoder_GetError(FLEncoder NONNULL) FLAPI; - - /** Returns the error message of an encoder, or NULL if there's no error. */ - const char* FLEncoder_GetErrorMessage(FLEncoder NONNULL) FLAPI; - - /** @} */ - /** @} */ - - - //////// JSON DELTA COMPRESSION - - - /** \defgroup delta Fleece 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. */ - FLSliceResult FLCreateJSONDelta(FLValue old, FLValue 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. */ - bool FLEncodeJSONDelta(FLValue old, FLValue nuu, FLEncoder NONNULL 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 error 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. */ - FLSliceResult FLApplyJSONDelta(FLValue old, - FLSlice jsonDelta, - FLError *error) 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. */ - bool FLEncodeApplyingJSONDelta(FLValue old, - FLSlice jsonDelta, - FLEncoder encoder) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Set(FLMutableArray NONNULL, 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.*/ - MUST_USE_RESULT - FLSlot FLMutableArray_Append(FLMutableArray NONNULL) 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.*/ - MUST_USE_RESULT - FLSlot FLMutableDict_Set(FLMutableDict FL_NONNULL, FLString key) FLAPI; - - - void FLSlot_SetNull(FLSlot NONNULL) FLAPI; ///< Stores a JSON null into a slot. - void FLSlot_SetBool(FLSlot NONNULL, bool) FLAPI; ///< Stores a boolean into a slot. - void FLSlot_SetInt(FLSlot NONNULL, int64_t) FLAPI; ///< Stores an integer into a slot. - void FLSlot_SetUInt(FLSlot NONNULL, uint64_t) FLAPI; ///< Stores an unsigned int into a slot. - void FLSlot_SetFloat(FLSlot NONNULL, float) FLAPI; ///< Stores a `float` into a slot. - void FLSlot_SetDouble(FLSlot NONNULL, double) FLAPI; ///< Stores a `double` into a slot. - void FLSlot_SetString(FLSlot NONNULL, FLString) FLAPI; ///< Stores a UTF-8 string into a slot. - void FLSlot_SetData(FLSlot NONNULL, FLSlice) FLAPI; ///< Stores a data blob into a slot. - void FLSlot_SetValue(FLSlot NONNULL, FLValue) FLAPI; ///< Stores an FLValue into a slot. - - static inline void FLSlot_SetArray(FLSlot NONNULL slot, FLArray array) { - FLSlot_SetValue(slot, (FLValue)array); - } - - static inline void FLSlot_SetDict(FLSlot NONNULL 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 +#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 "Fleece+CoreFoundation.h" + // When compiling as Objective-C, include CoreFoundation / Objective-C utilities: +#include #endif #endif // _FLEECE_H diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist index 56708c9..9160e3a 100644 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Info.plist differ diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap index 7e8d71f..157018d 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/Modules/module.modulemap @@ -1,24 +1,34 @@ framework module CouchbaseLite { header "CouchbaseLite.h" - header "CBLBase.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 "CBLPlatform.h" header "CBLLog.h" + header "CBLPlatform.h" header "CBLQuery.h" header "CBLReplicator.h" + header "CBLScope.h" module Fleece { - header "Base.h" header "Fleece.h" - header "FLSlice.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" } - - link "couchbase_lite" } - diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..fe840a0 --- /dev/null +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,17 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/_CodeSignature/CodeResources b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/_CodeSignature/CodeResources deleted file mode 100644 index b56374f..0000000 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/CouchbaseLite.framework/_CodeSignature/CodeResources +++ /dev/null @@ -1,357 +0,0 @@ - - - - - files - - Headers/Base.h - - 3NQnn7X+Ki77J+f/pz9KjjOdtbI= - - Headers/CBLBase.h - - tyIyxAEX8N13+UTMytLts14hRj0= - - Headers/CBLBlob.h - - c9wrfsp59BXDSyReg12o2Po+cv4= - - Headers/CBLDatabase.h - - NYZQZQXPcoZjUxSskTKMbFTtfEs= - - Headers/CBLDocument.h - - S3hpS7s7ABMPp/xIHp40bIZ2zDY= - - Headers/CBLEncryptable.h - - 9VnNsW6nTmbUZsOi5TNUNyZy/T0= - - Headers/CBLLog.h - - +8orYUMXwYW07B/VnRbWTs5OlAE= - - Headers/CBLPlatform.h - - Vln3jO3elRtPHV4FULtBxtrXSUk= - - Headers/CBLQuery.h - - M/IyqT/W/EgCJE8gYzsjzftpl/w= - - Headers/CBLReplicator.h - - hn5+NMXE5E7UMZYm+X2NIa6IPYE= - - Headers/CBL_Compat.h - - XSqrNRZlB1pOQDycn0aetrmCffU= - - Headers/CBL_Edition.h - - d8fohT/W0JIVRJH9u5SZTGSPMwg= - - Headers/CouchbaseLite.h - - OTH+XNdO5zXy7m3rDtWoqcoGCXE= - - Headers/FLSlice.h - - cmN3q7yIi1XdUYayk+yfP2Tf104= - - Headers/Fleece+CoreFoundation.h - - pHWdmILGUd1LggyUOYcdtDOb7Qc= - - Headers/Fleece.h - - MuPrDAGcfk2SE1ykzADxNrcUV40= - - Info.plist - - ut35QKk4iXQQDwTrfeYdWi6jLKI= - - Modules/module.modulemap - - yIpU8739tGhwfSh7c7sH/aayqW8= - - - files2 - - Headers/Base.h - - hash - - 3NQnn7X+Ki77J+f/pz9KjjOdtbI= - - hash2 - - VvX/a/3s61avnzp/K8EM9CGl56TsLYjNX+GLGkb5rPY= - - - Headers/CBLBase.h - - hash - - tyIyxAEX8N13+UTMytLts14hRj0= - - hash2 - - 9q9u3g/QYBdbaVhja6RsnldzbDD0Mmy+vHhzqVqgTrE= - - - Headers/CBLBlob.h - - hash - - c9wrfsp59BXDSyReg12o2Po+cv4= - - hash2 - - Y4yKVBYIx+lb3kNGhRy22NnXZeHWh3jEbvBKtW1ltW0= - - - Headers/CBLDatabase.h - - hash - - NYZQZQXPcoZjUxSskTKMbFTtfEs= - - hash2 - - eR0+s8tSHVJcRZQ+b/Bsy8Dwk0MzHKyNNQq13knFdNg= - - - Headers/CBLDocument.h - - hash - - S3hpS7s7ABMPp/xIHp40bIZ2zDY= - - hash2 - - Q3u39+jw+DDMyJT05O49q5U7oQCsYANy7SuFkAF8RPI= - - - Headers/CBLEncryptable.h - - hash - - 9VnNsW6nTmbUZsOi5TNUNyZy/T0= - - hash2 - - MZsIB84TTINDvRCzPQru3YwqBDaGXI55riUtunTC4lM= - - - Headers/CBLLog.h - - hash - - +8orYUMXwYW07B/VnRbWTs5OlAE= - - hash2 - - 4s4E7+5HXjYEMOAe3wKAXzgx7GtnuYPH9YOCreNZaNU= - - - Headers/CBLPlatform.h - - hash - - Vln3jO3elRtPHV4FULtBxtrXSUk= - - hash2 - - 6ROIjrWkUahV+l1yjp42zPUHABX2KYSQ9HgFauZYy28= - - - Headers/CBLQuery.h - - hash - - M/IyqT/W/EgCJE8gYzsjzftpl/w= - - hash2 - - fs17edkDGhtzruwoCVryjHMG1yHlWr6c9nFsP7zazm0= - - - Headers/CBLReplicator.h - - hash - - hn5+NMXE5E7UMZYm+X2NIa6IPYE= - - hash2 - - tywTmF0sVnjwU65PFHB/ctp9MUAfCFRDIKyWOjPfVj8= - - - Headers/CBL_Compat.h - - hash - - XSqrNRZlB1pOQDycn0aetrmCffU= - - hash2 - - 1f6udyu/EAf/xokKIROoYHKjdwL6/Scu6Ox3UdgoEQI= - - - Headers/CBL_Edition.h - - hash - - d8fohT/W0JIVRJH9u5SZTGSPMwg= - - hash2 - - xOMVavZ1Zn9otz8TlndgvIYRXWJsVwXoSSmT72hqxA0= - - - Headers/CouchbaseLite.h - - hash - - OTH+XNdO5zXy7m3rDtWoqcoGCXE= - - hash2 - - +4Mv0HyZ5kcAJwpJ4brvdPIl1vxWUpi4S+PrrYRZBCw= - - - Headers/FLSlice.h - - hash - - cmN3q7yIi1XdUYayk+yfP2Tf104= - - hash2 - - n0XEYG5harm8xQHAXk9I29ImaRsw2QZxwRQVzU5hFN0= - - - Headers/Fleece+CoreFoundation.h - - hash - - pHWdmILGUd1LggyUOYcdtDOb7Qc= - - hash2 - - h7PCJLfFqsz7spNK4EeH7AxxL/NytJ1sGfPX+Y3t+is= - - - Headers/Fleece.h - - hash - - MuPrDAGcfk2SE1ykzADxNrcUV40= - - hash2 - - SLGw1j68v4ia8Ut+WZXF9SY28V+LYj4gnFjLTZV6CxE= - - - Modules/module.modulemap - - hash - - yIpU8739tGhwfSh7c7sH/aayqW8= - - hash2 - - yqP3qbqSMuRDf/0piBdAZ4Oe+O3HsYI7wmIn0O6mEf0= - - - - rules - - ^.* - - ^.*\.lproj/ - - optional - - weight - 1000 - - ^.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^.* - - ^.*\.lproj/ - - optional - - weight - 1000 - - ^.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Base\.lproj/ - - weight - 1010 - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist index d86e1c0..ab0eaed 100644 --- a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist +++ b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Info.plist @@ -13,8 +13,8 @@ CFBundleSignature ???? CFBundleShortVersionString - 3.0.17 + 3.1.7 CFBundleVersion - 1 + 5 diff --git a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite index 2fc4a32..7700283 100644 Binary files a/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite and b/libcblite-3.0.3/lib/ios/CouchbaseLite.xcframework/ios-arm64_x86_64-simulator/dSYMs/CouchbaseLite.framework.dSYM/Contents/Resources/DWARF/CouchbaseLite differ diff --git a/libcblite-3.0.3/lib/macos/libcblite.3.dylib b/libcblite-3.0.3/lib/macos/libcblite.3.dylib index 8405492..df83f2f 100755 Binary files a/libcblite-3.0.3/lib/macos/libcblite.3.dylib and b/libcblite-3.0.3/lib/macos/libcblite.3.dylib differ diff --git a/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.so b/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.so index 729a4d7..689cef9 100644 Binary files a/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.so and b/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.so differ diff --git a/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.stripped.so b/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.stripped.so index cea83ee..3b0b541 100755 Binary files a/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.stripped.so and b/libcblite-3.0.3/lib/x86_64-linux-android/libcblite.stripped.so differ diff --git a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.dll b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.dll index 69842ea..6dee52e 100644 Binary files a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.dll and b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.dll differ diff --git a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.lib b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.lib index bbc5b43..0ddf2fc 100644 Binary files a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.lib and b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.lib differ diff --git a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.stripped.dll b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.stripped.dll index c6e580d..6a8d445 100755 Binary files a/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.stripped.dll and b/libcblite-3.0.3/lib/x86_64-pc-windows-gnu/cblite.stripped.dll differ diff --git a/libcblite-3.0.3/lib/x86_64-unknown-linux-gnu/libcblite.so.3 b/libcblite-3.0.3/lib/x86_64-unknown-linux-gnu/libcblite.so.3 index 9cd9e68..d92c0ca 100644 Binary files a/libcblite-3.0.3/lib/x86_64-unknown-linux-gnu/libcblite.so.3 and b/libcblite-3.0.3/lib/x86_64-unknown-linux-gnu/libcblite.so.3 differ diff --git a/src/collection.rs b/src/collection.rs new file mode 100644 index 0000000..c399c18 --- /dev/null +++ b/src/collection.rs @@ -0,0 +1,103 @@ +use crate::{ + CblRef, Listener, ListenerToken, release, retain, + c_api::{ + CBLCollection, CBLCollectionChange, CBLCollection_AddChangeListener, CBLCollection_Scope, + CBLCollection_Name, CBLCollection_Count, + }, + scope::Scope, +}; + +pub static DEFAULT_NAME: &str = "_default"; + +#[derive(Debug, PartialEq, Eq)] +pub struct Collection { + cbl_ref: *mut CBLCollection, +} + +impl Collection { + pub(crate) fn retain(cbl_ref: *mut CBLCollection) -> Self { + Self { + cbl_ref: unsafe { retain(cbl_ref) }, + } + } + + /** Returns the scope of the collection. */ + pub fn scope(&self) -> Scope { + unsafe { Scope::retain(CBLCollection_Scope(self.get_ref())) } + } + + /** Returns the collection name. */ + pub fn name(&self) -> String { + unsafe { + CBLCollection_Name(self.get_ref()) + .to_string() + .unwrap_or_default() + } + } + + /** Returns the number of documents in the collection. */ + pub fn count(&self) -> u64 { + unsafe { CBLCollection_Count(self.get_ref()) } + } + + /** Registers a collection change listener callback. It will be called after one or more documents are changed on disk. */ + pub fn add_listener( + &mut self, + listener: CollectionChangeListener, + ) -> Listener { + unsafe { + let listener = Box::new(listener); + let ptr = Box::into_raw(listener); + + Listener::new( + ListenerToken { + cbl_ref: CBLCollection_AddChangeListener( + self.get_ref(), + Some(c_collection_change_listener), + ptr.cast(), + ), + }, + Box::from_raw(ptr), + ) + } + } +} + +impl CblRef for Collection { + type Output = *mut CBLCollection; + fn get_ref(&self) -> Self::Output { + self.cbl_ref + } +} + +impl Drop for Collection { + fn drop(&mut self) { + unsafe { release(self.get_ref()) } + } +} + +impl Clone for Collection { + fn clone(&self) -> Self { + Self::retain(self.get_ref()) + } +} + +/** A collection change listener callback, invoked after one or more documents are changed on disk. */ +type CollectionChangeListener = Box)>; + +#[no_mangle] +unsafe extern "C" fn c_collection_change_listener( + context: *mut ::std::os::raw::c_void, + change: *const CBLCollectionChange, +) { + let callback = context as *const CollectionChangeListener; + if let Some(change) = change.as_ref() { + let collection = Collection::retain(change.collection as *mut CBLCollection); + let doc_ids = std::slice::from_raw_parts(change.docIDs, change.numDocs as usize) + .iter() + .filter_map(|doc_id| doc_id.to_string()) + .collect(); + + (*callback)(collection, doc_ids); + } +} diff --git a/src/database.rs b/src/database.rs index bf89d8f..7ad40e1 100644 --- a/src/database.rs +++ b/src/database.rs @@ -29,8 +29,14 @@ use crate::{ CBL_DeleteDatabase, CBLEncryptionKey_FromPassword, FLString, kCBLMaintenanceTypeCompact, kCBLEncryptionNone, kCBLMaintenanceTypeFullOptimize, kCBLMaintenanceTypeIntegrityCheck, kCBLMaintenanceTypeOptimize, kCBLMaintenanceTypeReindex, CBL_CopyDatabase, + CBLDatabase_ScopeNames, CBLDatabase_CollectionNames, CBLDatabase_Scope, + CBLDatabase_Collection, CBLDatabase_CreateCollection, CBLDatabase_DeleteCollection, + CBLDatabase_DefaultScope, CBLDatabase_DefaultCollection, }, Listener, check_error, Error, CouchbaseLiteError, + collection::Collection, + scope::Scope, + MutableArray, }; use std::path::{Path, PathBuf}; use std::ptr; @@ -89,7 +95,8 @@ enum_from_primitive! { } /** A database change listener callback, invoked after one or more documents are changed on disk. */ -type ChangeListener = Box)>; +#[deprecated(note = "please use `CollectionChangeListener` on default collection instead")] +type DatabaseChangeListener = Box)>; #[no_mangle] unsafe extern "C" fn c_database_change_listener( @@ -98,7 +105,7 @@ unsafe extern "C" fn c_database_change_listener( num_docs: ::std::os::raw::c_uint, c_doc_ids: *mut FLString, ) { - let callback = context as *const ChangeListener; + let callback = context as *const DatabaseChangeListener; let database = Database::retain(db as *mut CBLDatabase); let doc_ids = std::slice::from_raw_parts(c_doc_ids, num_docs as usize) @@ -324,10 +331,157 @@ impl Database { } /** Returns the number of documents in the database. */ + #[deprecated(note = "please use `count` on the default collection instead")] pub fn count(&self) -> u64 { unsafe { CBLDatabase_Count(self.get_ref()) } } + /** Returns the names of all existing scopes in the database. + The scope 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. */ + pub fn scope_names(&self) -> Result> { + let mut error = CBLError::default(); + let array = unsafe { CBLDatabase_ScopeNames(self.get_ref(), &mut error) }; + + check_error(&error).map(|()| unsafe { + MutableArray::adopt(array) + .iter() + .map(|v| v.as_string().unwrap_or("").to_string()) + .collect() + }) + } + + /** Returns the names of all collections in the scope. */ + pub fn collection_names(&self, scope_name: String) -> Result> { + let scope_name = from_str(&scope_name); + let mut error = CBLError::default(); + let array = unsafe { + CBLDatabase_CollectionNames(self.get_ref(), scope_name.get_ref(), &mut error) + }; + + check_error(&error).map(|()| unsafe { + MutableArray::adopt(array) + .iter() + .map(|v| v.as_string().unwrap_or("").to_string()) + .collect() + }) + } + + /** Returns an existing scope with the given name. + The scope exists when there is at least one collection created under the scope. + The default scope is exception in that it will always exists even there are no collections under it. */ + pub fn scope(&self, scope_name: String) -> Result> { + let scope_name = from_str(&scope_name); + let mut error = CBLError::default(); + let scope = unsafe { CBLDatabase_Scope(self.get_ref(), scope_name.get_ref(), &mut error) }; + + check_error(&error).map(|()| { + if scope.is_null() { + None + } else { + Some(Scope::retain(scope)) + } + }) + } + + /** Returns the existing collection with the given name and scope. */ + pub fn collection( + &self, + collection_name: String, + scope_name: String, + ) -> Result> { + let collection_name = from_str(&collection_name); + let scope_name = from_str(&scope_name); + let mut error = CBLError::default(); + let collection = unsafe { + CBLDatabase_Collection( + self.get_ref(), + collection_name.get_ref(), + scope_name.get_ref(), + &mut error, + ) + }; + + check_error(&error).map(|()| { + if collection.is_null() { + None + } else { + Some(Collection::retain(collection)) + } + }) + } + + /** 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. + If the collection already exists, the existing collection will be returned. */ + pub fn create_collection( + &self, + collection_name: String, + scope_name: String, + ) -> Result { + let collection_name = from_str(&collection_name); + let scope_name = from_str(&scope_name); + let mut error = CBLError::default(); + let collection = unsafe { + CBLDatabase_CreateCollection( + self.get_ref(), + collection_name.get_ref(), + scope_name.get_ref(), + &mut error, + ) + }; + + check_error(&error).map(|()| Collection::retain(collection)) + } + + /** 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. */ + pub fn delete_collection(&self, collection_name: String, scope_name: String) -> Result<()> { + let collection_name = from_str(&collection_name); + let scope_name = from_str(&scope_name); + unsafe { + check_bool(|error| { + CBLDatabase_DeleteCollection( + self.get_ref(), + collection_name.get_ref(), + scope_name.get_ref(), + error, + ) + }) + } + } + + /** Returns the default scope. */ + pub fn default_scope(&self) -> Result { + let mut error = CBLError::default(); + let scope = unsafe { CBLDatabase_DefaultScope(self.get_ref(), &mut error) }; + + check_error(&error).map(|()| Scope::retain(scope)) + } + + /** Returns the default collection. */ + pub fn default_collection(&self) -> Result> { + let mut error = CBLError::default(); + let collection = unsafe { CBLDatabase_DefaultCollection(self.get_ref(), &mut error) }; + + check_error(&error).map(|()| { + if collection.is_null() { + None + } else { + Some(Collection::retain(collection)) + } + }) + } + //////// NOTIFICATIONS: /** Registers a database change listener function. It will be called after one or more @@ -340,7 +494,11 @@ impl Database { You must keep the `Listener` object as long as you need it. */ #[must_use] - pub fn add_listener(&mut self, listener: ChangeListener) -> Listener { + #[deprecated(note = "please use `add_listener` on default collection instead")] + pub fn add_listener( + &mut self, + listener: DatabaseChangeListener, + ) -> Listener { unsafe { let listener = Box::new(listener); let ptr = Box::into_raw(listener); diff --git a/src/document.rs b/src/document.rs index 305195b..dbe12e2 100644 --- a/src/document.rs +++ b/src/document.rs @@ -26,11 +26,18 @@ use crate::{ CBLDocument_ID, CBLDocument_MutableProperties, CBLDocument_Properties, CBLDocument_RevisionID, CBLDocument_Sequence, CBLDocument_SetJSON, CBLDocument_SetProperties, CBLError, FLString, kCBLConcurrencyControlFailOnConflict, - kCBLConcurrencyControlLastWriteWins, + kCBLConcurrencyControlLastWriteWins, CBLDocumentChange, CBLCollection, + CBLCollection_GetMutableDocument, CBLCollection_SaveDocument, + CBLCollection_SaveDocumentWithConcurrencyControl, + CBLCollection_SaveDocumentWithConflictHandler, CBLCollection_DeleteDocument, + CBLCollection_DeleteDocumentWithConcurrencyControl, CBLCollection_PurgeDocument, + CBLCollection_PurgeDocumentByID, CBLCollection_GetDocumentExpiration, + CBLCollection_SetDocumentExpiration, CBLCollection_AddDocumentChangeListener, }, slice::from_str, CblRef, CouchbaseLiteError, Database, Dict, Error, ListenerToken, MutableDict, Result, Timestamp, check_bool, check_failure, failure, release, retain, Listener, + collection::Collection, }; /** An in-memory copy of a document. */ @@ -73,15 +80,16 @@ unsafe extern "C" fn c_conflict_handler( /** A document change listener lets you detect changes made to a specific document after they are persisted to the database. */ -type ChangeListener = Box)>; +#[deprecated(note = "please use `CollectionDocumentChangeListener` instead")] +type DatabaseDocumentChangeListener = Box)>; #[no_mangle] -unsafe extern "C" fn c_document_change_listener( +unsafe extern "C" fn c_database_document_change_listener( context: *mut ::std::os::raw::c_void, db: *const CBLDatabase, c_doc_id: FLString, ) { - let callback = context as *const ChangeListener; + let callback = context as *const DatabaseDocumentChangeListener; let database = Database::retain(db as *mut CBLDatabase); (*callback)(&database, c_doc_id.to_string()); } @@ -91,6 +99,7 @@ unsafe extern "C" fn c_document_change_listener( impl Database { /** Reads a document from the database. Each call to this function returns a new object containing the document's current state. */ + #[deprecated(note = "please use `get_document` on default collection instead")] pub fn get_document(&self, id: &str) -> Result { unsafe { // we always get a mutable CBLDocument, @@ -114,6 +123,7 @@ impl Database { this one. This can lead to data loss! To avoid this, call `save_document_with_concurency_control` or `save_document_resolving` instead. */ + #[deprecated(note = "please use `get_document` on default collection instead")] pub fn save_document(&mut self, doc: &mut Document) -> Result<()> { unsafe { check_bool(|error| CBLDatabase_SaveDocument(self.get_ref(), doc.get_ref(), error)) @@ -125,6 +135,9 @@ impl Database { 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 `save_document_resolving` instead. */ + #[deprecated( + note = "please use `save_document_with_concurrency_control` on default collection instead" + )] pub fn save_document_with_concurency_control( &mut self, doc: &mut Document, @@ -146,6 +159,7 @@ impl Database { /** Saves a new or modified document to the database. This function is the same as `save_document`, except that it allows for custom conflict handling in the event that the document has been updated since `doc` was loaded. */ + #[deprecated(note = "please use `save_document_resolving` on default collection instead")] pub fn save_document_resolving( &mut self, doc: &mut Document, @@ -169,6 +183,7 @@ impl Database { } /** Deletes a document from the database. Deletions are replicated. */ + #[deprecated(note = "please use `delete_document` on default collection instead")] pub fn delete_document(&mut self, doc: &Document) -> Result<()> { unsafe { check_bool(|error| CBLDatabase_DeleteDocument(self.get_ref(), doc.get_ref(), error)) @@ -176,6 +191,9 @@ impl Database { } /** Deletes a document from the database. Deletions are replicated. */ + #[deprecated( + note = "please use `delete_document_with_concurrency_control` on default collection instead" + )] pub fn delete_document_with_concurency_control( &mut self, doc: &Document, @@ -196,6 +214,7 @@ impl Database { /** Purges a document. This removes all traces of the document from the database. Purges are _not_ replicated. If the document is changed on a server, it will be re-created */ + #[deprecated(note = "please use `purge_document` on default collection instead")] pub fn purge_document(&mut self, doc: &Document) -> Result<()> { unsafe { check_bool(|error| CBLDatabase_PurgeDocument(self.get_ref(), doc.get_ref(), error)) @@ -203,6 +222,7 @@ impl Database { } /** Purges a document, given only its ID. */ + #[deprecated(note = "please use `purge_document_by_id` on default collection instead")] pub fn purge_document_by_id(&mut self, id: &str) -> Result<()> { unsafe { check_bool(|error| { @@ -214,6 +234,7 @@ impl Database { /** Returns the time, if any, at which a given document will expire and be purged. Documents don't normally expire; you have to call `set_document_expiration` to set a document's expiration time. */ + #[deprecated(note = "please use `document_expiration` on default collection instead")] pub fn document_expiration(&self, doc_id: &str) -> Result> { unsafe { let mut error = CBLError::default(); @@ -231,6 +252,7 @@ impl Database { } /** Sets or clears the expiration time of a document. */ + #[deprecated(note = "please use `set_document_espiration` on default collection instead")] pub fn set_document_expiration(&mut self, doc_id: &str, when: Option) -> Result<()> { let exp: i64 = match when { Some(Timestamp(n)) => n, @@ -258,11 +280,12 @@ impl Database { You must keep the Listener object as long as you need it */ #[must_use] + #[deprecated(note = "please use `add_document_change_listener` on default collection instead")] pub fn add_document_change_listener( &self, document: &Document, - listener: ChangeListener, - ) -> Listener { + listener: DatabaseDocumentChangeListener, + ) -> Listener { unsafe { let listener = Box::new(listener); let ptr = Box::into_raw(listener); @@ -270,7 +293,211 @@ impl Database { ListenerToken::new(CBLDatabase_AddDocumentChangeListener( self.get_ref(), CBLDocument_ID(document.get_ref()), - Some(c_document_change_listener), + Some(c_database_document_change_listener), + ptr.cast(), + )), + Box::from_raw(ptr), + ) + } + } +} + +//////// COLLECTION'S DOCUMENT API: + +/** A document change listener lets you detect changes made to a specific document after they +are persisted to the collection. */ +type CollectionDocumentChangeListener = Box)>; + +#[no_mangle] +unsafe extern "C" fn c_collection_document_change_listener( + context: *mut ::std::os::raw::c_void, + change: *const CBLDocumentChange, +) { + let callback = context as *const CollectionDocumentChangeListener; + if let Some(change) = change.as_ref() { + let collection = Collection::retain(change.collection as *mut CBLCollection); + (*callback)(collection, change.docID.to_string()); + } +} + +impl Collection { + /** 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.) */ + pub fn get_document(&self, id: &str) -> Result { + unsafe { + // we always get a mutable CBLDocument, + // since Rust doesn't let us have MutableDocument subclass. + let mut error = CBLError::default(); + let doc = CBLCollection_GetMutableDocument( + self.get_ref(), + from_str(id).get_ref(), + &mut error, + ); + if doc.is_null() { + return if error.code == 0 { + Err(Error::cbl_error(CouchbaseLiteError::NotFound)) + } else { + failure(error) + }; + } + Ok(Document::wrap(doc)) + } + } + + /** Saves a (mutable) document to the collection. */ + pub fn save_document(&mut self, doc: &mut Document) -> Result<()> { + unsafe { + check_bool(|error| CBLCollection_SaveDocument(self.get_ref(), doc.get_ref(), error)) + } + } + + /** 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. */ + pub fn save_document_with_concurency_control( + &mut self, + doc: &mut Document, + concurrency: ConcurrencyControl, + ) -> Result<()> { + let c_concurrency = concurrency as u8; + unsafe { + check_bool(|error| { + CBLCollection_SaveDocumentWithConcurrencyControl( + self.get_ref(), + doc.get_ref(), + c_concurrency, + error, + ) + }) + } + } + + /** 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. */ + pub fn save_document_resolving( + &mut self, + doc: &mut Document, + conflict_handler: ConflictHandler, + ) -> Result { + unsafe { + let callback = conflict_handler as *mut std::ffi::c_void; + match check_bool(|error| { + CBLCollection_SaveDocumentWithConflictHandler( + self.get_ref(), + doc.get_ref(), + Some(c_conflict_handler), + callback, + error, + ) + }) { + Ok(_) => Ok(doc.clone()), + Err(err) => Err(err), + } + } + } + + /** Deletes a document from the collection. Deletions are replicated. */ + pub fn delete_document(&mut self, doc: &Document) -> Result<()> { + unsafe { + check_bool(|error| CBLCollection_DeleteDocument(self.get_ref(), doc.get_ref(), error)) + } + } + + /** Deletes a document from the collection. Deletions are replicated. */ + pub fn delete_document_with_concurency_control( + &mut self, + doc: &Document, + concurrency: ConcurrencyControl, + ) -> Result<()> { + let c_concurrency = concurrency as u8; + unsafe { + check_bool(|error| { + CBLCollection_DeleteDocumentWithConcurrencyControl( + self.get_ref(), + doc.get_ref(), + c_concurrency, + error, + ) + }) + } + } + + /** 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. */ + pub fn purge_document(&mut self, doc: &Document) -> Result<()> { + unsafe { + check_bool(|error| CBLCollection_PurgeDocument(self.get_ref(), doc.get_ref(), error)) + } + } + + /** Purges a document, given only its ID. */ + pub fn purge_document_by_id(&mut self, id: &str) -> Result<()> { + unsafe { + check_bool(|error| { + CBLCollection_PurgeDocumentByID(self.get_ref(), from_str(id).get_ref(), error) + }) + } + } + + /** 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. */ + pub fn document_expiration(&self, doc_id: &str) -> Result> { + unsafe { + let mut error = CBLError::default(); + let exp = CBLCollection_GetDocumentExpiration( + self.get_ref(), + from_str(doc_id).get_ref(), + &mut error, + ); + match exp { + 0 => Ok(None), + _ if exp > 0 => Ok(Some(Timestamp(exp))), + _ => failure(error), + } + } + } + + /** Sets or clears the expiration time of a document. */ + pub fn set_document_expiration(&mut self, doc_id: &str, when: Option) -> Result<()> { + let exp: i64 = match when { + Some(Timestamp(n)) => n, + _ => 0, + }; + unsafe { + check_bool(|error| { + CBLCollection_SetDocumentExpiration( + self.get_ref(), + from_str(doc_id).get_ref(), + exp, + error, + ) + }) + } + } + + /** Registers a document change listener callback. It will be called after a specific document is changed on disk. */ + pub fn add_document_change_listener( + &self, + document: &Document, + listener: CollectionDocumentChangeListener, + ) -> Listener { + unsafe { + let listener = Box::new(listener); + let ptr = Box::into_raw(listener); + Listener::new( + ListenerToken::new(CBLCollection_AddDocumentChangeListener( + self.get_ref(), + CBLDocument_ID(document.get_ref()), + Some(c_collection_document_change_listener), ptr.cast(), )), Box::from_raw(ptr), diff --git a/src/index.rs b/src/index.rs index 579809e..349f90f 100644 --- a/src/index.rs +++ b/src/index.rs @@ -2,11 +2,14 @@ use crate::{ CblRef, Database, c_api::{ CBLValueIndexConfiguration, CBLDatabase_GetIndexNames, CBLDatabase_DeleteIndex, CBLError, - CBLDatabase_CreateValueIndex, + CBLDatabase_CreateValueIndex, CBLCollection_CreateValueIndex, CBLCollection_DeleteIndex, + CBLCollection_GetIndexNames, }, error::{Result, failure}, slice::from_str, QueryLanguage, Array, + collection::Collection, + check_error, }; pub struct ValueIndexConfiguration { @@ -33,6 +36,7 @@ impl ValueIndexConfiguration { } impl Database { + #[deprecated(note = "please use `create_index` on default collection instead")] pub fn create_index(&self, name: &str, config: &ValueIndexConfiguration) -> Result { let mut err = CBLError::default(); let slice = from_str(name); @@ -50,6 +54,7 @@ impl Database { failure(err) } + #[deprecated(note = "please use `delete_index` on default collection instead")] pub fn delete_index(&self, name: &str) -> Result { let mut err = CBLError::default(); let slice = from_str(name); @@ -60,8 +65,44 @@ impl Database { failure(err) } + #[deprecated(note = "please use `get_index_names` on default collection instead")] pub fn get_index_names(&self) -> Array { let arr = unsafe { CBLDatabase_GetIndexNames(self.get_ref()) }; Array::wrap(arr) } } + +impl Collection { + pub fn create_index(&self, name: &str, config: &ValueIndexConfiguration) -> Result { + let mut err = CBLError::default(); + let slice = from_str(name); + let r = unsafe { + CBLCollection_CreateValueIndex( + self.get_ref(), + slice.get_ref(), + config.get_ref(), + &mut err, + ) + }; + if !err { + return Ok(r); + } + failure(err) + } + + pub fn delete_index(&self, name: &str) -> Result { + let mut err = CBLError::default(); + let slice = from_str(name); + let r = unsafe { CBLCollection_DeleteIndex(self.get_ref(), slice.get_ref(), &mut err) }; + if !err { + return Ok(r); + } + failure(err) + } + + pub fn get_index_names(&self) -> Result { + let mut err = CBLError::default(); + let arr = unsafe { CBLCollection_GetIndexNames(self.get_ref(), &mut err) }; + check_error(&err).map(|()| Array::wrap(arr)) + } +} diff --git a/src/lib.rs b/src/lib.rs index 32d2568..8b1bf35 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,11 +29,13 @@ #![allow(clippy::cast_possible_wrap)] #![allow(clippy::copy_iterator)] #![allow(clippy::missing_panics_doc)] +#![allow(deprecated)] #[macro_use] extern crate enum_primitive; pub mod blob; +pub mod collection; pub mod database; pub mod document; pub mod encryptable; @@ -44,6 +46,7 @@ pub mod index; pub mod logging; pub mod query; pub mod replicator; +pub mod scope; pub mod slice; mod c_api; diff --git a/src/main.rs b/src/main.rs index cf7c3d9..12c4781 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#![allow(deprecated)] extern crate couchbase_lite; extern crate tempdir; diff --git a/src/replicator.rs b/src/replicator.rs index 30a443b..19cd64a 100644 --- a/src/replicator.rs +++ b/src/replicator.rs @@ -40,8 +40,11 @@ use crate::{ kCBLDocumentFlagsDeleted, kCBLProxyHTTP, kCBLProxyHTTPS, kCBLReplicatorBusy, kCBLReplicatorConnecting, kCBLReplicatorIdle, kCBLReplicatorOffline, kCBLReplicatorStopped, kCBLReplicatorTypePull, kCBLReplicatorTypePush, kCBLReplicatorTypePushAndPull, + CBLReplicator_IsDocumentPending2, CBLReplicator_PendingDocumentIDs2, + CBLReplicationCollection, }, MutableArray, Listener, error, + collection::Collection, }; // WARNING: THIS API IS UNIMPLEMENTED SO FAR @@ -326,7 +329,8 @@ pub enum EncryptionError { \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. */ -pub type PropertyEncryptor = fn( +#[deprecated(note = "please use `CollectionPropertyEncryptor` on default collection instead")] +pub type DefaultCollectionPropertyEncryptor = fn( document_id: Option, properties: Dict, key_path: Option, @@ -336,7 +340,7 @@ pub type PropertyEncryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] -pub extern "C" fn c_property_encryptor( +pub extern "C" fn c_default_collection_property_encryptor( context: *mut ::std::os::raw::c_void, document_id: FLString, properties: FLDict, @@ -353,7 +357,7 @@ pub extern "C" fn c_property_encryptor( let mut result = FLSliceResult_New(0); if let Some(input) = input.to_vec() { result = (*repl_conf_context) - .property_encryptor + .default_collection_property_encryptor .map(|callback| { callback( document_id.to_string(), @@ -397,11 +401,93 @@ pub extern "C" fn c_property_encryptor( } } +/** Callback that encrypts encryptable properties in documents pushed by the replicator. +\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. */ +pub type CollectionPropertyEncryptor = fn( + scope: Option, + collection: Option, + document_id: Option, + properties: Dict, + key_path: Option, + input: Vec, + algorithm: Option, + kid: Option, + error: &Error, +) -> std::result::Result, EncryptionError>; +#[no_mangle] +pub extern "C" fn c_collection_property_encryptor( + context: *mut ::std::os::raw::c_void, + scope: FLString, + collection: FLString, + document_id: FLString, + properties: FLDict, + key_path: FLString, + input: FLSlice, + algorithm: *mut FLStringResult, + kid: *mut FLStringResult, + cbl_error: *mut CBLError, +) -> FLSliceResult { + unsafe { + let repl_conf_context = context as *const ReplicationConfigurationContext; + let mut error = cbl_error.as_ref().map_or(Error::default(), Error::new); + + let mut result = FLSliceResult_New(0); + if let Some(input) = input.to_vec() { + result = (*repl_conf_context) + .collection_property_encryptor + .map(|callback| { + callback( + scope.to_string(), + collection.to_string(), + document_id.to_string(), + Dict::wrap(properties, &properties), + key_path.to_string(), + input, + algorithm.as_ref().and_then(|s| s.clone().to_string()), + kid.as_ref().and_then(|s| s.clone().to_string()), + &error, + ) + }) + .map_or(FLSliceResult_New(0), |v| match v { + Ok(v) => FLSlice_Copy(from_bytes(&v[..]).get_ref()), + Err(err) => { + match err { + EncryptionError::Temporary => { + error!("Encryption callback returned with transient error"); + error = Error { + code: ErrorCode::WebSocket(503), + internal_info: None, + }; + } + EncryptionError::Permanent => { + error!("Encryption callback returned with non transient error"); + error = Error::cbl_error(CouchbaseLiteError::Crypto); + } + } + + FLSliceResult::null() + } + }); + } else { + error!("Encryption input is None"); + error = Error::cbl_error(CouchbaseLiteError::Crypto); + } + + if error != Error::default() { + *cbl_error = error.as_cbl_error(); + } + result + } +} + /** Callback that decrypts encrypted encryptable properties in documents pulled by the replicator. \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. */ -pub type PropertyDecryptor = fn( +#[deprecated(note = "please use `CollectionPropertyDecryptor` on default collection instead")] +pub type DefaultCollectionPropertyDecryptor = fn( document_id: Option, properties: Dict, key_path: Option, @@ -411,7 +497,7 @@ pub type PropertyDecryptor = fn( error: &Error, ) -> std::result::Result, EncryptionError>; #[no_mangle] -pub extern "C" fn c_property_decryptor( +pub extern "C" fn c_default_collection_property_decryptor( context: *mut ::std::os::raw::c_void, document_id: FLString, properties: FLDict, @@ -428,7 +514,7 @@ pub extern "C" fn c_property_decryptor( let mut result = FLSliceResult_New(0); if let Some(input) = input.to_vec() { result = (*repl_conf_context) - .property_decryptor + .default_collection_property_decryptor .map(|callback| { callback( document_id.to_string(), @@ -472,21 +558,145 @@ pub extern "C" fn c_property_decryptor( } } +/** Callback that decrypts encrypted encryptable properties in documents pulled by the replicator. +\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. */ +pub type CollectionPropertyDecryptor = fn( + scope: Option, + collection: Option, + document_id: Option, + properties: Dict, + key_path: Option, + input: Vec, + algorithm: Option, + kid: Option, + error: &Error, +) -> std::result::Result, EncryptionError>; +#[no_mangle] +pub extern "C" fn c_collection_property_decryptor( + context: *mut ::std::os::raw::c_void, + scope: FLString, + collection: FLString, + document_id: FLString, + properties: FLDict, + key_path: FLString, + input: FLSlice, + algorithm: FLString, + kid: FLString, + cbl_error: *mut CBLError, +) -> FLSliceResult { + unsafe { + let repl_conf_context = context as *const ReplicationConfigurationContext; + let mut error = cbl_error.as_ref().map_or(Error::default(), Error::new); + + let mut result = FLSliceResult_New(0); + if let Some(input) = input.to_vec() { + result = (*repl_conf_context) + .collection_property_decryptor + .map(|callback| { + callback( + scope.to_string(), + collection.to_string(), + document_id.to_string(), + Dict::wrap(properties, &properties), + key_path.to_string(), + input.to_vec(), + algorithm.to_string(), + kid.to_string(), + &error, + ) + }) + .map_or(FLSliceResult_New(0), |v| match v { + Ok(v) => FLSlice_Copy(from_bytes(&v[..]).get_ref()), + Err(err) => { + match err { + EncryptionError::Temporary => { + error!("Decryption callback returned with transient error"); + error = Error { + code: ErrorCode::WebSocket(503), + internal_info: None, + }; + } + EncryptionError::Permanent => { + error!("Decryption callback returned with non transient error"); + error = Error::cbl_error(CouchbaseLiteError::Crypto); + } + } + + FLSliceResult::null() + } + }); + } else { + error!("Decryption input is None"); + error = Error::cbl_error(CouchbaseLiteError::Crypto); + } + + if error != Error::default() { + *cbl_error = error.as_cbl_error(); + } + result + } +} + #[derive(Default)] pub struct ReplicationConfigurationContext { + #[deprecated(note = "please use `collection.push_filter` on default collection instead")] pub push_filter: Option, + #[deprecated(note = "please use `collection.pull_filter` on default collection instead")] pub pull_filter: Option, + #[deprecated(note = "please use `collection.conflict_resolver` on default collection instead")] pub conflict_resolver: Option, - pub property_encryptor: Option, - pub property_decryptor: Option, + #[deprecated( + note = "please use `collection_property_encryptor` on default collection instead" + )] + pub default_collection_property_encryptor: Option, + #[deprecated( + note = "please use `collection_property_decryptor` on default collection instead" + )] + pub default_collection_property_decryptor: Option, + pub collection_property_encryptor: Option, + pub collection_property_decryptor: Option, +} + +pub struct ReplicationCollection { + pub collection: Collection, + pub conflict_resolver: Option, // Optional conflict-resolver callback. + pub push_filter: Option, // Optional callback to filter which docs are pushed. + pub pull_filter: Option, // Optional callback to validate incoming docs. + pub channels: MutableArray, // Optional set of channels to pull from + pub document_ids: MutableArray, // Optional set of document IDs to replicate +} + +impl ReplicationCollection { + pub fn to_cbl_replication_collection(&self) -> CBLReplicationCollection { + CBLReplicationCollection { + collection: self.collection.get_ref(), + conflictResolver: self + .conflict_resolver + .as_ref() + .and(Some(c_replication_conflict_resolver)), + pushFilter: self + .push_filter + .as_ref() + .and(Some(c_replication_push_filter)), + pullFilter: self + .pull_filter + .as_ref() + .and(Some(c_replication_pull_filter)), + channels: self.channels.get_ref(), + documentIDs: self.document_ids.get_ref(), + } + } } /** The configuration of a replicator. */ pub struct ReplicatorConfiguration { - pub database: Database, // The database to replicate - pub endpoint: Endpoint, // The address of the other database to replicate with + #[deprecated(note = "use collections instead")] + pub database: Option, // The database to replicate. When setting the database, ONLY the default collection will be used for replication. + pub endpoint: Endpoint, // The address of the other database to replicate with pub replicator_type: ReplicatorType, // Push, pull or both - pub continuous: bool, // Continuous replication? + pub continuous: bool, // Continuous replication? //-- Auto Purge: /** If auto purge is active, then the library will automatically purge any documents that the replicating @@ -511,8 +721,11 @@ pub struct ReplicatorConfiguration { pub pinned_server_certificate: Option>, // An X.509 cert to "pin" TLS connections to (PEM or DER) pub trusted_root_certificates: Option>, // Set of anchor certs (PEM format) //-- Filtering: + #[deprecated(note = "please use `collection.channels` on default collection instead")] pub channels: MutableArray, // Optional set of channels to pull from + #[deprecated(note = "please use `collection.document_ids` on default collection instead")] pub document_ids: MutableArray, // Optional set of document IDs to replicate + pub collections: Option>, // The collections to replicate with the target's endpoint (Required if the database is not set). //-- 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 @@ -553,9 +766,20 @@ impl Replicator { ) -> Result { unsafe { let headers = MutableDict::from_hashmap(&config.headers); + let mut collections: Option> = + config.collections.as_ref().map(|collections| { + collections + .iter() + .map(|c| c.to_cbl_replication_collection()) + .collect() + }); let cbl_config = CBLReplicatorConfiguration { - database: retain(config.database.get_ref()), + database: config + .database + .as_ref() + .map(|d| retain(d.get_ref())) + .unwrap_or(ptr::null_mut()), endpoint: config.endpoint.get_ref(), replicatorType: config.replicator_type.clone().into(), continuous: config.continuous, @@ -595,13 +819,27 @@ impl Replicator { .as_ref() .and(Some(c_replication_conflict_resolver)), propertyEncryptor: context - .property_encryptor + .default_collection_property_encryptor .as_ref() - .and(Some(c_property_encryptor)), + .and(Some(c_default_collection_property_encryptor)), propertyDecryptor: context - .property_decryptor + .default_collection_property_decryptor + .as_ref() + .and(Some(c_default_collection_property_decryptor)), + documentPropertyEncryptor: context + .collection_property_encryptor .as_ref() - .and(Some(c_property_decryptor)), + .and(Some(c_collection_property_encryptor)), + documentPropertyDecryptor: context + .collection_property_decryptor + .as_ref() + .and(Some(c_collection_property_decryptor)), + collections: if let Some(collections) = collections.as_mut() { + collections.as_mut_ptr() + } else { + ptr::null_mut() + }, + collectionCount: collections.as_ref().map(|c| c.len()).unwrap_or_default(), acceptParentDomainCookies: config.accept_parent_domain_cookies, context: std::ptr::addr_of!(*context) as *mut _, }; @@ -689,6 +927,7 @@ impl Replicator { /** Indicates which documents 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. */ + #[deprecated(note = "please use `pending_document_ids_2` instead")] pub fn pending_document_ids(&self) -> Result> { unsafe { let mut error = CBLError::default(); @@ -706,6 +945,29 @@ impl Replicator { } } + /** Indicates which documents 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. */ + pub fn pending_document_ids_2(&self, collection: Collection) -> Result> { + unsafe { + let mut error = CBLError::default(); + let docs: FLDict = CBLReplicator_PendingDocumentIDs2( + self.get_ref(), + collection.get_ref(), + std::ptr::addr_of_mut!(error), + ); + + check_error(&error).and_then(|()| { + if docs.is_null() { + return Err(Error::default()); + } + + let dict = Dict::wrap(docs, self); + Ok(dict.to_keys_hash_set()) + }) + } + } + /** Indicates whether the document with the given ID has local changes that have not yet been pushed to the server by this replicator. @@ -723,6 +985,23 @@ impl Replicator { } } + /** Indicates whether the document 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 pending_document_ids and + checking whether the result contains \p docID. See that function's documentation for details. */ + pub fn is_document_pending_2(&self, collection: Collection, doc_id: &str) -> Result { + unsafe { + let mut error = CBLError::default(); + let result = CBLReplicator_IsDocumentPending2( + self.get_ref(), + from_str(doc_id).get_ref(), + collection.get_ref(), + std::ptr::addr_of_mut!(error), + ); + check_error(&error).map(|_| result) + } + } + /** Adds a listener that will be called when the replicator's status changes. */ @@ -864,6 +1143,8 @@ unsafe extern "C" fn c_replicator_document_change_listener( id: doc_id, flags: document.flags, error: check_error(&document.error), + scope: document.scope.to_string(), + collection: document.collection.to_string(), }) }) .collect(); @@ -880,6 +1161,8 @@ pub struct ReplicatedDocument { pub id: String, // The document ID pub flags: u32, // Indicates whether the document was deleted or removed pub error: Result<()>, // Error, if document failed to replicate + pub scope: Option, + pub collection: Option, } /** Direction of document transfer. */ diff --git a/src/scope.rs b/src/scope.rs new file mode 100644 index 0000000..df6a3ca --- /dev/null +++ b/src/scope.rs @@ -0,0 +1,78 @@ +use crate::{ + CblRef, check_error, release, retain, + c_api::{CBLScope, CBLScope_Name, CBLScope_CollectionNames, CBLScope_Collection, CBLError}, + collection::Collection, + error::Result, + MutableArray, + slice::from_str, +}; + +#[derive(Debug, PartialEq, Eq)] +pub struct Scope { + cbl_ref: *mut CBLScope, +} + +impl Scope { + pub(crate) fn retain(cbl_ref: *mut CBLScope) -> Self { + Self { + cbl_ref: unsafe { retain(cbl_ref) }, + } + } + + /** Returns the name of the scope. */ + pub fn name(&self) -> String { + unsafe { + CBLScope_Name(self.get_ref()) + .to_string() + .unwrap_or_default() + } + } + + /** Returns the names of all collections in the scope. */ + pub fn collection_names(&self) -> Result> { + let mut error = CBLError::default(); + let array = unsafe { CBLScope_CollectionNames(self.get_ref(), &mut error) }; + + check_error(&error).map(|()| unsafe { + MutableArray::adopt(array) + .iter() + .map(|v| v.as_string().unwrap_or("").to_string()) + .collect() + }) + } + + /** Returns an existing collection in the scope with the given name.*/ + pub fn collection(&self, collection_name: String) -> Result> { + let collection_name = from_str(&collection_name); + let mut error = CBLError::default(); + let collection = + unsafe { CBLScope_Collection(self.get_ref(), collection_name.get_ref(), &mut error) }; + + check_error(&error).map(|()| { + if collection.is_null() { + None + } else { + Some(Collection::retain(collection)) + } + }) + } +} + +impl CblRef for Scope { + type Output = *mut CBLScope; + fn get_ref(&self) -> Self::Output { + self.cbl_ref + } +} + +impl Drop for Scope { + fn drop(&mut self) { + unsafe { release(self.get_ref()) } + } +} + +impl Clone for Scope { + fn clone(&self) -> Self { + Self::retain(self.get_ref()) + } +} diff --git a/src/wrapper.h b/src/wrapper.h index c6e4627..7ec713f 100644 --- a/src/wrapper.h +++ b/src/wrapper.h @@ -1 +1,2 @@ #include "cbl/CouchbaseLite.h" +#include "fleece/FLExpert.h" \ No newline at end of file diff --git a/tests/collection_tests.rs b/tests/collection_tests.rs new file mode 100644 index 0000000..a319c9a --- /dev/null +++ b/tests/collection_tests.rs @@ -0,0 +1,434 @@ +extern crate couchbase_lite; +use self::couchbase_lite::*; + +pub mod utils; + +use collection::DEFAULT_NAME; + +#[test] +fn create_delete_scopes_collections() { + utils::with_db(|db| { + let unknown = "unknwon".to_string(); + let new_scope = "new_scope".to_string(); + let new_collection_1 = "new_collection_1".to_string(); + let new_collection_2 = "new_collection_2".to_string(); + + // List scopes & collections + assert_eq!(db.scope_names().unwrap(), vec![DEFAULT_NAME]); + assert_eq!( + db.collection_names(DEFAULT_NAME.to_string()).unwrap(), + vec![DEFAULT_NAME] + ); + + assert_eq!( + db.collection_names(unknown.clone()).unwrap(), + Vec::::default() + ); + + // Get scope + assert!(db.scope(DEFAULT_NAME.to_string()).unwrap().is_some()); + assert!(db.scope(unknown.clone()).unwrap().is_none()); + assert_eq!( + db.default_scope().unwrap(), + db.scope(DEFAULT_NAME.to_string()).unwrap().unwrap() + ); + + // Get collection + assert!(db + .collection(DEFAULT_NAME.to_string(), DEFAULT_NAME.to_string()) + .unwrap() + .is_some()); + assert!(db + .collection(unknown.clone(), DEFAULT_NAME.to_string()) + .unwrap() + .is_none()); // Invalid collection => None + assert!(db + .collection(DEFAULT_NAME.to_string(), unknown.clone()) + .is_err()); // Invalid scope => Err + assert_eq!( + db.default_collection().unwrap().unwrap(), + db.collection(DEFAULT_NAME.to_string(), DEFAULT_NAME.to_string()) + .unwrap() + .unwrap() + ); + + // Add collection in default scope + { + let c1_default_scope = db + .create_collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap(); + + assert_eq!( + db.collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap() + .unwrap(), + c1_default_scope + ); + assert_eq!( + db.create_collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap(), + c1_default_scope + ); + + assert_eq!( + db.collection_names(DEFAULT_NAME.to_string()).unwrap(), + vec![DEFAULT_NAME.to_string(), new_collection_1.clone()] + ); + } + + // Add collection in new scope + { + let c2_new_scope = db + .create_collection(new_collection_2.clone(), new_scope.clone()) + .unwrap(); + + assert_eq!( + db.collection(new_collection_2.clone(), new_scope.clone()) + .unwrap() + .unwrap(), + c2_new_scope + ); + assert_eq!( + db.create_collection(new_collection_2.clone(), new_scope.clone()) + .unwrap(), + c2_new_scope + ); + + assert_eq!( + db.scope_names().unwrap(), + vec![DEFAULT_NAME.to_string(), new_scope.clone()] + ); + assert_eq!( + db.collection_names(new_scope.clone()).unwrap(), + vec![new_collection_2.clone()] + ); + } + + // Delete collections + assert!(db + .delete_collection(DEFAULT_NAME.to_string(), unknown.clone()) + .is_err()); // Invalid scope => Err + assert!(db + .delete_collection(unknown.clone(), DEFAULT_NAME.to_string()) + .is_ok()); // Invalid collection => Ok + assert!(db + .delete_collection(unknown.clone(), unknown.clone()) + .is_ok()); // Invalid collection & scope => Ok + + assert!(db + .delete_collection(new_collection_2.clone(), new_scope.clone()) + .is_ok()); + assert!(db.scope(new_scope.clone()).unwrap().is_none()); + assert_eq!(db.scope_names().unwrap(), vec![DEFAULT_NAME]); + assert!(db + .collection(new_collection_2.clone(), new_scope.clone()) + .unwrap() + .is_none()); + assert_eq!( + db.collection_names(new_scope.clone()).unwrap(), + Vec::::default() + ); + + assert!(db + .delete_collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .is_ok()); + assert!(db.scope(DEFAULT_NAME.to_string()).unwrap().is_some()); // Default scope kept + assert!(db + .collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap() + .is_none()); + + assert!(db + .delete_collection(DEFAULT_NAME.to_string(), DEFAULT_NAME.to_string()) + .is_err()); // Impossible to delete default collection + }); +} + +#[test] +fn collections_accessors() { + utils::with_db(|db| { + // Setup + let new_scope = "new_scope".to_string(); + let new_collection_1 = "new_collection_1".to_string(); + let new_collection_2 = "new_collection_2".to_string(); + + let c1_default_scope = db + .create_collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap(); + assert_eq!( + db.collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap() + .unwrap(), + c1_default_scope + ); + + let c2_new_scope = db + .create_collection(new_collection_2.clone(), new_scope.clone()) + .unwrap(); + assert_eq!( + db.collection(new_collection_2.clone(), new_scope.clone()) + .unwrap() + .unwrap(), + c2_new_scope + ); + + let c1_new_scope = db + .create_collection(new_collection_1.clone(), new_scope.clone()) + .unwrap(); + assert_eq!( + db.collection(new_collection_1.clone(), new_scope.clone()) + .unwrap() + .unwrap(), + c1_new_scope + ); + + let default_scope = db.scope(DEFAULT_NAME.to_string()).unwrap().unwrap(); + let new_actual_scope = db.scope(new_scope.clone()).unwrap().unwrap(); + + // Scope + assert_eq!(c1_default_scope.scope(), default_scope); + assert_eq!(c2_new_scope.scope(), new_actual_scope); + assert_eq!(c1_new_scope.scope(), new_actual_scope); + + // Name + assert_eq!(c1_default_scope.name(), new_collection_1.clone()); + assert_eq!(c2_new_scope.name(), new_collection_2.clone()); + assert_eq!(c1_new_scope.name(), new_collection_1.clone()); + + // Count + assert_eq!(c1_default_scope.count(), 0); + assert_eq!(c2_new_scope.count(), 0); + assert_eq!(c1_new_scope.count(), 0); + }); +} + +#[test] +fn scope_accessors() { + utils::with_db(|db| { + // Setup + let new_scope = "new_scope".to_string(); + let new_collection_1 = "new_collection_1".to_string(); + let new_collection_2 = "new_collection_2".to_string(); + + let c1_default_scope = db + .create_collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap(); + assert_eq!( + db.collection(new_collection_1.clone(), DEFAULT_NAME.to_string()) + .unwrap() + .unwrap(), + c1_default_scope + ); + + let c2_new_scope = db + .create_collection(new_collection_2.clone(), new_scope.clone()) + .unwrap(); + assert_eq!( + db.collection(new_collection_2.clone(), new_scope.clone()) + .unwrap() + .unwrap(), + c2_new_scope + ); + + let c1_new_scope = db + .create_collection(new_collection_1.clone(), new_scope.clone()) + .unwrap(); + assert_eq!( + db.collection(new_collection_1.clone(), new_scope.clone()) + .unwrap() + .unwrap(), + c1_new_scope + ); + + let default_scope = db.scope(DEFAULT_NAME.to_string()).unwrap().unwrap(); + let new_actual_scope = db.scope(new_scope.clone()).unwrap().unwrap(); + + // Name + assert_eq!(default_scope.name(), DEFAULT_NAME.to_string()); + assert_eq!(new_actual_scope.name(), new_scope.clone()); + + // Collections + assert_eq!( + default_scope.collection_names().unwrap(), + vec![DEFAULT_NAME.to_string(), new_collection_1.clone()] + ); + assert_eq!( + new_actual_scope.collection_names().unwrap(), + vec![new_collection_2.clone(), new_collection_1.clone()] + ); + + assert!(default_scope + .collection("unknwon".to_string()) + .unwrap() + .is_none()); + + assert_eq!( + default_scope + .collection(new_collection_1.clone()) + .unwrap() + .unwrap(), + c1_default_scope + ); + assert_eq!( + new_actual_scope + .collection(new_collection_2.clone()) + .unwrap() + .unwrap(), + c2_new_scope + ); + assert_eq!( + new_actual_scope + .collection(new_collection_1.clone()) + .unwrap() + .unwrap(), + c1_new_scope + ); + }); +} + +#[test] +fn collection_documents() { + utils::with_db(|db| { + // Collection 1 + let mut collection_1 = db + .create_collection("collection_1".to_string(), DEFAULT_NAME.to_string()) + .unwrap(); + let mut doc_1 = Document::new_with_id("foo"); + doc_1 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_1 + .save_document(&mut doc_1) + .expect("save_document"); + + assert!(collection_1.get_document("foo").is_ok()); + assert!(db + .default_collection() + .unwrap() + .unwrap() + .get_document("foo") + .is_err()); // Document 1 not in default collection + + // Collection 2 + let mut collection_2 = db + .create_collection("collection_2".to_string(), "scope_1".to_string()) + .unwrap(); + assert!(collection_2.get_document("foo").is_err()); // Document 1 not in collection 2 + + let mut doc_2 = Document::new_with_id("foo"); + doc_2 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_2 + .save_document(&mut doc_2) + .expect("save_document"); + + assert!(collection_2.get_document("foo").is_ok()); + + // Collection 3 + let mut collection_3 = db + .create_collection("collection_3".to_string(), "scope_1".to_string()) + .unwrap(); + assert!(collection_3.get_document("foo").is_err()); // Document 2 not in collection 3 even though collections 2 & 3 are in the same scope + + let mut doc_3 = Document::new_with_id("foo"); + doc_3 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_3 + .save_document(&mut doc_3) + .expect("save_document"); + + assert!(collection_3.get_document("foo").is_ok()); + + // Delete documents + assert!(collection_1.delete_document(&doc_1).is_ok()); + assert!(collection_1.get_document("foo").unwrap().is_deleted()); + + assert!(collection_2.delete_document(&doc_2).is_ok()); + assert!(collection_2.get_document("foo").unwrap().is_deleted()); + + assert!(collection_3.delete_document(&doc_3).is_ok()); + assert!(collection_3.get_document("foo").unwrap().is_deleted()); + }); +} + +#[test] +fn queries() { + utils::with_db(|db| { + // Setup + { + let mut default_collection = db.default_collection().unwrap().unwrap(); + let mut doc_1 = Document::new_with_id("foo"); + doc_1 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + default_collection + .save_document(&mut doc_1) + .expect("save_document"); + + let mut collection_1 = db + .create_collection("collection_1".to_string(), DEFAULT_NAME.to_string()) + .unwrap(); + let mut doc_1 = Document::new_with_id("foo1"); + doc_1 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_1 + .save_document(&mut doc_1) + .expect("save_document"); + + let mut collection_2 = db + .create_collection("collection_2".to_string(), "scope_1".to_string()) + .unwrap(); + let mut doc_2 = Document::new_with_id("foo2"); + doc_2 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_2 + .save_document(&mut doc_2) + .expect("save_document"); + + let mut collection_3 = db + .create_collection("collection_3".to_string(), "scope_1".to_string()) + .unwrap(); + let mut doc_3 = Document::new_with_id("foo3"); + doc_3 + .set_properties_as_json(r#"{"foo":true,"bar":true}"#) + .expect("set_properties_as_json"); + collection_3 + .save_document(&mut doc_3) + .expect("save_document"); + } + + fn query(db: &mut Database, query: &str) -> Vec { + let query = Query::new(db, QueryLanguage::N1QL, query).expect("create query"); + + let mut query_result = query.execute().expect("execute"); + + let mut results = vec![]; + while let Some(row) = query_result.next() { + results.push(row.get(0).as_string().unwrap_or("").to_string()); + } + results + } + + assert_eq!(query(db, "SELECT _id FROM _"), vec!["foo".to_string()]); // Default collection + assert_eq!( + query(db, "SELECT _id FROM collection_1"), + vec!["foo1".to_string()] + ); // Collection must be in default scope with this query + assert_eq!( + query(db, "SELECT _id FROM _default.collection_1"), + vec!["foo1".to_string()] + ); + assert_eq!( + query(db, "SELECT _id FROM scope_1.collection_2"), + vec!["foo2".to_string()] + ); + assert_eq!( + query(db, "SELECT _id FROM scope_1.collection_3"), + vec!["foo3".to_string()] + ); + }); +} diff --git a/tests/lib_test.rs b/tests/lib_test.rs index 82db92b..375ec19 100644 --- a/tests/lib_test.rs +++ b/tests/lib_test.rs @@ -6,5 +6,5 @@ use couchbase_lite::*; #[test] fn couchbase_lite_c_version_test() { - assert_eq!(couchbase_lite_c_version(), "3.0.17".to_string()); + assert_eq!(couchbase_lite_c_version(), "3.1.7".to_string()); } diff --git a/tests/replicator_tests.rs b/tests/replicator_tests.rs index 607baed..6388e72 100644 --- a/tests/replicator_tests.rs +++ b/tests/replicator_tests.rs @@ -549,13 +549,13 @@ fn decryptor_err_permanent( #[test] fn encryption_ok_decryption_ok() { let context1 = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; let context2 = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -619,8 +619,8 @@ fn encryption_error_temporary() { }; let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor_err_temporary), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor_err_temporary), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -654,8 +654,8 @@ fn encryption_error_temporary() { // Change local DB 1 replicator to make the encryption work let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -681,8 +681,8 @@ fn decryption_error_temporary() { }; let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor_err_temporary), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor_err_temporary), ..Default::default() }; @@ -716,8 +716,8 @@ fn decryption_error_temporary() { // Change local DB replicator to make the decryption work let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -743,8 +743,8 @@ fn encryption_error_permanent() { }; let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor_err_permanent), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor_err_permanent), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -778,8 +778,8 @@ fn encryption_error_permanent() { // Change local DB 1 replicator to make the encryption work let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; @@ -825,8 +825,8 @@ fn decryption_error_permanent() { }; let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor_err_permanent), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor_err_permanent), ..Default::default() }; @@ -860,8 +860,8 @@ fn decryption_error_permanent() { // Change local DB replicator to make the decryption work let context = ReplicationConfigurationContext { - property_encryptor: Some(encryptor), - property_decryptor: Some(decryptor), + default_collection_property_encryptor: Some(encryptor), + default_collection_property_decryptor: Some(decryptor), ..Default::default() }; diff --git a/tests/utils.rs b/tests/utils.rs index 4490afe..2f4140f 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -96,7 +96,7 @@ fn generate_replication_configuration( config: ReplicationTestConfiguration, ) -> ReplicatorConfiguration { ReplicatorConfiguration { - database: local_db.clone(), + database: Some(local_db.clone()), endpoint: Endpoint::new_with_local_db(central_db), replicator_type: config.replicator_type, continuous: config.continuous, @@ -111,6 +111,7 @@ fn generate_replication_configuration( trusted_root_certificates: None, channels: MutableArray::default(), document_ids: config.document_ids, + collections: None, accept_parent_domain_cookies: false, } }