structs, templates, alias
Ellery Newcomer
ellery-newcomer at utulsa.edu
Sun Apr 25 08:04:33 PDT 2010
Hello.
I have a bunch of disparate binary record types that I need to be able
to read and write to/from a binary stream. Currently, the way I do this
is just by drumming out a struct declaration and relying on the tupleof
property to specify how to read/write.
Ex:
struct Rec0{
ushort index1;
ushort index2;
ushort index3;
ushort junk;
double value;
}
Rec rec;
// blit knows!
blit(rec, x"01 00 12 00 05 00 00 00 7F F8 00 00 00 00 00 00");
It works really well for simple cases. However, there are some records
that have really complicated substructures.
struct Rec1{
ushort index;
ushort options;
ushort nparams;
Parameter[] params;
}
struct Parameter{
ParamType pt;
union{
STRING str;
CV param;
}
}
etc etc
for params, or any substructure dependent on a length field, if the
length field immediately precedes the structure, I can wrap the two in a
struct which my read/write routines can treat specially as the next
contiguous field. Well and good.
What's really annoying is when the length field and the array/structure
are separated by one or more fields, eg.
struct Rec2{
ushort index;
ushort nparams;
ushort options;
Parameter[] params;
}
At the moment, I just special case these records. However, I would very
much like to annotate their fields somehow so that the io routines can
treat them like any other record. One thing I thought about was using
templates to express this:
struct Rec1{
ushort index;
ushort options;
Parameters!() params;
}
struct Rec2{
ushort index;
ushort nparams;
ushort options;
Parameters!(nparams) params;
}
// blit knows it can call member blit on this struct
// one thing I like about this is that it always knows
// about the length field, and can automatically modify
// it when you do something with the parameter array.
struct Parameters(alias k = __dflt__){
static if(k.stringof == "__dflt__") ushort len;
else alias k len;
Parameter[] _params;
int blit(byte[] data){
int pos = 0;
static if(k.stringof == "__dflt__") pos = read(len,data);
//else assume len has already been read
params.length = len;
...
// read params
}
}
That doesn't work, though, as DMD complains about inaccessible frames or
something. I suppose it probably shouldn't work.
Does anyone have any ideas regarding this problem?
More information about the Digitalmars-d-learn
mailing list