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
}
}