7#ifndef BOTAN_FFI_UTILS_H_ 
    8#define BOTAN_FFI_UTILS_H_ 
   10#include <botan/exceptn.h> 
   12#include <botan/mem_ops.h> 
   13#include <botan/internal/mem_utils.h> 
   27      int error_code() const noexcept
 override { 
return m_err_code; }
 
 
   35template <
typename T, u
int32_t MAGIC>
 
   38      explicit botan_struct(std::unique_ptr<T> obj) : m_magic(MAGIC), m_obj(std::move(obj)) {}
 
   50      bool magic_ok()
 const { 
return (m_magic == MAGIC); }
 
   56      std::unique_ptr<T> m_obj;
 
 
   61#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC)                             \ 
   62   struct NAME final : public Botan_FFI::botan_struct<TYPE, MAGIC> {            \ 
   63         explicit NAME(std::unique_ptr<TYPE> x) : botan_struct(std::move(x)) {} \ 
 
   66#define BOTAN_FFI_DECLARE_DUMMY_STRUCT(NAME, MAGIC) \ 
   67   struct NAME final : public Botan_FFI::botan_struct<int, MAGIC> {} 
 
   78template <
typename T, u
int32_t M>
 
   94template <std::invocable T>
 
  100   } 
catch(std::bad_alloc&) {
 
  106   } 
catch(std::exception& e) {
 
 
  113template <
typename T, u
int32_t M, 
typename F>
 
  115   using RetT = std::invoke_result_t<F, T&>;
 
  116   static_assert(std::is_void_v<RetT> || std::is_same_v<RetT, BOTAN_FFI_ERROR> || std::is_same_v<RetT, int>,
 
  117                 "BOTAN_FFI_DO must be used with a block that returns either nothing, int or BOTAN_FFI_ERROR");
 
  132   if constexpr(std::is_void_v<RetT>) {
 
 
  158#define BOTAN_FFI_VISIT(obj, lambda) botan_ffi_visit(obj, lambda, __func__) 
  160template <
typename T, u
int32_t M>
 
  177template <
typename T, 
typename... Args>
 
  180   *obj = 
new std::remove_pointer_t<T>(std::forward<Args>(args)...);
 
 
  185#define BOTAN_FFI_CHECKED_DELETE(o) ffi_delete_object(o, __func__) 
  188   if(view == 
nullptr) {
 
  191   return view(ctx, buf.data(), buf.size());
 
 
  196   if(view == 
nullptr) {
 
  199   return view(ctx, str.data(), str.size() + 1);
 
 
  210template <
typename Fn, 
typename... Args>
 
  216template <
typename Fn, 
typename... Args>
 
  225template <std::
integral T>
 
  226inline int write_output(T out[], 
size_t* out_len, 
const T buf[], 
size_t buf_len) {
 
  227   static_assert(
sizeof(T) == 1, 
"T should be either uint8_t or char");
 
  229   if(out_len == 
nullptr) {
 
  233   const size_t avail = *out_len;
 
  236   if((avail >= buf_len) && (out != 
nullptr)) {
 
 
#define BOTAN_UNSTABLE_API
 
const char * what() const noexcept override
 
Exception(std::string_view msg)
 
Botan::ErrorType error_type() const noexcept override
 
FFI_Error(std::string_view what, int err_code)
 
int error_code() const noexcept override
 
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
 
@ BOTAN_FFI_ERROR_EXCEPTION_THROWN
 
@ BOTAN_FFI_ERROR_OUT_OF_MEMORY
 
@ BOTAN_FFI_ERROR_INVALID_OBJECT
 
@ BOTAN_FFI_ERROR_NULL_POINTER
 
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
 
int(* botan_view_str_fn)(botan_view_ctx view_ctx, const char *str, size_t len)
 
void ffi_clear_last_exception()
 
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
 
int ffi_error_exception_thrown(const char *func_name, const char *exn, int rc)
 
int botan_view_bin_bounce_fn(botan_view_ctx vctx, const uint8_t *buf, size_t len)
 
int botan_view_str_bounce_fn(botan_view_ctx vctx, const char *str, size_t len)
 
int botan_ffi_visit(botan_struct< T, M > *o, F func, const char *func_name)
 
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
 
int ffi_delete_object(botan_struct< T, M > *obj, const char *func_name)
 
T & safe_get(botan_struct< T, M > *p)
 
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
 
int copy_view_str(uint8_t out[], size_t *out_len, Fn fn, Args... args)
 
int write_output(T out[], size_t *out_len, const T buf[], size_t buf_len)
 
int ffi_guard_thunk(const char *func_name, T thunk)
 
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
 
int write_str_output(char out[], size_t *out_len, const std::string &str)
 
constexpr void copy_mem(T *out, const T *in, size_t n)
 
constexpr void clear_mem(T *ptr, size_t n)
 
bool any_null_pointers(Ptrs... ptr)
 
botan_struct(const botan_struct &other)=delete
 
botan_struct(std::unique_ptr< T > obj)
 
botan_struct & operator=(const botan_struct &other)=delete
 
botan_struct(botan_struct &&other)=delete
 
botan_struct & operator=(botan_struct &&other)=delete