Couchbase Lite C++
Couchbase Lite C++ API
Loading...
Searching...
No Matches
Blob.hh
Go to the documentation of this file.
1//
2// Blob.hh
3//
4// Copyright (c) 2019 Couchbase, Inc All rights reserved.
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17//
18
19#pragma once
20#include "cbl++/Base.hh"
21#include "cbl++/Document.hh"
22#include "cbl/CBLBlob.h"
23#include "cbl/CBLDatabase.h"
24#include "fleece/Mutable.hh"
25#include <optional>
26#include <string>
27#include <string_view>
28
29
31
32namespace cbl {
33 class BlobReadStream;
34 class BlobWriteStream;
35
39 class Blob : protected RefCounted {
40 public:
44 static bool isBlob(fleece::Dict d) {return FLDict_IsBlob(d);}
45
51 Blob(std::optional<std::string_view> contentType, slice contents) {
52 slice ctype;
53 if ( contentType ) ctype = slice(*contentType);
54 _ref = (CBLRefCounted*) CBLBlob_CreateWithData(ctype, contents);
55 }
56
60 inline Blob(std::optional<std::string_view> contentType, BlobWriteStream& writer);
61
66 Blob(fleece::Dict d)
67 :RefCounted((CBLRefCounted*) FLDict_GetBlob(d))
68 { }
69
71 bool blobEquals(const Blob& other) const {return CBLBlob_Equals(ref(), other.ref());}
72
74 uint64_t length() const {return CBLBlob_Length(ref());}
75
77 std::string contentType() const {return internal::asString(CBLBlob_ContentType(ref()));}
78
80 std::string digest() const {return internal::asString(CBLBlob_Digest(ref()));}
81
84 fleece::Dict properties() const {return CBLBlob_Properties(ref());}
85
87 std::string createJSON() const {return alloc_slice(CBLBlob_CreateJSON(ref())).asString();}
88
91 operator fleece::Dict() const {return properties();}
92
100 CBLError error;
101 fleece::alloc_slice content = CBLBlob_Content(ref(), &error);
102 internal::check(content.buf, error);
103 return content;
104 }
105
111
112 protected:
113
115
116 private:
117 friend class Database;
118 struct adopt_t {};
119 inline static constexpr adopt_t adopt{};
120
121 Blob(CBLBlob* _cbl_nullable cObj, adopt_t) { _ref = (CBLRefCounted*)cObj; }
122 };
123
126 public:
129
133 CBLError error;
134 _stream = CBLBlob_OpenContentStream(blob->ref(), &error);
135 internal::check(_stream, error);
136 }
137
140 CBLBlobReader_Close(_stream);
141 }
142
147 size_t read(void *dst, size_t maxLength) {
148 CBLError error;
149 int bytesRead = CBLBlobReader_Read(_stream, dst, maxLength, &error);
150 internal::check(bytesRead >= 0, error);
151 return size_t(bytesRead);
152 }
153
158 int64_t seek(int64_t offset, SeekBase base) {
159 CBLError error{};
160 int64_t ret = CBLBlobReader_Seek(_stream, offset, base, &error);
161 internal::check(ret >= 0, error);
162 return ret;
163 }
164
166 uint64_t position() {
167 return CBLBlobReader_Position(_stream);
168 }
169
170 private:
171 CBLBlobReadStream* _cbl_nullable _stream {nullptr};
172 };
173
175 return new BlobReadStream(this);
176 }
177
180 public:
183 CBLError error;
184 _writer = CBLBlobWriter_Create(db.ref(), &error);
185 internal::check(_writer, error);
186 }
187
191 CBLBlobWriter_Close(_writer);
192 }
193
196 void write(fleece::slice data) {
197 write(data.buf, data.size);
198 }
199
203 void write(const void *src, size_t length) {
204 CBLError error;
205 if (!CBLBlobWriter_Write(_writer, src, length, &error))
206 internal::check(false, error);
207 }
208
209 private:
210 friend class Blob;
211 CBLBlobWriteStream* _cbl_nullable _writer {nullptr};
212 };
213
214 inline Blob::Blob(std::optional<std::string_view> contentType, BlobWriteStream& writer) {
215 slice ctype;
216 if ( contentType ) ctype = slice(*contentType);
217 _ref = (CBLRefCounted*) CBLBlob_CreateWithStream(ctype, writer._writer);
218 writer._writer = nullptr;
219 }
220
221 inline Blob Database::getBlob(fleece::Dict properties) const {
222 CBLError error{};
223 const CBLBlob* blob = CBLDatabase_GetBlob(this->ref(), properties, &error);
224 // Per the C API: null with error.code==0 is a legitimate "not found";
225 // null with a populated error is a real failure -> throw.
226 internal::check(blob != nullptr || error.code == 0, error);
227 return {const_cast<CBLBlob*>(blob), Blob::adopt};
228 }
229
230 inline void Database::saveBlob(const Blob& blob) {
231 CBLError error{};
232 internal::check(CBLDatabase_SaveBlob(this->ref(), blob.ref(), &error), error);
233 }
234}
235
#define CBL_REFCOUNTED_BOILERPLATE(CLASS, SUPER, C_TYPE)
Definition Base.hh:160
#define _cbl_nullable
#define CBL_ASSUME_NONNULL_END
#define CBL_ASSUME_NONNULL_BEGIN
A reference to a binary data blob associated with a document.
Definition Blob.hh:39
std::string contentType() const
Returns a blob's MIME type, if its metadata has a content_type property.
Definition Blob.hh:77
Blob(std::optional< std::string_view > contentType, slice contents)
Creates a new blob, given its contents as a single block of data.
Definition Blob.hh:51
Blob() noexcept
Constructs a null reference (one that points to no object).
Definition Blob.hh:114
uint64_t length() const
Returns the length in bytes of a blob's content (from its length property).
Definition Blob.hh:74
friend class Database
Definition Blob.hh:117
std::string digest() const
Returns the cryptographic digest of a blob's content (from its digest property).
Definition Blob.hh:80
std::string createJSON() const
Returns the JSON representation of the blob's metadata dictionary.
Definition Blob.hh:87
bool blobEquals(const Blob &other) const
Compares whether this blob and another are equal based on their content.
Definition Blob.hh:71
CBLBlob *_Nullable ref() const
Returns a pointer to the underlying C object (CBLBlob), or NULL if this is a null reference.
Definition Blob.hh:114
static bool isBlob(fleece::Dict d)
Returns true if a dictionary in a document is a blob reference.
Definition Blob.hh:44
Blob(fleece::Dict d)
Creates a Blob instance on an existing blob reference in a document or query result.
Definition Blob.hh:66
BlobReadStream * openContentStream()
Opens a stream for reading a blob's content.
Definition Blob.hh:174
alloc_slice loadContent()
Reads the blob's content into memory and returns it.
Definition Blob.hh:99
fleece::Dict properties() const
Returns a blob's metadata.
Definition Blob.hh:84
A stream for reading a blob's content from the database.
Definition Blob.hh:125
size_t read(void *dst, size_t maxLength)
Reads data from a blob.
Definition Blob.hh:147
~BlobReadStream()
Closes the underlying read stream.
Definition Blob.hh:139
uint64_t position()
Returns the current position of a CBLBlobReadStream.
Definition Blob.hh:166
int64_t seek(int64_t offset, SeekBase base)
Sets the position of a CBLBlobReadStream.
Definition Blob.hh:158
CBLSeekBase SeekBase
Alias for the C CBLSeekBase enum describing the reference point used by seek.
Definition Blob.hh:128
BlobReadStream(Blob *blob)
Opens a stream for reading a blob's content.
Definition Blob.hh:132
A stream for writing a new blob to the database.
Definition Blob.hh:179
void write(fleece::slice data)
Writes data to a new blob.
Definition Blob.hh:196
BlobWriteStream(Database db)
Create a stream to write a new blob to the database.
Definition Blob.hh:182
void write(const void *src, size_t length)
Writes data to a new blob.
Definition Blob.hh:203
~BlobWriteStream()
Closes the blob-writing stream if it has not been handed off to a Blob constructor.
Definition Blob.hh:190
friend class Blob
Definition Blob.hh:210
A Couchbase Lite database, which is a container for collections of documents.
Definition Database.hh:147
void saveBlob(const Blob &blob)
Save a new Blob object into the database without associating it with any documents.
Definition Blob.hh:230
Blob getBlob(fleece::Dict properties) const
Get a Blob from the database using the Blob properties.
Definition Blob.hh:221
CBLDatabase *_Nullable ref() const
Returns a pointer to the underlying C object (CBLDatabase), or NULL if this is a null reference.
Definition Database.hh:411
_cbl_warn_unused CBLBlob * CBLBlob_CreateWithData(FLString contentType, FLSlice contents)
bool CBLBlob_Equals(CBLBlob *blob, CBLBlob *anotherBlob)
bool CBLDatabase_SaveBlob(CBLDatabase *db, CBLBlob *blob, CBLError *_cbl_nullable outError)
int64_t CBLBlobReader_Seek(CBLBlobReadStream *stream, int64_t offset, CBLSeekBase base, CBLError *_cbl_nullable outError)
bool FLDict_IsBlob(FLDict _cbl_nullable)
_cbl_warn_unused CBLBlob * CBLBlob_CreateWithStream(FLString contentType, CBLBlobWriteStream *writer)
uint64_t CBLBlobReader_Position(CBLBlobReadStream *stream)
int CBLBlobReader_Read(CBLBlobReadStream *stream, void *dst, size_t maxLength, CBLError *_cbl_nullable outError)
FLString CBLBlob_Digest(const CBLBlob *)
_cbl_warn_unused FLStringResult CBLBlob_CreateJSON(const CBLBlob *blob)
FLString CBLBlob_ContentType(const CBLBlob *)
CBLSeekBase
void CBLBlobWriter_Close(CBLBlobWriteStream *_cbl_nullable)
const CBLBlob *_cbl_nullable CBLDatabase_GetBlob(CBLDatabase *db, FLDict properties, CBLError *_cbl_nullable outError)
struct CBLBlobReadStream CBLBlobReadStream
FLDict CBLBlob_Properties(const CBLBlob *)
struct CBLBlobWriteStream CBLBlobWriteStream
_cbl_warn_unused CBLBlobReadStream *_cbl_nullable CBLBlob_OpenContentStream(const CBLBlob *blob, CBLError *_cbl_nullable)
const CBLBlob *_cbl_nullable FLDict_GetBlob(FLDict _cbl_nullable blobDict)
_cbl_warn_unused CBLBlobWriteStream *_cbl_nullable CBLBlobWriter_Create(CBLDatabase *db, CBLError *_cbl_nullable)
struct CBLBlob CBLBlob
_cbl_warn_unused FLSliceResult CBLBlob_Content(const CBLBlob *blob, CBLError *_cbl_nullable outError)
uint64_t CBLBlob_Length(const CBLBlob *)
void CBLBlobReader_Close(CBLBlobReadStream *_cbl_nullable)
bool CBLBlobWriter_Write(CBLBlobWriteStream *writer, const void *data, size_t length, CBLError *_cbl_nullable outError)
struct CBLRefCounted CBLRefCounted
Definition Base.hh:46
fleece::slice slice
Convenience alias for fleece::slice, a non-owning view of a byte range.
Definition Base.hh:49
fleece::alloc_slice alloc_slice
Convenience alias for fleece::alloc_slice, an owning byte buffer.
Definition Base.hh:51