Apache OpenDALâ„¢ C++ Binding
The C++ binding for Apache OpenDALâ„¢
Loading...
Searching...
No Matches
opendal.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. 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,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
22#include <cstring>
23#include <iostream>
24#include <memory>
25#include <optional>
26#include <string>
27#include <unordered_map>
28#include <vector>
29
30#include "data_structure.hpp"
31
32namespace opendal {
33
34namespace ffi {
35class Operator;
36class Reader;
37class Lister;
38} // namespace ffi
39
40class Reader;
41class Lister;
42
47class Operator {
48 public:
49 Operator() noexcept;
50
57 Operator(std::string_view scheme,
58 const std::unordered_map<std::string, std::string> &config = {});
59
60 // Disable copy and assign
61 Operator(const Operator &) = delete;
62 Operator &operator=(const Operator &) = delete;
63
64 // Enable move
65 Operator(Operator &&other) noexcept;
66 Operator &operator=(Operator &&other) noexcept;
67
68 ~Operator() noexcept;
69
75 bool Available() const;
76
85 std::string Read(std::string_view path);
86
93 void Write(std::string_view path, std::string_view data);
94
101 Reader GetReader(std::string_view path);
102
109 [[deprecated("Use Exists() instead.")]]
110 bool IsExist(std::string_view path);
111
118 bool Exists(std::string_view path);
119
125 void CreateDir(std::string_view path);
126
133 void Copy(std::string_view src, std::string_view dst);
134
141 void Rename(std::string_view src, std::string_view dst);
142
148 void Remove(std::string_view path);
149
156 Metadata Stat(std::string_view path);
157
165 std::vector<Entry> List(std::string_view path);
166
167 Lister GetLister(std::string_view path);
169
170 private:
171 void Destroy() noexcept;
172
173 ffi::Operator *operator_{nullptr};
174 };
175
185class Reader {
186 public:
187 Reader(Reader &&other) noexcept;
188
189 ~Reader() noexcept;
190
191 std::streamsize Read(void *s, std::streamsize n);
192
193 std::streampos Seek(std::streamoff off, std::ios_base::seekdir way);
194
195 private:
196 friend class Operator;
197
198 Reader(ffi::Reader *pointer) noexcept;
199
200 void Destroy() noexcept;
201
202 ffi::Reader *reader_{nullptr};
203};
204
211class ReaderStream : public std::istream {
212 public:
213 class ReaderStreamBuf : public std::streambuf {
214 public:
216 : reader_(std::move(reader)), buffer_start_pos_(0) {
217 setg(buffer_, buffer_, buffer_);
218 }
219
220 protected:
221 std::streamsize xsgetn(char *s, std::streamsize count) override {
222 std::streamsize total_read = 0;
223
224 while (total_read < count) {
225 if (gptr() < egptr()) {
226 std::streamsize available_bytes = egptr() - gptr();
227 std::streamsize to_copy =
228 std::min(available_bytes, count - total_read);
229 std::memcpy(s + total_read, gptr(), to_copy);
230 gbump(to_copy);
231 total_read += to_copy;
232 continue;
233 }
234
235 if (underflow() == traits_type::eof()) break;
236 }
237
238 return total_read;
239 }
240
241 int_type underflow() override {
242 if (gptr() < egptr()) {
243 return traits_type::to_int_type(*gptr());
244 }
245
246 // Update the buffer start position to current reader position
247 buffer_start_pos_ += (egptr() - eback());
248
249 std::streamsize n = reader_.Read(buffer_, sizeof(buffer_));
250 if (n <= 0) {
251 return traits_type::eof();
252 }
253
254 setg(buffer_, buffer_, buffer_ + n);
255 return traits_type::to_int_type(*gptr());
256 }
257
258 int_type uflow() override {
259 int_type result = underflow();
260 if (result != traits_type::eof()) {
261 gbump(1);
262 }
263 return result;
264 }
265
266 std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir,
267 std::ios_base::openmode which) override {
268 if (dir == std::ios_base::cur && off == 0) {
269 // tellg() case - return current position
270 return buffer_start_pos_ + (gptr() - eback());
271 }
272
273 // Actual seek operation
274 std::streampos new_pos = reader_.Seek(off, dir);
275 if (new_pos != std::streampos(-1)) {
276 buffer_start_pos_ = new_pos;
277 setg(buffer_, buffer_, buffer_);
278 }
279 return new_pos;
280 }
281
282 std::streampos seekpos(std::streampos pos,
283 std::ios_base::openmode which) override {
284 return seekoff(pos, std::ios_base::beg, which);
285 }
286
287 private:
288 Reader reader_;
289 char buffer_[8192];
290 std::streampos buffer_start_pos_;
291 };
292
294 : std::istream(&buf_), buf_(std::move(reader)) {}
295
296 private:
297 ReaderStreamBuf buf_;
298};
299
312class Lister {
313 public:
314 Lister(Lister &&other) noexcept;
315
316 ~Lister() noexcept;
317
324 class Iterator {
325 public:
326 using iterator_category = std::input_iterator_tag;
328 using difference_type = std::ptrdiff_t;
329 using pointer = Entry *;
330 using reference = Entry &;
331
332 Iterator(Lister &lister) : lister_{lister} {
333 current_entry_ = lister_.Next();
334 }
335
336 Entry operator*() { return current_entry_.value(); }
337
339 if (current_entry_) {
340 current_entry_ = lister_.Next();
341 }
342 return *this;
343 }
344
345 bool operator!=(const Iterator &other) const {
346 return current_entry_ != std::nullopt ||
347 other.current_entry_ != std::nullopt;
348 }
349
350 protected:
351 // Only used for end iterator
352 Iterator(Lister &lister, bool /*end*/) noexcept : lister_(lister) {}
353
354 private:
355 friend class Lister;
356
357 Lister &lister_;
358 std::optional<Entry> current_entry_;
359 };
360
366 std::optional<Entry> Next();
367
368 Iterator begin() { return Iterator(*this); }
369 Iterator end() { return Iterator(*this, true); }
370
371 private:
372 friend class Operator;
373
374 Lister(ffi::Lister *pointer) noexcept;
375
376 void Destroy() noexcept;
377
378 ffi::Lister *lister_{nullptr};
379};
380
381} // namespace opendal
Definition data_structure.hpp:195
The entry of a file or directory.
Definition data_structure.hpp:188
Definition opendal.hpp:324
std::ptrdiff_t difference_type
Definition opendal.hpp:328
Entry operator*()
Definition opendal.hpp:336
Iterator(Lister &lister)
Definition opendal.hpp:332
std::input_iterator_tag iterator_category
Definition opendal.hpp:326
Iterator(Lister &lister, bool) noexcept
Definition opendal.hpp:352
Iterator & operator++()
Definition opendal.hpp:338
bool operator!=(const Iterator &other) const
Definition opendal.hpp:345
Lister is designed to list the entries of a directory.
Definition opendal.hpp:312
std::optional< Entry > Next()
Get the next entry of the lister.
~Lister() noexcept
Lister(Lister &&other) noexcept
Iterator begin()
Definition opendal.hpp:368
Iterator end()
Definition opendal.hpp:369
The metadata of a file or directory.
Definition data_structure.hpp:49
Operator is the entry for all public APIs.
Definition opendal.hpp:47
void Remove(std::string_view path)
Remove a file or directory.
Reader GetReader(std::string_view path)
Read data from the operator.
Operator() noexcept
Capability Info()
void Rename(std::string_view src, std::string_view dst)
Rename a file from src to dst.
Operator(Operator &&other) noexcept
bool Exists(std::string_view path)
Check if the path exists.
bool Available() const
Check if the operator is available.
~Operator() noexcept
std::string Read(std::string_view path)
Read data from the operator.
Operator(const Operator &)=delete
bool IsExist(std::string_view path)
Check if the path exists.
Operator & operator=(const Operator &)=delete
Lister GetLister(std::string_view path)
void CreateDir(std::string_view path)
Create a directory.
Operator & operator=(Operator &&other) noexcept
void Copy(std::string_view src, std::string_view dst)
Copy a file from src to dst.
void Write(std::string_view path, std::string_view data)
Write data to the operator.
std::vector< Entry > List(std::string_view path)
List the entries of a directory.
Metadata Stat(std::string_view path)
Get the metadata of a file or directory.
Definition opendal.hpp:213
int_type uflow() override
Definition opendal.hpp:258
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which) override
Definition opendal.hpp:266
std::streamsize xsgetn(char *s, std::streamsize count) override
Definition opendal.hpp:221
int_type underflow() override
Definition opendal.hpp:241
std::streampos seekpos(std::streampos pos, std::ios_base::openmode which) override
Definition opendal.hpp:282
ReaderStreamBuf(Reader &&reader)
Definition opendal.hpp:215
ReaderStream is a stream wrapper of Reader which provides iostream interface. It wraps the Reader to ...
Definition opendal.hpp:211
ReaderStream(Reader &&reader)
Definition opendal.hpp:293
Reader is designed to read data from the operator.
Definition opendal.hpp:185
Reader(Reader &&other) noexcept
std::streamsize Read(void *s, std::streamsize n)
std::streampos Seek(std::streamoff off, std::ios_base::seekdir way)
~Reader() noexcept
Definition data_structure.hpp:27