5 The C# bindings for Xapian are packaged in the ``Xapian`` namespace
6 and largely follow the C++ API, with the following differences and
7 additions. C# strings and other types are converted automatically
8 in the bindings, so generally it should just work as expected.
10 The ``examples`` subdirectory contains examples showing how to use the
11 C# bindings based on the simple examples from ``xapian-examples``:
12 `SimpleIndex.cs <examples/SimpleIndex.cs>`_,
13 `SimpleSearch.cs <examples/SimpleSearch.cs>`_,
14 `SimpleExpand.cs <examples/SimpleExpand.cs>`_.
16 Note: the passing of strings from C# into Xapian and back isn't currently zero byte safe. If you try to handle string containing zero bytes, you'll find they get truncated at the zero byte.
23 In Xapian 1.0.0 and later, the Xapian::Stem, Xapian::QueryParser, and
24 Xapian::TermGenerator classes all assume text is in UTF-8. If you're
25 using Mono on UNIX with a UTF-8 locale (which is the default on most
26 modern Linux distributions), then Xapian appears to get passed Unicode
27 strings as UTF-8, so it should just work. We tested with Mono 2.6.7
28 using the Mono C# 2.0 compiler (gmcs).
30 However, Microsoft and Mono's C# implementations apparently take
31 rather different approaches to Unicode, and we've not tested with
32 Microsoft's implementation. If you try it, please report how well
33 it works (or how badly it fails...)
36 Method Naming Conventions
37 #########################
39 Methods are renamed to use the "CamelCase" capitalisation convention which C# normally uses. So in C# you use ``GetDescription`` instead of
46 Exceptions are thrown as SWIG exceptions instead of Xapian
47 exceptions. This isn't done well at the moment; in future we will
48 throw wrapped Xapian exceptions. For now, it's probably easier to
49 catch all exceptions and try to take appropriate action based on
50 their associated string.
56 The C#-wrapped iterators work much like their C++ counterparts, with
57 operators "++", "--", "==", and "!=" overloaded. E.g.:
61 Xapian.MSetIterator m = mset.begin();
62 while (m != mset.end()) {
68 Iterator dereferencing
69 ######################
71 C++ iterators are often dereferenced to get information, eg
72 ``(*it)``. In C# these are all mapped to named methods, as
75 +------------------+----------------------+
76 | Iterator | Dereferencing method |
77 +==================+======================+
78 | PositionIterator | ``GetTermPos()`` |
79 +------------------+----------------------+
80 | PostingIterator | ``GetDocId()`` |
81 +------------------+----------------------+
82 | TermIterator | ``GetTerm()`` |
83 +------------------+----------------------+
84 | ValueIterator | ``GetValue()`` |
85 +------------------+----------------------+
86 | MSetIterator | ``GetDocId()`` |
87 +------------------+----------------------+
88 | ESetIterator | ``GetTerm()`` |
89 +------------------+----------------------+
92 Other methods, such as ``MSetIterator.GetDocument()``, are available unchanged.
98 MSet objects have some additional methods to simplify access (these
99 work using the C++ array dereferencing):
101 +---------------------------------+-------------------------------------+
102 | Method name | Explanation |
103 +=================================+=====================================+
104 | ``GetHit(index)`` | returns MSetIterator at index |
105 +---------------------------------+-------------------------------------+
106 |``GetDocumentPercentage(index)`` | ``ConvertToPercent(GetHit(index))`` |
107 +---------------------------------+-------------------------------------+
108 | ``GetDocument(index)`` | ``GetHit(index).GetDocument()`` |
109 +---------------------------------+-------------------------------------+
110 | ``GetDocumentId(index)`` | ``GetHit(index).GetDocId()`` |
111 +---------------------------------+-------------------------------------+
117 The C++ API contains a few non-class functions (the Database factory
118 functions, and some functions reporting version information), but C# doesn't
119 allow functions which aren't in a class so these are wrapped as static
120 member functions of abstract classes like so:
122 - ``Xapian::version_string()`` is wrapped as ``Xapian.Version.String()``
123 - ``Xapian::major_version()`` is wrapped as ``Xapian.Version.Major()``
124 - ``Xapian::minor_version()`` is wrapped as ``Xapian.Version.Minor()``
125 - ``Xapian::revision()`` is wrapped as ``Xapian.Version.Revision()``
126 - ``Xapian::Remote::open()`` is wrapped as ``Xapian.Remote.Open()`` (both the TCP and "program" versions are wrapped - the SWIG wrapper checks the parameter list to decide which to call).
127 - ``Xapian::Remote::open_writable()`` is wrapped as ``Xapian.Remote.OpenWritable()`` (both the TCP and "program" versions are wrapped - the SWIG wrapper checks the parameter list to decide which to call).
134 The ``Xapian::DB_*`` constants are currently wrapped in a Xapian
135 class within the Xapian namespace, so have a double Xapian prefix!
136 So ``Xapian::DB_CREATE_OR_OPEN`` is available as
137 ``Xapian.Xapian.DB_CREATE_OR_OPEN``.
138 The ``Query::OP_*`` constants are wrapped a little oddly too:
139 ``Query::OP_OR`` is wrapped as ``Xapian.Query.op.OP_OR``.
140 Similarly, ``QueryParser::STEM_SOME`` as
141 ``Xapian.QueryParser.stem_strategy.STEM_SOME``.
142 The naming here needs sorting out...
148 In C++ there's a Xapian::Query constructor which takes a query operator and
149 start/end iterators specifying a number of terms or queries, plus an optional
151 This isn't currently wrapped in C#.
153 .. FIXME implement this wrapping!
154 .. In C#, this is wrapped to accept any C# sequence (for
155 .. example a list or tuple) to give the terms/queries, and you can specify
156 .. a mixture of terms and queries if you wish. For example:
157 .. subq = xapian.Query(xapian.Query.OP_AND, "hello", "world")
158 .. q = xapian.Query(xapian.Query.OP_AND, [subq, "foo", xapian.Query("bar", 2)])
161 MatchAll and MatchNothing
162 -------------------------
164 In Xapian 1.3.0 and later, these are wrapped as static constants
165 ``xapian.Query.MatchAll`` and ``xapian.Query.MatchNothing``.
167 If you want to be compatible with earlier versions, you can continue to use
168 ``new xapian.Query("")`` instead of ``xapian.Query.MatchAll``
169 and ``new xapian.Query()`` instead of
170 ``xapian.Query.MatchNothing``.
172 .. FIXME: Need to define the custom output typemap to handle this if it
173 .. actually seems useful...
177 .. There is an additional method `GetMatchingTerms()` which takes
178 .. an MSetIterator and returns a list of terms in the current query which
179 .. match the document given by that iterator. You may find this
180 .. more convenient than using the TermIterator directly.
186 Custom MatchDeciders can be created in C#; simply subclass
187 Xapian.MatchDecider, and define an
188 Apply method that will do the work. The simplest example (which does nothing
189 useful) would be as follows:
193 class MyMatchDecider : Xapian.MatchDecider {
194 public override bool Apply(Xapian.Document doc) {