using System; using System.Collections; using System.Runtime.InteropServices; using System.Text; namespace Xpace { #region External Struct Xpace_Index #if _WIN64 [StructLayout(LayoutKind.Explicit, Size = 8)] #else [StructLayout(LayoutKind.Explicit, Size = 4)] #endif public unsafe struct Xpace_Index { [FieldOffset(0)] public void* v; } #endregion public class Index : IDisposable { #region DLL calls //void Xpace_String_Destroy // (Xpace_String); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern void Xpace_String_Destroy (char* str); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Index_Create // (const Xpace_String config, // Xpace_Index* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_Index_Create ([MarshalAs(UnmanagedType.LPWStr)] string config, Xpace_Index* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Index_getConfig // (const Xpace_TableCursor, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_Index_getConfig (Xpace_Index tc, char** result); //XPACE_EXPORT void _stdcall Xpace_Index_Destroy // (Xpace_Index ix); [DllImport("xpace.dll")] private static extern void Xpace_Index_Destroy (Xpace_Index index); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Index_isEmpty // (const Xpace_Index ix, // bool* result); [DllImport("xpace.dll")] private static unsafe extern IntPtr Xpace_Index_isEmpty (Xpace_Index index, bool* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Index_getTermCount // (const Xpace_Index ix, // uint64* result); [DllImport("xpace.dll")] private static unsafe extern IntPtr Xpace_Index_getTermCount (Xpace_Index index, UInt64* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Index_getTerms // (const Xpace_Index ix, // uint64 begin, // uint64 count, // bool includeCounts, // Xpace_Result* result); [DllImport("xpace.dll")] private static unsafe extern IntPtr Xpace_Index_getTerms (Xpace_Index index, UInt64 begin, UInt64 count, bool includeCounts, Xpace_Result* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Eval // (const Xpace_Index index, // Xpace_String query, // uint64 recCount, // Xpace_RefListCursor* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_Index_Eval (Xpace_Index index, [MarshalAs(UnmanagedType.LPWStr)] string query, UInt64 recCount, Xpace_RefListCursor* result); #endregion #region private data internal Xpace_Index _index; // internal because Search needs this private bool _disposed = false; #endregion #region Constructor / Destructor /// /// Constructor /// /// the Table's Configuration public Index (string config) { unsafe { fixed (Xpace_Index* index = &_index) { IntPtr err = Xpace_Index_Create(config, index); if (err != IntPtr.Zero) throw new XpaceException(err); } } } internal unsafe Index (Xpace_Index index) { _index = index; } public void Dispose () { CleanUp(true); GC.SuppressFinalize(this); } public void CleanUp (bool disposing) { if (!_disposed) { Xpace_Index_Destroy(_index); _disposed = true; } } ~Index () { CleanUp(false); } #endregion #region properties /// /// Is the table empty? /// /// true iff the table is empty public bool isEmpty { get { unsafe { if (_index.v != null) { bool result; IntPtr err = Xpace_Index_isEmpty(_index, &result); if (err != IntPtr.Zero) throw new XpaceException(err); return result; } } return true; } } /// /// Get the Index's configuration /// /// the configuration public string config { get { string ret; unsafe { char* c_str; IntPtr err = Xpace_Index_getConfig(_index, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new string(c_str); Xpace_String_Destroy(c_str); } return ret; } } /// /// The number of terms in the index /// /// The number of terms public UInt64 termCount { get { UInt64 ret; unsafe { IntPtr err = Xpace_Index_getTermCount(_index, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); } return ret; } } #endregion #region index access public Result getTerms (UInt64 begin, UInt64 count, bool includeCounts) { unsafe { Xpace_Result res; IntPtr err = Xpace_Index_getTerms(_index, begin, count, includeCounts, &res); if (err != IntPtr.Zero) throw new XpaceException(err); return new Result(&res); } } public RefList eval (string query, UInt64 recCount) { unsafe { Xpace_RefListCursor res; IntPtr err = Xpace_Index_Eval(_index, query, recCount, &res); if (err != IntPtr.Zero) throw new XpaceException(err); return new RefList(res); } } #endregion } #region External Struct Xpace_IndexList #if _WIN64 [StructLayout(LayoutKind.Explicit, Size = 8)] #else [StructLayout(LayoutKind.Explicit, Size = 4)] #endif public unsafe struct Xpace_IndexList { [FieldOffset(0)] public void* v; } #endregion public class IndexList : IDisposable { #region DLL calls //void Xpace_String_Destroy // (Xpace_String); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern void Xpace_String_Destroy (char* str); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_Create // (Xpace_String config, // bool overwrite, // Xpace_IndexList* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_Create ([MarshalAs(UnmanagedType.LPWStr)] String config, bool overwrite, Xpace_IndexList* result); //XPACE_EXPORT void _stdcall Xpace_IndexList_Destroy // (Xpace_IndexList il); [DllImport("xpace.dll")] private static unsafe extern void Xpace_IndexList_Destroy (Xpace_IndexList il); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_getConfig // (Xpace_IndexList il, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_getConfig (Xpace_IndexList il, char** result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_getCount // (const Xpace_IndexList il, // size_t* result); [DllImport("xpace.dll")] private static unsafe extern IntPtr Xpace_IndexList_getCount (Xpace_IndexList il, uint* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_getIndexConfig // (const Xpace_IndexList il, // size_t indexNum, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_getIndexConfig (Xpace_IndexList il, uint indexNum, char** result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_openIndexName // (const Xpace_IndexList il, // const Xpace_String indexName, // uint* indexNum, // Xpace_String config, // Xpace_Index* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_openIndexName (Xpace_IndexList il, [MarshalAs(UnmanagedType.LPWStr)] String indexName, uint* indexNum, [MarshalAs(UnmanagedType.LPWStr)] String config, Xpace_Index* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_IndexList_openIndexNum // (const Xpace_IndexList il, // uint indexNum, // Xpace_String config, // Xpace_Index* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_openIndexNum (Xpace_IndexList il, uint indexNum, [MarshalAs(UnmanagedType.LPWStr)] String config, Xpace_Index* result); //XPACE_EXPORT Xpace_Error _stdcall Xpace_Eval // (const Xpace_IndexList indexList, // Xpace_String query, // uint64 recCount, // Xpace_RefListCursor* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_IndexList_Eval (Xpace_IndexList indexList, [MarshalAs(UnmanagedType.LPWStr)] string query, UInt64 recCount, Xpace_RefListCursor* result); #endregion #region private data internal Xpace_IndexList _index_list; // internal because Search needs this private bool _disposed = false; #endregion #region Constructor / Destructor /// /// Constructor /// /// the IndexList's Configuration public IndexList (string config) { unsafe { fixed (Xpace_IndexList* il = &_index_list) { IntPtr err = Xpace_IndexList_Create(config, false, il); if (err != IntPtr.Zero) throw new XpaceException(err); } } } public void Dispose () { CleanUp(); GC.SuppressFinalize(this); } private void CleanUp () { if (!_disposed) { Xpace_IndexList_Destroy(_index_list); _disposed = true; } } ~IndexList () { CleanUp(); } #endregion #region properties /// /// Get the IndexLists's configuration /// /// the configuration public string config { get { string ret; unsafe { char* c_str; IntPtr err = Xpace_IndexList_getConfig(_index_list, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new string(c_str); Xpace_String_Destroy(c_str); } return ret; } } /// /// How many Indexes in the IndexList /// /// The number of Indexes in the Index List public uint count { get { uint ret; unsafe { IntPtr err = Xpace_IndexList_getCount(_index_list, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); } return ret; } } #endregion #region Index properties /// /// Get an Index's configuration /// /// the number of the index /// the configuration public string getIndexConfig (uint indexNum) { string ret; unsafe { char* c_str; IntPtr err = Xpace_IndexList_getIndexConfig(_index_list, indexNum, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new string(c_str); Xpace_String_Destroy(c_str); } return ret; } #endregion #region Open Index /// /// Open an Index by name /// /// The index's name /// Fill in the index's number /// The Index public Index openIndex (string name, out uint indexNum) { unsafe { Xpace_Index index; IntPtr err; fixed (uint* idxNum = &indexNum) { err = Xpace_IndexList_openIndexName(_index_list, name, idxNum, null, &index); } if (err != IntPtr.Zero) throw new XpaceException(err); return new Index(index); } } /// /// Open an Index by number /// /// The index number /// The opened Index public Index openIndex (uint indexNum) { unsafe { Xpace_Index index; IntPtr err = Xpace_IndexList_openIndexNum(_index_list, indexNum, null, &index); if (err != IntPtr.Zero) throw new XpaceException(err); return new Index(index); } } public RefList eval (string query, UInt64 recCount) { unsafe { Xpace_RefListCursor res; IntPtr err = Xpace_IndexList_Eval(_index_list, query, recCount, &res); if (err != IntPtr.Zero) throw new XpaceException(err); return new RefList(res); } } #endregion } }