Skip to content

Commit

Permalink
Merge branch '3.1.x' into test_parameters_3.1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Nao-ris committed Sep 5, 2024
2 parents dc530d8 + b81a19f commit 1fc0ce9
Show file tree
Hide file tree
Showing 148 changed files with 15,594 additions and 5,293 deletions.
Binary file not shown.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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``


Expand Down
Binary file modified libcblite-3.0.3/.DS_Store
Binary file not shown.
Binary file modified libcblite-3.0.3/include/.DS_Store
Binary file not shown.
172 changes: 172 additions & 0 deletions libcblite-3.0.3/include/cbl++/Base.hh
Original file line number Diff line number Diff line change
@@ -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 <algorithm>
#include <functional>
#include <cassert>
#include <memory>
#include <utility>

#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... Args>
class ListenerToken {
public:
using Callback = std::function<void(Args...)>;

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> _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
173 changes: 173 additions & 0 deletions libcblite-3.0.3/include/cbl++/Blob.hh
Original file line number Diff line number Diff line change
@@ -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 <string>

// 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
Loading

0 comments on commit 1fc0ce9

Please sign in to comment.