summary refs log tree commit diff
diff options
context:
space:
mode:
authorBob1312021-09-02 07:14:37 +1000
committerArun Isaac2021-09-07 01:23:59 +0530
commit3e74ce5db678ab36178920a7d071b408e4ea2efe (patch)
tree07d1fe590f820a9a050d71c0410086fb6900fffe
parente95d5405593176df126d0b5d0c83d4ce71f4ac24 (diff)
downloadguile-xapian-3e74ce5db678ab36178920a7d071b408e4ea2efe.tar.gz
guile-xapian-3e74ce5db678ab36178920a7d071b408e4ea2efe.tar.lz
guile-xapian-3e74ce5db678ab36178920a7d071b408e4ea2efe.zip
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 <arunisaac@systemreboot.net>
-rw-r--r--xapian.i.in104
1 files changed, 104 insertions, 0 deletions
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 <arunisaac@systemreboot.net>
+ * Copyright © 2021 Bob131 <bob@bob131.so>
  *
  * This file is part of guile-xapian.
  *
@@ -34,5 +35,108 @@
     (load-extension "libguilexapian" "SWIG_init")))
 %}
 
+%{
+  #include <string>
+
+  // 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);
+  }
+}