From 3e74ce5db678ab36178920a7d071b408e4ea2efe Mon Sep 17 00:00:00 2001 From: Bob131 Date: Thu, 2 Sep 2021 07:14:37 +1000 Subject: Add SWIG wrappers for bytevector method variants. Several Xapian methods use `std::string' to represent opaque binary blobs. SWIG treats these as UTF-8 strings and converts them to an SCM representation via `scm_from_utf8_string', which will throw an error if the input is not valid UTF-8. This commit updates the SWIG interface file to add wrappers taking or returning bytevectors instead of strings for Xapian methods dealing with document values and bodies. * xapian.i.in (SWIG_bytevector, typemap_in_SWIG_bytevector, typemap_out_SWIG_bytevector): Add machinery for defining bytevector-variant wrappers of existing methods taking or returning std::string. * (Xapian::ValueIterator::get_value_bytes, Xapian::Document::get_value_bytes, Xapian::Document::add_value_bytes, Xapian::Document::get_data_bytes, Xapian::Document::set_data_bytes, Xapian::Database::get_metadata_bytes, Xapian::WritableDatabase::set_metadata_bytes, Xapian::Query::Query): Add bytevector variants of methods. Signed-off-by: Arun Isaac --- xapian.i.in | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/xapian.i.in b/xapian.i.in index 1832786..4f36f8e 100644 --- a/xapian.i.in +++ b/xapian.i.in @@ -1,5 +1,6 @@ /* guile-xapian --- Guile bindings for Xapian * Copyright © 2020 Arun Isaac + * Copyright © 2021 Bob131 * * This file is part of guile-xapian. * @@ -34,5 +35,108 @@ (load-extension "libguilexapian" "SWIG_init"))) %} +%{ + #include + + // We introduce a dummy typedef for std::string without declaring it + // to SWIG so we can establish a new SWIG typemap applying only to + // certain redeclarations of existing C++ functions taking or + // returning strings. + typedef std::string SWIG_bytevector; + + static inline void typemap_in_SWIG_bytevector (SWIG_bytevector& out, SCM in) { + out.assign ((char*) SCM_BYTEVECTOR_CONTENTS (in), + SCM_BYTEVECTOR_LENGTH (in)); + } + + static inline SCM typemap_out_SWIG_bytevector (const SWIG_bytevector& in) { + SCM result = scm_c_make_bytevector (in.size ()); + memcpy (SCM_BYTEVECTOR_CONTENTS (result), in.data (), in.size ()); + return result; + } +%} + +%typemap(in) SWIG_bytevector { + if (scm_is_bytevector ($input)) { + $1 = std::string (); + typemap_in_SWIG_bytevector ($1, $input); + } else { + %argument_fail (SWIG_TypeError, "$type", $symname, $argnum); + } +} + +%typemap(in) SWIG_bytevector&, SWIG_bytevector* { + if (scm_is_bytevector ($input)) { + $1 = new std::string (); + typemap_in_SWIG_bytevector (*$1, $input); + } else { + %argument_fail (SWIG_TypeError, "$type", $symname, $argnum); + } +} + +%typemap(out) SWIG_bytevector { + $result = typemap_out_SWIG_bytevector ($1); +} + +%typemap(out) SWIG_bytevector&, SWIG_bytevector* { + $result = typemap_out_SWIG_bytevector (*$1); +} + +%typecheck(SWIG_TYPECHECK_SWIGOBJECT) + SWIG_bytevector, SWIG_bytevector&, SWIG_bytevector* +{ + $1 = scm_is_bytevector ($input); +} + %include xapian-head.i %include xapian-headers.i + +%extend Xapian::ValueIterator { + SWIG_bytevector get_value_bytes () { + return **$self; + } +} + +%extend Xapian::Document { + SWIG_bytevector get_value_bytes (Xapian::valueno valueno) { + return $self->get_value (valueno); + } + + void add_value_bytes (Xapian::valueno valueno, const SWIG_bytevector& bytes) { + $self->add_value (valueno, bytes); + } + + SWIG_bytevector get_data_bytes () { + return $self->get_data (); + } + + void set_data_bytes (const SWIG_bytevector& bytes) { + $self->set_data (bytes); + } +} + +%extend Xapian::Database { + SWIG_bytevector get_metadata_bytes (const std::string& key) { + return $self->get_metadata (key); + } +} + +%extend Xapian::WritableDatabase { + void set_metadata_bytes (const std::string& key, + const SWIG_bytevector& bytes) + { + $self->set_metadata (key, bytes); + } +} + +%extend Xapian::Query { + Query (op op_, Xapian::valueno slot, const SWIG_bytevector& range_limit) { + return new Xapian::Query (op_, slot, range_limit); + } + + Query (op op_, Xapian::valueno slot, + const SWIG_bytevector& range_lower, const SWIG_bytevector& range_upper) + { + return new Xapian::Query (op_, slot, range_lower, range_upper); + } +} -- cgit v1.2.3