#include <algorithm>
#include <string>
#include "seal/c/plaintext.h"
#include "seal/c/utilities.h"
#include "seal/plaintext.h"
#include "seal/util/common.h"
using namespace std;
using namespace seal;
using namespace seal::c;
using namespace seal::util;
using ph = struct Plaintext::PlaintextPrivateHelper
{
static void set_scale(seal::Plaintext *plain, double new_scale)
{
plain->scale_ = new_scale;
}
static void swap_data(seal::Plaintext *plain, seal::DynArray<uint64_t> &new_data)
{
swap(plain->data_, new_data);
}
static void set(seal::Plaintext *plain, uint64_t coeff_count, uint64_t *coeffs)
{
plain->data_.resize(0, false);
plain->data_.resize(coeff_count, false);
copy_n(coeffs, coeff_count, plain->data_.begin());
plain->coeff_count_ = coeff_count;
plain->parms_id_ = parms_id_zero;
}
};
SEAL_C_FUNC Plaintext_Create1(void *memoryPoolHandle, void **plaintext)
{
IfNullRet(plaintext, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(memoryPoolHandle);
Plaintext *plain = nullptr;
try
{
plain = new Plaintext(*handle);
*plaintext = plain;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC Plaintext_Create2(uint64_t coeffCount, void *memoryPoolHandle, void **plaintext)
{
IfNullRet(plaintext, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(memoryPoolHandle);
Plaintext *plain = nullptr;
try
{
plain = new Plaintext(coeffCount, *handle);
*plaintext = plain;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC Plaintext_Create3(uint64_t capacity, uint64_t coeffCount, void *memoryPoolHandle, void **plaintext)
{
IfNullRet(plaintext, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(memoryPoolHandle);
Plaintext *plain = nullptr;
try
{
plain = new Plaintext(capacity, coeffCount, *handle);
*plaintext = plain;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC Plaintext_Create4(char *hex_poly, void *memoryPoolHandle, void **plaintext)
{
IfNullRet(plaintext, E_POINTER);
IfNullRet(hex_poly, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(memoryPoolHandle);
string hex_poly_str(hex_poly);
try
{
Plaintext *plain = new Plaintext(hex_poly_str, *handle);
*plaintext = plain;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC Plaintext_Create5(void *copy, void **plaintext)
{
Plaintext *copyptr = FromVoid<Plaintext>(copy);
IfNullRet(copyptr, E_POINTER);
IfNullRet(plaintext, E_POINTER);
Plaintext *plain = new Plaintext(*copyptr);
*plaintext = plain;
return S_OK;
}
SEAL_C_FUNC Plaintext_Set1(void *thisptr, void *assign)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
Plaintext *assignptr = FromVoid<Plaintext>(assign);
IfNullRet(assignptr, E_POINTER);
*plain = *assignptr;
return S_OK;
}
SEAL_C_FUNC Plaintext_Set2(void *thisptr, char *hex_poly)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(hex_poly, E_POINTER);
try
{
string hex_poly_str(hex_poly);
*plain = hex_poly_str;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC Plaintext_Set3(void *thisptr, uint64_t const_coeff)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
*plain = const_coeff;
return S_OK;
}
SEAL_C_FUNC Plaintext_Set4(void *thisptr, uint64_t count, uint64_t *coeffs)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
ph::set(plain, count, coeffs);
return S_OK;
}
SEAL_C_FUNC Plaintext_Destroy(void *thisptr)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
delete plain;
return S_OK;
}
SEAL_C_FUNC Plaintext_CoeffCount(void *thisptr, uint64_t *coeff_count)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(coeff_count, E_POINTER);
*coeff_count = plain->coeff_count();
return S_OK;
}
SEAL_C_FUNC Plaintext_CoeffAt(void *thisptr, uint64_t index, uint64_t *coeff)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(coeff, E_POINTER);
try
{
*coeff = (*plain)[index];
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const out_of_range &)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
}
}
SEAL_C_FUNC Plaintext_SetCoeffAt(void *thisptr, uint64_t index, uint64_t value)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
try
{
(*plain)[index] = value;
return S_OK;
}
catch (const out_of_range &)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
}
}
SEAL_C_FUNC Plaintext_ToString(void *thispt, char *outstr, uint64_t *length)
{
Plaintext *plain = FromVoid<Plaintext>(thispt);
IfNullRet(plain, E_POINTER);
IfNullRet(length, E_POINTER);
return ToStringHelper(plain->to_string(), outstr, length);
}
SEAL_C_FUNC Plaintext_IsNTTForm(void *thisptr, bool *is_ntt_form)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(is_ntt_form, E_POINTER);
*is_ntt_form = plain->is_ntt_form();
return S_OK;
}
SEAL_C_FUNC Plaintext_IsZero(void *thisptr, bool *is_zero)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(is_zero, E_POINTER);
*is_zero = plain->is_zero();
return S_OK;
}
SEAL_C_FUNC Plaintext_GetParmsId(void *thisptr, uint64_t *parms_id)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(parms_id, E_POINTER);
for (size_t i = 0; i < plain->parms_id().size(); i++)
{
parms_id[i] = plain->parms_id()[i];
}
return S_OK;
}
SEAL_C_FUNC Plaintext_SetParmsId(void *thisptr, uint64_t *parms_id)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(parms_id, E_POINTER);
CopyParmsId(parms_id, plain->parms_id());
return S_OK;
}
SEAL_C_FUNC Plaintext_SetZero1(void *thisptr)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
plain->set_zero();
return S_OK;
}
SEAL_C_FUNC Plaintext_SetZero2(void *thisptr, uint64_t start_coeff)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
try
{
plain->set_zero(safe_cast<size_t>(start_coeff));
return S_OK;
}
catch (const out_of_range &)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
}
}
SEAL_C_FUNC Plaintext_SetZero3(void *thisptr, uint64_t start_coeff, uint64_t length)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
try
{
plain->set_zero(safe_cast<size_t>(start_coeff), safe_cast<size_t>(length));
return S_OK;
}
catch (const out_of_range &)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
}
}
SEAL_C_FUNC Plaintext_Reserve(void *thisptr, uint64_t capacity)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
try
{
plain->reserve(capacity);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
}
SEAL_C_FUNC Plaintext_Resize(void *thisptr, uint64_t coeff_count)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
try
{
plain->resize(coeff_count);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
}
SEAL_C_FUNC Plaintext_ShrinkToFit(void *thisptr)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
plain->shrink_to_fit();
return S_OK;
}
SEAL_C_FUNC Plaintext_Release(void *thisptr)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
plain->release();
return S_OK;
}
SEAL_C_FUNC Plaintext_Capacity(void *thisptr, uint64_t *capacity)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(capacity, E_POINTER);
*capacity = plain->capacity();
return S_OK;
}
SEAL_C_FUNC Plaintext_SignificantCoeffCount(void *thisptr, uint64_t *significant_coeff_count)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(significant_coeff_count, E_POINTER);
*significant_coeff_count = plain->significant_coeff_count();
return S_OK;
}
SEAL_C_FUNC Plaintext_NonZeroCoeffCount(void *thisptr, uint64_t *nonzero_coeff_count)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(nonzero_coeff_count, E_POINTER);
*nonzero_coeff_count = plain->nonzero_coeff_count();
return S_OK;
}
SEAL_C_FUNC Plaintext_Scale(void *thisptr, double *scale)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(scale, E_POINTER);
*scale = plain->scale();
return S_OK;
}
SEAL_C_FUNC Plaintext_SetScale(void *thisptr, double scale)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
ph::set_scale(plain, scale);
return S_OK;
}
SEAL_C_FUNC Plaintext_Equals(void *thisptr, void *other, bool *result)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
Plaintext *otherptr = FromVoid<Plaintext>(other);
IfNullRet(otherptr, E_POINTER);
IfNullRet(result, E_POINTER);
*result = (*plain == *otherptr);
return S_OK;
}
SEAL_C_FUNC Plaintext_SwapData(void *thisptr, uint64_t count, uint64_t *new_data)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(new_data, E_POINTER);
DynArray<uint64_t> new_array(plain->pool());
new_array.resize(count);
copy_n(new_data, count, new_array.begin());
ph::swap_data(plain, new_array);
return S_OK;
}
SEAL_C_FUNC Plaintext_Pool(void *thisptr, void **pool)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(pool, E_POINTER);
MemoryPoolHandle *handleptr = new MemoryPoolHandle(plain->pool());
*pool = handleptr;
return S_OK;
}
SEAL_C_FUNC Plaintext_SaveSize(void *thisptr, uint8_t compr_mode, int64_t *result)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(result, E_POINTER);
try
{
*result = static_cast<int64_t>(plain->save_size(static_cast<compr_mode_type>(compr_mode)));
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
}
SEAL_C_FUNC Plaintext_Save(void *thisptr, uint8_t *outptr, uint64_t size, uint8_t compr_mode, int64_t *out_bytes)
{
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(outptr, E_POINTER);
IfNullRet(out_bytes, E_POINTER);
try
{
*out_bytes = util::safe_cast<int64_t>(plain->save(
reinterpret_cast<seal_byte *>(outptr), util::safe_cast<size_t>(size),
static_cast<compr_mode_type>(compr_mode)));
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
catch (const runtime_error &)
{
return COR_E_IO;
}
}
SEAL_C_FUNC Plaintext_UnsafeLoad(void *thisptr, void *context, uint8_t *inptr, uint64_t size, int64_t *in_bytes)
{
const SEALContext *ctx = FromVoid<SEALContext>(context);
IfNullRet(ctx, E_POINTER);
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(inptr, E_POINTER);
IfNullRet(in_bytes, E_POINTER);
try
{
*in_bytes = util::safe_cast<int64_t>(
plain->unsafe_load(*ctx, reinterpret_cast<seal_byte *>(inptr), util::safe_cast<size_t>(size)));
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
catch (const runtime_error &)
{
return COR_E_IO;
}
}
SEAL_C_FUNC Plaintext_Load(void *thisptr, void *context, uint8_t *inptr, uint64_t size, int64_t *in_bytes)
{
const SEALContext *ctx = FromVoid<SEALContext>(context);
IfNullRet(ctx, E_POINTER);
Plaintext *plain = FromVoid<Plaintext>(thisptr);
IfNullRet(plain, E_POINTER);
IfNullRet(inptr, E_POINTER);
IfNullRet(in_bytes, E_POINTER);
try
{
*in_bytes = util::safe_cast<int64_t>(
plain->load(*ctx, reinterpret_cast<seal_byte *>(inptr), util::safe_cast<size_t>(size)));
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
catch (const logic_error &)
{
return COR_E_INVALIDOPERATION;
}
catch (const runtime_error &)
{
return COR_E_IO;
}
}