Code:
namespace MainLib.StructuredBinaries
{
public delegate void SetDelegate(object value);
public delegate object GetDelegate();
public interface IFieldFormat
{
Table Parent { get; set; }
string Name { get; }
int Index { get; }
SetDelegate GetSDelegate(List<byte[]> data, int YIndex);
GetDelegate GetGDelegate(List<byte[]> data, int YIndex);
}
public abstract class Bool8Field : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "A bool"; } }
public virtual int Index { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { data[YIndex][Index] = ((bool)value) ? (byte)1 : (byte)0; };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return (data[YIndex][Index] == 1) ? true : false; };
}
}
public abstract class Int8Field : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "A byte"; } }
public virtual int Index { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { data[YIndex][Index] = (byte)value; };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return data[YIndex][Index]; };
}
}
public abstract class Int16Field : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "A short"; } }
public virtual int Index { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { Tools.PutBytes(data[YIndex], Index, (short)value); };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return Tools.TakeInt16(data[YIndex], Index); };
}
}
public abstract class Int32Field : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "An int"; } }
public virtual int Index { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { Tools.PutBytes(data[YIndex], Index, (int)value); };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return Tools.TakeInt32(data[YIndex], Index); };
}
}
public abstract class SingleField : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "A float"; } }
public virtual int Index { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { Tools.PutBytes(data[YIndex], Index, (float)value); };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return Tools.TakeSingle(data[YIndex], Index); };
}
}
public abstract class StringField : IFieldFormat
{
public virtual Table Parent { get { return null; } set { } }
public virtual string Name { get { return "A fixed string"; } }
public virtual int Index { get { return 0; } }
public virtual int Size { get { return 0; } }
public SetDelegate SetSDelegate(List<byte[]> data, int YIndex)
{
return delegate(object value) { Tools.PutBytes(data[YIndex], Index, (string)value, Size); };
}
public GetDelegate GetSDelegate(List<byte[]> data, int YIndex)
{
return delegate() { return Tools.TakeString(data[YIndex], Index, Size); };
}
}
public interface ITableFormat
{
Table Parent { get; set; }
string Name { get; }
IFieldFormat[] Fields { get; }
int RecordLength { get; }
}
public class Table
{
public List<byte[]> Data;
public ITableFormat Format;
public int XDimension
{
get
{
return Format.RecordLength;
}
}
public int YDimension
{
get
{
return Data.Count;
}
}
public int Size
{
get
{
return XDimension * YDimension;
}
}
public byte[] Bytes
{
set
{
if ((value.Length % XDimension) != 0) throw new ArgumentException("Invalid data for the " + Format.Name + " table");
byte[] temp = new byte[XDimension];
Data = new List<byte[]>();
for (int i = 0; i < (value.Length / XDimension); i++)
{
Array.ConstrainedCopy(value, i * XDimension, temp, 0, XDimension);
Data.Add(temp);
}
}
get
{
byte[] temp = new byte[XDimension * YDimension];
for (int i = 0; i < YDimension; i++) Array.ConstrainedCopy(Data[i], 0, temp, i * XDimension, XDimension);
return temp;
}
}
public object this[int YIndex, int XIndex]
{
get
{
return Format.Fields[XIndex].GetGDelegate(Data, YIndex)();
}
set
{
Format.Fields[XIndex].GetSDelegate(Data, YIndex)(value);
}
}
public Table(ITableFormat format)
{
Format = format;
}
public Table(ITableFormat format, byte[] data)
{
Format = format;
Bytes = data;
}
}
}
Please tell me your opinion on this. Its an improved version of what im using in the exes. The various formats are based on these classes and there is a way to make a class that dynamically creates the format of the table (but i use fixed formats to increase speed).
PS: i think ive forgot to mark some things as static but nvm about details. Im just wondering if the concept is right, cause there seem to be numerous ways to solve the problem. Btw, since all interaction a user can have (or even importing/exporting the data to and from a db) requires strings, i use objects and the .ToString() method which converts accordingly to the type. Setting the data doesnt use strings tho, but i can easily change it.