mirror of
https://github.com/facebook/sapling.git
synced 2024-12-29 08:02:24 +03:00
revisionstore: remove c_api
Summary: It was once used by EdenFS, but is now dead code, no need to keep it around. Reviewed By: singhsrb Differential Revision: D22784582 fbshipit-source-id: d01cf5a99a010530166cabb0de55a5ea3c51c9c7
This commit is contained in:
parent
537f4445f8
commit
5af4e00fb4
@ -7,4 +7,3 @@ add_subdirectory(backingstore)
|
|||||||
add_subdirectory(cdatapack)
|
add_subdirectory(cdatapack)
|
||||||
add_subdirectory(clib)
|
add_subdirectory(clib)
|
||||||
add_subdirectory(configparser)
|
add_subdirectory(configparser)
|
||||||
add_subdirectory(revisionstore)
|
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
rust_static_library(rust_revisionstore CRATE revisionstore)
|
|
||||||
install_rust_static_library(
|
|
||||||
rust_revisionstore
|
|
||||||
EXPORT mercurial
|
|
||||||
INSTALL_DIR lib
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(revisionstore RevisionStore.cpp)
|
|
||||||
set_target_properties(
|
|
||||||
revisionstore
|
|
||||||
PROPERTIES
|
|
||||||
PUBLIC_HEADER
|
|
||||||
RevisionStore.h
|
|
||||||
)
|
|
||||||
target_include_directories(revisionstore PUBLIC
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
revisionstore
|
|
||||||
PRIVATE
|
|
||||||
rust_revisionstore
|
|
||||||
Folly::folly
|
|
||||||
)
|
|
||||||
|
|
||||||
# curl used in the Rust crate has its own copy of curl compiled and it uses
|
|
||||||
# Crypt32 and Secur32 on Windows. We need to declare the link dependencies here
|
|
||||||
# to avoid linker errors.
|
|
||||||
if (WIN32)
|
|
||||||
target_link_libraries(
|
|
||||||
revisionstore
|
|
||||||
PRIVATE
|
|
||||||
Crypt32
|
|
||||||
Secur32
|
|
||||||
Ncrypt
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS revisionstore
|
|
||||||
EXPORT mercurial
|
|
||||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
|
||||||
PUBLIC_HEADER DESTINATION "include/eden/scm/lib/revisionstore/"
|
|
||||||
)
|
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* GNU General Public License version 2.
|
|
||||||
*/
|
|
||||||
#include "RevisionStore.h"
|
|
||||||
using namespace facebook::eden;
|
|
||||||
|
|
||||||
// The following functions are exported from this rust library:
|
|
||||||
// @dep=//eden/scm/lib/revisionstore:revisionstore
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct ByteData {
|
|
||||||
const uint8_t* ptr;
|
|
||||||
size_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GetData {
|
|
||||||
RevisionStoreByteVecStruct* value;
|
|
||||||
RevisionStoreStringStruct* error;
|
|
||||||
bool is_key_error;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
extern "C" DataPackUnionStruct* revisionstore_datapackunion_new(
|
|
||||||
const char* const paths[],
|
|
||||||
size_t num_paths) noexcept;
|
|
||||||
extern "C" void revisionstore_datapackunion_free(
|
|
||||||
DataPackUnionStruct* store) noexcept;
|
|
||||||
extern "C" GetData revisionstore_datapackunion_get(
|
|
||||||
DataPackUnionStruct* store,
|
|
||||||
const uint8_t* name,
|
|
||||||
size_t name_len,
|
|
||||||
const uint8_t* hgid,
|
|
||||||
size_t hgid_len) noexcept;
|
|
||||||
|
|
||||||
extern "C" void revisionstore_string_free(
|
|
||||||
RevisionStoreStringStruct* str) noexcept;
|
|
||||||
extern "C" ByteData revisionstore_string_data(
|
|
||||||
RevisionStoreStringStruct* str) noexcept;
|
|
||||||
|
|
||||||
extern "C" void revisionstore_bytevec_free(
|
|
||||||
RevisionStoreByteVecStruct* bytes) noexcept;
|
|
||||||
extern "C" ByteData revisionstore_bytevec_data(
|
|
||||||
RevisionStoreByteVecStruct* bytes) noexcept;
|
|
||||||
|
|
||||||
namespace facebook {
|
|
||||||
namespace eden {
|
|
||||||
|
|
||||||
void DataPackUnion::Deleter::operator()(DataPackUnionStruct* ptr) const
|
|
||||||
noexcept {
|
|
||||||
revisionstore_datapackunion_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataPackUnion::DataPackUnion(const char* const paths[], size_t num_paths)
|
|
||||||
: store_(revisionstore_datapackunion_new(paths, num_paths)) {}
|
|
||||||
|
|
||||||
folly::Optional<RevisionStoreByteVec> DataPackUnion::get(
|
|
||||||
folly::ByteRange name,
|
|
||||||
folly::ByteRange hgid) {
|
|
||||||
// This implementation is strongly coupled to that of
|
|
||||||
// revisionstore_datapackunion_get in eden/scm/lib/revisionstore/src/c_api.rs
|
|
||||||
auto got = revisionstore_datapackunion_get(
|
|
||||||
store_.get(), name.data(), name.size(), hgid.data(), hgid.size());
|
|
||||||
if (got.value) {
|
|
||||||
return RevisionStoreByteVec(got.value);
|
|
||||||
}
|
|
||||||
if (got.is_key_error) {
|
|
||||||
return folly::none;
|
|
||||||
}
|
|
||||||
RevisionStoreString error(got.error);
|
|
||||||
throw DataPackUnionGetError(error.stringPiece().str());
|
|
||||||
}
|
|
||||||
|
|
||||||
RevisionStoreString::RevisionStoreString(RevisionStoreStringStruct* ptr)
|
|
||||||
: ptr_(ptr) {}
|
|
||||||
|
|
||||||
void RevisionStoreString::Deleter::operator()(
|
|
||||||
RevisionStoreStringStruct* ptr) const noexcept {
|
|
||||||
revisionstore_string_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
folly::StringPiece RevisionStoreString::stringPiece() const noexcept {
|
|
||||||
auto data = revisionstore_string_data(ptr_.get());
|
|
||||||
return folly::StringPiece(reinterpret_cast<const char*>(data.ptr), data.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
RevisionStoreByteVec::RevisionStoreByteVec(RevisionStoreByteVecStruct* ptr)
|
|
||||||
: ptr_(ptr) {}
|
|
||||||
|
|
||||||
void RevisionStoreByteVec::Deleter::operator()(
|
|
||||||
RevisionStoreByteVecStruct* ptr) const noexcept {
|
|
||||||
revisionstore_bytevec_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
folly::ByteRange RevisionStoreByteVec::bytes() const noexcept {
|
|
||||||
auto data = revisionstore_bytevec_data(ptr_.get());
|
|
||||||
return folly::ByteRange(data.ptr, data.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace eden
|
|
||||||
} // namespace facebook
|
|
@ -1,92 +0,0 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved
|
|
||||||
#pragma once
|
|
||||||
/** This module makes available to C++ some of the Rust revisionstore
|
|
||||||
* functionality.
|
|
||||||
*/
|
|
||||||
#include <folly/Optional.h>
|
|
||||||
#include <folly/Range.h>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace facebook {
|
|
||||||
namespace eden {
|
|
||||||
|
|
||||||
struct DataPackUnionStruct;
|
|
||||||
struct RevisionStoreStringStruct;
|
|
||||||
struct RevisionStoreByteVecStruct;
|
|
||||||
|
|
||||||
/** Represents a Rust String value returned from the revisionstore crate.
|
|
||||||
* The string bytes are guaranteed to be value UTF-8.
|
|
||||||
* The string value is used to represent a human readable error string.
|
|
||||||
*/
|
|
||||||
class RevisionStoreString {
|
|
||||||
public:
|
|
||||||
explicit RevisionStoreString(RevisionStoreStringStruct* ptr);
|
|
||||||
|
|
||||||
// Explicitly reference the string bytes as a StringPiece
|
|
||||||
folly::StringPiece stringPiece() const noexcept;
|
|
||||||
|
|
||||||
operator folly::StringPiece() const noexcept {
|
|
||||||
return stringPiece();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Deleter {
|
|
||||||
void operator()(RevisionStoreStringStruct*) const noexcept;
|
|
||||||
};
|
|
||||||
std::unique_ptr<RevisionStoreStringStruct, Deleter> ptr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Represents a Rust Vec<u8> value returned from the revisionstore crate.
|
|
||||||
*/
|
|
||||||
class RevisionStoreByteVec {
|
|
||||||
public:
|
|
||||||
explicit RevisionStoreByteVec(RevisionStoreByteVecStruct* ptr);
|
|
||||||
|
|
||||||
// Explicitly reference the bytes as a ByteRange
|
|
||||||
folly::ByteRange bytes() const noexcept;
|
|
||||||
|
|
||||||
// Implicit conversion to ByteRange
|
|
||||||
operator folly::ByteRange() const noexcept {
|
|
||||||
return bytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Deleter {
|
|
||||||
void operator()(RevisionStoreByteVecStruct*) const noexcept;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<RevisionStoreByteVecStruct, Deleter> ptr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DataPackUnionGetError : public std::runtime_error {
|
|
||||||
public:
|
|
||||||
using std::runtime_error::runtime_error;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** DataPackUnion is configured with a list of directory paths that
|
|
||||||
* contain some number of datapack files.
|
|
||||||
* DataPackUnion can be queried to see if it contains a given key,
|
|
||||||
* and fetch the corresponding de-delta'd value
|
|
||||||
*/
|
|
||||||
class DataPackUnion {
|
|
||||||
public:
|
|
||||||
DataPackUnion(const char* const paths[], size_t num_paths);
|
|
||||||
|
|
||||||
// Look up the name/hgid pair. If found, de-delta and return the data as a
|
|
||||||
// RevisionStoreByteVec. If not found, return folly::none. If an error
|
|
||||||
// occurs, throw a DataPackUnionGetError exception. This method is not thread
|
|
||||||
// safe.
|
|
||||||
folly::Optional<RevisionStoreByteVec> get(
|
|
||||||
folly::ByteRange name,
|
|
||||||
folly::ByteRange hgid);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Deleter {
|
|
||||||
void operator()(DataPackUnionStruct*) const noexcept;
|
|
||||||
};
|
|
||||||
std::unique_ptr<DataPackUnionStruct, Deleter> store_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace eden
|
|
||||||
} // namespace facebook
|
|
@ -1,281 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* GNU General Public License version 2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//! This module exports some concrete implementations of the revisionstore
|
|
||||||
//! API for use from C++ code. The exports in this file match up to the C++
|
|
||||||
//! header file RevisionStore.h in the top level of this crate.
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
collections::HashMap,
|
|
||||||
ffi::CStr,
|
|
||||||
fs,
|
|
||||||
os::raw::c_char,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
ptr, slice,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
use types::{HgId, Key, RepoPath};
|
|
||||||
|
|
||||||
use crate::datapack::DataPack;
|
|
||||||
use crate::datastore::{HgIdDataStore, StoreResult};
|
|
||||||
use crate::types::StoreKey;
|
|
||||||
use crate::uniondatastore::UnionHgIdDataStore;
|
|
||||||
|
|
||||||
pub struct DataPackUnion {
|
|
||||||
paths: Vec<PathBuf>,
|
|
||||||
packs: HashMap<PathBuf, Arc<DataPack>>,
|
|
||||||
store: UnionHgIdDataStore<Arc<DataPack>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the supplied path has a .datapack extension
|
|
||||||
fn is_datapack(path: &Path) -> bool {
|
|
||||||
if let Some(extension) = path.extension() {
|
|
||||||
extension == "datapack"
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ScanResult {
|
|
||||||
NoChanges,
|
|
||||||
ChangesDetected,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataPackUnion {
|
|
||||||
fn new(paths: Vec<PathBuf>) -> Self {
|
|
||||||
Self {
|
|
||||||
paths,
|
|
||||||
packs: HashMap::new(),
|
|
||||||
store: UnionHgIdDataStore::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rescan_paths(&mut self) -> ScanResult {
|
|
||||||
// first step is to release any unlinked pack files
|
|
||||||
let num_before = self.packs.len();
|
|
||||||
self.packs.retain(|path, _| path.exists());
|
|
||||||
let mut num_changed = num_before - self.packs.len();
|
|
||||||
|
|
||||||
// next step is to discover any new files
|
|
||||||
for path in &self.paths {
|
|
||||||
match Self::scan_dir(&mut self.packs, path) {
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!(
|
|
||||||
"Error while scanning {} for datapack files: {}",
|
|
||||||
path.display(),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(num) => num_changed += num,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if num_changed == 0 {
|
|
||||||
return ScanResult::NoChanges;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-create the union portion; while we can add elements, there isn't
|
|
||||||
// a way to remove them, so we build a new one and populate it.
|
|
||||||
// The UnionHgIdDataStore is just a Vec of Arc's to our packs, so this is
|
|
||||||
// relatively cheap.
|
|
||||||
self.store = UnionHgIdDataStore::new();
|
|
||||||
|
|
||||||
for pack in self.packs.values() {
|
|
||||||
self.store.add(pack.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
ScanResult::ChangesDetected
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scan_dir(packs: &mut HashMap<PathBuf, Arc<DataPack>>, path: &Path) -> Result<usize> {
|
|
||||||
let mut num_changed = 0;
|
|
||||||
for entry in fs::read_dir(path)? {
|
|
||||||
let entry = entry?;
|
|
||||||
let path = entry.path();
|
|
||||||
if is_datapack(&path) {
|
|
||||||
if !packs.contains_key(&path) {
|
|
||||||
let pack = Arc::new(DataPack::new(&path)?);
|
|
||||||
packs.insert(path, pack);
|
|
||||||
num_changed += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(num_changed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lookup Key. If the key is missing, scan for changes in the pack files and try once more.
|
|
||||||
fn get(&mut self, key: &Key) -> Result<Option<Vec<u8>>> {
|
|
||||||
match self.store.get(StoreKey::hgid(key.clone()))? {
|
|
||||||
StoreResult::Found(data) => Ok(Some(data)),
|
|
||||||
StoreResult::NotFound(key) => match self.rescan_paths() {
|
|
||||||
ScanResult::ChangesDetected => match self.store.get(key)? {
|
|
||||||
StoreResult::Found(data) => Ok(Some(data)),
|
|
||||||
StoreResult::NotFound(_) => Ok(None),
|
|
||||||
},
|
|
||||||
ScanResult::NoChanges => Ok(None),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct a new datapack store.
|
|
||||||
/// Will panic the program if the paths array or elements
|
|
||||||
/// of the paths array are null.
|
|
||||||
/// Returns an instance of DataPackUnion which must be
|
|
||||||
/// freed using revisionstore_datapackunion_free when it is
|
|
||||||
/// no longer required.
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_datapackunion_new(
|
|
||||||
paths: *const *const c_char,
|
|
||||||
num_paths: usize,
|
|
||||||
) -> *mut DataPackUnion {
|
|
||||||
debug_assert!(!paths.is_null());
|
|
||||||
let paths = unsafe { slice::from_raw_parts(paths, num_paths) };
|
|
||||||
let paths = paths
|
|
||||||
.iter()
|
|
||||||
.map(|&path_ptr| {
|
|
||||||
debug_assert!(
|
|
||||||
!path_ptr.is_null(),
|
|
||||||
"paths passed to revisionstore_unionstore_new must not be null"
|
|
||||||
);
|
|
||||||
let path_cstr = unsafe { CStr::from_ptr(path_ptr) };
|
|
||||||
let path_str = path_cstr.to_str().expect("Not a valid UTF-8 path");
|
|
||||||
Path::new(path_str).to_path_buf()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let mut store = DataPackUnion::new(paths);
|
|
||||||
store.rescan_paths();
|
|
||||||
Box::into_raw(Box::new(store))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Free a DataPackUnion instance created via revisionstore_unionstore_new().
|
|
||||||
/// Releases all associated resources.
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_datapackunion_free(store: *mut DataPackUnion) {
|
|
||||||
debug_assert!(!store.is_null());
|
|
||||||
let store = unsafe { Box::from_raw(store) };
|
|
||||||
drop(store);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct an instance of Key from the provided ffi parameters
|
|
||||||
fn make_key(name: *const u8, name_len: usize, hgid: *const u8, hgid_len: usize) -> Result<Key> {
|
|
||||||
debug_assert!(!name.is_null());
|
|
||||||
debug_assert!(!hgid.is_null());
|
|
||||||
|
|
||||||
let path_slice = unsafe { slice::from_raw_parts(name, name_len) };
|
|
||||||
let path = RepoPath::from_utf8(path_slice)?.to_owned();
|
|
||||||
|
|
||||||
let hgid_slice = unsafe { slice::from_raw_parts(hgid, hgid_len) };
|
|
||||||
let hgid = HgId::from_slice(hgid_slice)?;
|
|
||||||
|
|
||||||
Ok(Key::new(path, hgid))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper function that performs the get operation, wrapped in a Result
|
|
||||||
fn datapackunion_get_impl(
|
|
||||||
store: *mut DataPackUnion,
|
|
||||||
name: *const u8,
|
|
||||||
name_len: usize,
|
|
||||||
hgid: *const u8,
|
|
||||||
hgid_len: usize,
|
|
||||||
) -> Result<Option<Vec<u8>>> {
|
|
||||||
debug_assert!(!store.is_null());
|
|
||||||
let store = unsafe { &mut *store };
|
|
||||||
let key = make_key(name, name_len, hgid, hgid_len)?;
|
|
||||||
store.get(&key)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct GetData {
|
|
||||||
value: *mut Vec<u8>,
|
|
||||||
error: *mut String,
|
|
||||||
is_key_error: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lookup the value corresponding to name/hgid.
|
|
||||||
/// If the key is present, de-delta and populate `GetData::value`.
|
|
||||||
/// If the requested key could not be found sets `GetData::is_key_error` to true.
|
|
||||||
/// If some other error occurred, populates `GetData::error`.
|
|
||||||
/// The caller is responsible for calling revisionstore_string_free() on
|
|
||||||
/// the `error` value if it is non-null when this function returns.
|
|
||||||
/// The caller is responsible for calling revisionstore_bytevec_free() on
|
|
||||||
/// the `value` if it is non-null when this function returns.
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_datapackunion_get(
|
|
||||||
store: *mut DataPackUnion,
|
|
||||||
name: *const u8,
|
|
||||||
name_len: usize,
|
|
||||||
hgid: *const u8,
|
|
||||||
hgid_len: usize,
|
|
||||||
) -> GetData {
|
|
||||||
match datapackunion_get_impl(store, name, name_len, hgid, hgid_len) {
|
|
||||||
Ok(Some(data)) => GetData {
|
|
||||||
value: Box::into_raw(Box::new(data)),
|
|
||||||
error: ptr::null_mut(),
|
|
||||||
is_key_error: false,
|
|
||||||
},
|
|
||||||
Ok(None) => GetData {
|
|
||||||
value: ptr::null_mut(),
|
|
||||||
error: ptr::null_mut(),
|
|
||||||
is_key_error: true,
|
|
||||||
},
|
|
||||||
Err(err) => GetData {
|
|
||||||
value: ptr::null_mut(),
|
|
||||||
error: Box::into_raw(Box::new(format!("{}", err))),
|
|
||||||
is_key_error: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dispose of a String object, such as that returned in the `error` parameter
|
|
||||||
/// of revisionstore_datapackunion_get().
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_string_free(string: *mut String) {
|
|
||||||
debug_assert!(!string.is_null());
|
|
||||||
let string = unsafe { Box::from_raw(string) };
|
|
||||||
drop(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the pointer to the start of the string data
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_string_data(string: *mut String) -> ByteData {
|
|
||||||
debug_assert!(!string.is_null());
|
|
||||||
let string = unsafe { &*string };
|
|
||||||
ByteData {
|
|
||||||
ptr: string.as_bytes().as_ptr(),
|
|
||||||
len: string.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dispose of a Vec<u8> object, such as that returned in the `value` parameter
|
|
||||||
/// of revisionstore_datapackunion_get().
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_bytevec_free(vec: *mut Vec<u8>) {
|
|
||||||
debug_assert!(!vec.is_null());
|
|
||||||
let vec = unsafe { Box::from_raw(vec) };
|
|
||||||
drop(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct ByteData {
|
|
||||||
ptr: *const u8,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the pointer to the start of the byte data and its size in bytes
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn revisionstore_bytevec_data(bytes: *mut Vec<u8>) -> ByteData {
|
|
||||||
debug_assert!(!bytes.is_null());
|
|
||||||
let bytes = unsafe { &*bytes };
|
|
||||||
ByteData {
|
|
||||||
ptr: bytes.as_ptr(),
|
|
||||||
len: bytes.len(),
|
|
||||||
}
|
|
||||||
}
|
|
@ -140,7 +140,6 @@ mod types;
|
|||||||
mod unionstore;
|
mod unionstore;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub mod c_api;
|
|
||||||
pub mod datapack;
|
pub mod datapack;
|
||||||
pub mod datastore;
|
pub mod datastore;
|
||||||
pub mod edenapi;
|
pub mod edenapi;
|
||||||
|
Loading…
Reference in New Issue
Block a user