blob: 01bb99813d081e1a9c8cdd34e084799e9fc7ec36 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include "opendal.hpp"
using namespace opendal;
#define RUST_STR(s) rust::Str(s.data(), s.size())
#define RUST_STRING(s) rust::String(s.data(), s.size())
// Operator
Operator::Operator(std::string_view scheme,
const std::unordered_map<std::string, std::string> &config) {
auto rust_map = rust::Vec<ffi::HashMapValue>();
rust_map.reserve(config.size());
for (auto &[k, v] : config) {
rust_map.push_back({RUST_STRING(k), RUST_STRING(v)});
}
operator_ = opendal::ffi::new_operator(RUST_STR(scheme), rust_map);
}
bool Operator::available() const { return operator_.has_value(); }
// We can't avoid copy, because std::vector hides the internal structure.
// std::vector doesn't support init from a pointer without copy.
std::vector<uint8_t> Operator::read(std::string_view path) {
auto rust_vec = operator_.value()->read(RUST_STR(path));
return {rust_vec.data(), rust_vec.data() + rust_vec.size()};
}
void Operator::write(std::string_view path, const std::vector<uint8_t> &data) {
operator_.value()->write(
RUST_STR(path), rust::Slice<const uint8_t>(data.data(), data.size()));
}
bool Operator::is_exist(std::string_view path) {
return operator_.value()->is_exist(RUST_STR(path));
}
void Operator::create_dir(std::string_view path) {
operator_.value()->create_dir(RUST_STR(path));
}
void Operator::copy(std::string_view src, std::string_view dst) {
operator_.value()->copy(RUST_STR(src), RUST_STR(dst));
}
void Operator::rename(std::string_view src, std::string_view dst) {
operator_.value()->rename(RUST_STR(src), RUST_STR(dst));
}
void Operator::remove(std::string_view path) {
operator_.value()->remove(RUST_STR(path));
}
Metadata Operator::stat(std::string_view path) {
return {operator_.value()->stat(RUST_STR(path))};
}
std::vector<Entry> Operator::list(std::string_view path) {
auto rust_vec = operator_.value()->list(RUST_STR(path));
std::vector<Entry> entries;
entries.reserve(rust_vec.size());
for (auto &&entry : rust_vec) {
entries.push_back(std::move(entry));
}
return entries;
}
Lister Operator::lister(std::string_view path) {
return operator_.value()->lister(RUST_STR(path));
}
Reader Operator::reader(std::string_view path) {
return operator_.value()->reader(RUST_STR(path));
}
// Reader
std::streamsize Reader::read(void *s, std::streamsize n) {
auto rust_slice = rust::Slice<uint8_t>(reinterpret_cast<uint8_t *>(s), n);
auto read_size = raw_reader_->read(rust_slice);
return read_size;
}
ffi::SeekDir to_rust_seek_dir(std::ios_base::seekdir dir);
std::streampos Reader::seek(std::streamoff off, std::ios_base::seekdir dir) {
return raw_reader_->seek(off, to_rust_seek_dir(dir));
}
// Lister
std::optional<Entry> Lister::next() {
auto entry = raw_lister_->next();
if (entry.has_value) {
return std::move(entry.value);
} else {
return std::nullopt;
}
}
// Metadata
std::optional<std::string> parse_optional_string(ffi::OptionalString &&s);
Metadata::Metadata(ffi::Metadata &&other) {
type = static_cast<EntryMode>(other.mode);
content_length = other.content_length;
cache_control = parse_optional_string(std::move(other.cache_control));
content_disposition =
parse_optional_string(std::move(other.content_disposition));
content_type = parse_optional_string(std::move(other.content_type));
content_md5 = parse_optional_string(std::move(other.content_md5));
etag = parse_optional_string(std::move(other.etag));
auto last_modified_str =
parse_optional_string(std::move(other.last_modified));
if (last_modified_str.has_value()) {
last_modified =
boost::posix_time::from_iso_string(last_modified_str.value());
}
}
// Entry
Entry::Entry(ffi::Entry &&other) : path(std::move(other.path)) {}
// helper functions
std::optional<std::string> parse_optional_string(ffi::OptionalString &&s) {
if (s.has_value) {
return std::string(std::move(s.value));
} else {
return std::nullopt;
}
}
ffi::SeekDir to_rust_seek_dir(std::ios_base::seekdir dir) {
switch (dir) {
case std::ios_base::beg:
return ffi::SeekDir::Start;
case std::ios_base::cur:
return ffi::SeekDir::Current;
case std::ios_base::end:
return ffi::SeekDir::End;
default:
throw std::runtime_error("invalid seekdir");
}
}