jacob navia wrote:[color=blue]
> I am writing software to make a general storage
> facility of any kind of objects to/from disk.
> [...]
> The "wizard" software generates the following functions:
> ----------------------------------------------
> //@ Serialization function for structure structure
> int structureSerialize(structure *data,FILE *out)
> {
> int i;
> unsigned char *p;
> if (data == NULL)
> return 0;
> if (!initialized) {
> InitXmlWriter(out);
> initialized=1;
> }[/color]
Is `initialized' a static variable somewhere? If so,
it seems you can have only one XmlWriter stream active at
a time, or maybe even at all.
A possible alternative would be to wrap the FILE* in
a struct of its own along with whatever state variables
are needed, so you can do
XmlWriter *outxml = NewXmlWriter(out);
.... and then pass an XmlWriter* to all the wizard-generated
("charmed?") functions.
[color=blue]
> fprintf(out,"<Object id=\"ID%x\"
> typename=\"structure\">\n",(int)data);[/color]
Non-portable (as I expect you know), since the conversion
from pointer to int is implementation-defined and perhaps
meaningless. Even if the conversion does something simple
like "just copy the bits," the generated object IDs might
not be unique (if int is narrower than pointer, say, or if
dynamic memory management re-uses a free()d object's memory).
[color=blue]
> fprintf(out,"\t<byte name=\"a\">%d</byte>\n",data->a);
> fprintf(out,"\t<int name=\"b\">%d</int>\n",data->b);
> fprintf(out,"\t<int name=\"c\">%d</int>\n",data->c);
> ...[/color]
Bleah. Have you considered a table-driven solution?
[color=blue]
> // Type long double not supported natively.
> // Using hexadecimal encoding
> p = (unsigned char *)&data->g;
> fprintf(out,"\t<bin.hex name=\"g\">");
> for(i=0; i<12;i++) {
> fprintf(out,"%x",*(p++) & 0xff);
> }[/color]
Non-portable, of course.
[color=blue]
> structureSerialize(data->Next,out); // follow the Next pointer
> TabSerialize(&data->tab,out); // Follow embedded structures[/color]
I'd have expected these to be done in the opposite order
(but I haven't read the M'soft specs). Either way, though,
using recursion to chase what might be a long linked list is
not a wonderful idea.
[color=blue]
> return 1;[/color]
If `1' means "success," maybe this should be written
as `return !ferror(out);' or some such.
[color=blue]
> 3) Open issues are what to do with:
> A) Unions. In my opinion there is no way to know which of the
> members of the union is valid, so unions will not be followed
> and just stored in binary form.[/color]
Hence non-portable.
[color=blue]
> B) Function pointers. There is no easy way to know what is
> the name of the function stored in a function pointer.
> Storing the pointer may be useful if the program is loaded
> at the same address.[/color]
... and hasn't been recompiled or even relinked, and
hasn't been loaded with a newer version of a shared library,
and isn't running under a debugger and ...
There's also the problem that C doesn't define the
conversion of a function pointer to any numeric datum; the
only way to get a portable representation would be to deal
with the pointer's constituent bytes. The byte stream would
be interpretable by but meaningless to a recipient other than
the same program (if lucky), hence non-portable.
If you have a table of "pointable" functions you can
translate the pointer to a name easily enough -- and such
a table would seem necessary on the receiving end, to get
from name back to function pointer again. If you get hold
of a function pointer whose target is not in your table,
I think you should announce a serialization failure.
[color=blue]
> Questions:
>
> Are any of you aware of an implementation of this in C?
>
> What would you propose for unions and function pointers?[/color]
If you can't support them usefully, don't support them
at all. Opinion only; YMMV.
[color=blue]
> Are there any other standards for datatypes in XML besides
> the one mentioned above?[/color]
I don't know. Probably. My counter-question: Since you're
committed to a non-portable representation anyhow (c.f. the
treatment of `long double'), why fool around with XML? What
advantage does it offer if the portably-packaged content isn't
itself portable?
--
Eric.Sosman@sun.com