using System; using System.Runtime.InteropServices; using System.Text; namespace Xpace { #if _WIN64 [StructLayout(LayoutKind.Explicit, Size = 8)] #else [StructLayout(LayoutKind.Explicit, Size = 4)] #endif public unsafe struct Xpace_TableCursor { [FieldOffset(0)] public void* v; } public class TableCursor : 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_Error Xpace_TableCursor_Create // (Xpace_String c, // Xpace_TableCursor* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_Create ([MarshalAs(UnmanagedType.LPWStr)] String config, Xpace_TableCursor* result); //Xpace_Error Xpace_TableCursor_Destroy // (Xpace_TableCursor); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static extern void Xpace_TableCursor_Destroy (Xpace_TableCursor tc); //XPACE_EXPORT Xpace_Error _stdcall Xpace_TableCursor_getConfig // (const Xpace_TableCursor, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getConfig (Xpace_TableCursor tc, char** result); //Xpace_Error Xpace_TableCursor_getName // (Xpace_TableCursor, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getName (Xpace_TableCursor tc, char** result); //Xpace_Error Xpace_TableCursor_isEmpty // (Xpace_TableCursor, // bool* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_isEmpty (Xpace_TableCursor tc, bool* result); //Xpace_Error Xpace_TableCursor_getColumnConfig // (Xpace_TableCursor, // uint col, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getColumnConfig (Xpace_TableCursor tc, uint col, char** result); //Xpace_Error Xpace_TableCursor_getRowCount // (Xpace_TableCursor, // uint64* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getRowCount (Xpace_TableCursor tc, UInt64* result); //Xpace_Error Xpace_TableCursor_getColumnCount // (Xpace_TableCursor, // uint* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getColumnCount (Xpace_TableCursor tc, uint* result); //Xpace_Error Xpace_TableCursor_moveToRow // (Xpace_TableCursor, // uint64 row, // bool* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_moveToRow (Xpace_TableCursor tc, UInt64 row, bool* result); //Xpace_Error Xpace_TableCursor_getCellStr // (Xpace_TableCursor, // uint column, // Xpace_String* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getCellStr (Xpace_TableCursor tc, uint col, char** result); //Xpace_Error Xpace_TableCursor_getCellInt // (const Xpace_TableCursor, // uint column, // bool* ok, // int64* result); [DllImport("xpace.dll", CharSet = CharSet.Unicode)] private static unsafe extern IntPtr Xpace_TableCursor_getCellInt (Xpace_TableCursor tc, uint column, bool* ok, Int64* result); #endregion #region private data internal Xpace_TableCursor _table_cursor; // internal because Search needs this private SchemaTable _schema_table; private bool _disposed = false; #endregion #region Constructor / Destructor /// /// Constructor /// /// the Table's Configuration public TableCursor (string config) { unsafe { fixed (Xpace_TableCursor* tc = &_table_cursor) { IntPtr err = Xpace_TableCursor_Create(config, tc); if (err != IntPtr.Zero) throw new XpaceException(err); } } _schema_table = new SchemaTable(this); } public void Dispose () { CleanUp(); GC.SuppressFinalize(this); } private void CleanUp () { if (!_disposed) { Xpace_TableCursor_Destroy(_table_cursor); _disposed = true; } } ~TableCursor () { CleanUp(); } #endregion #region properties /// /// Is the table empty? /// /// true iff the table is empty public bool isEmpty { get { unsafe { if (_table_cursor.v != null) { bool result; IntPtr err = Xpace_TableCursor_isEmpty(_table_cursor, &result); if (err != IntPtr.Zero) throw new XpaceException(err); return result; } } return true; } } public string config { get { string ret; unsafe { char* c_str; IntPtr err = Xpace_TableCursor_getConfig(_table_cursor, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new string(c_str); Xpace_String_Destroy(c_str); } return ret; } } public string name { get { string ret; unsafe { char* c_str; IntPtr err = Xpace_TableCursor_getName(_table_cursor, &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 columns in the table /// /// The number of columns public uint columnCount { get { uint ret; unsafe { IntPtr err = Xpace_TableCursor_getColumnCount(_table_cursor, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); } return ret; } } /// /// The number of rows in the table /// /// The number of rows public UInt64 rowCount { get { UInt64 ret; unsafe { IntPtr err = Xpace_TableCursor_getRowCount(_table_cursor, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); } return ret; } } #endregion #region column properties /// /// Get a column's configuration /// /// the column number /// the column's Configuration public string getColumnConfig (uint col) { string ret; unsafe { char* c_str; IntPtr err = Xpace_TableCursor_getColumnConfig(_table_cursor, col, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new string(c_str); Xpace_String_Destroy(c_str); } return ret; } #endregion public SchemaTable getSchema () { return _schema_table; } #region access /// /// Move cursor to a row in the table /// /// move cursor to this row /// true if successful, false (and don't move) if not public bool moveToRow (UInt64 row) { bool ret; unsafe { IntPtr err = Xpace_TableCursor_moveToRow(_table_cursor, row, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); } return ret; } /// /// get the (string) contents of a cell from the current row /// /// from this column /// the (string) contents of the cell public string getCellStr (uint col) { string ret; unsafe { char* c_str; IntPtr err = Xpace_TableCursor_getCellStr(_table_cursor, col, &c_str); if (err != IntPtr.Zero) throw new XpaceException(err); ret = new String(c_str); Xpace_String_Destroy(c_str); } return ret; } /// /// get the (integer) contents of a cell from the current row /// /// from this column /// fillin true iff successful /// the (integer) contents of the cell public Int64 getCellInt (uint col, out bool ok) { Int64 ret; unsafe { bool o; IntPtr err = Xpace_TableCursor_getCellInt(_table_cursor, col, &o, &ret); if (err != IntPtr.Zero) throw new XpaceException(err); ok = o; } return ret; } #endregion } }