|
From: William F. D. <wil...@th...> - 2007-01-05 21:30:33
|
Hi Mike,
This must be a common app for flexml -- it's one of my own main uses for
it. I too need to do marshalling and the reverse for basic values, and
recursive types built from them by vectoring and map (hash-table)
formation, down to any depth. (E.g. lists of lists of maps of strings,
etc.) My implementation language is C++, which (IMO) makes things a
little cleaner than straight C since I don't need to use void*, or
casting operations anyplace.
It is a fundamental limitation of flex that the communication between
actions can only take place by global variables. There is no way around
that.
But you can structure your code so that it is quite clean by using stack
operations. This strategy will work for any basic data types and any
collection of type constructors (e.g. vector-formation,
struct-formation, binding_comp_list-formation, etc.) One global Stack
object is all you need.
When a start tag is seen in the XML, push onto the stack a placeholder
object. When an end tag is seen, you'll know how many objects to pop
(and what types they should be); pop them and build your object, putting
it into the placeholder you had pushed. For type constructors (like
vector<> in C++) that take a variable number of parameters, use the
'cons' strategy from LISP; that is, cons in each argument as you
encounter it, as if you were building a right-branching binary tree.
You definitely don't want to be allocating and freeing in every action
-- let your stack operation (push/pop) definitions do that for you.
I can send you some sample C++ code that implements these ideas if that
would be useful.
Will
On Fri, 2007-01-05 at 17:10 +0000, Mike Aubury wrote:
> Hi - i've managed to do some *really* nice things with this software - but one
> thing keeps me back.
> Is there anyway to pass data around within the actions ?
>
>
> Background
>
> I'm trying to marshall (serialize) some C structures into XML.
> I've got a program which parses a definition of a C structure (if you've ever
> used RPCGEN or ONCRPC - it works on the same principle (and uses the .x file
> syntax :-)) and generates some code which dumps the XML.
>
> I'm now trying to get my parser to generate the .dtd and .act files for
> reading that file back in...
>
> Take this snippet of XML :
>
> <binding_comp_list>
> <binding_comp_list__abind VALUE="0"/>
> <binding_comp_list__type VALUE="70"/>
> <binding_comp_list__data SET='TRUE' VALUE=""/>
> </binding_comp_list>
>
> Ideally - I'd want to
> 1) allocate some memory for the binding_comp_list structure
> in the 'start' for 'binding_comp_list'
> 2) use that parent to set the data..
> 3) use that memory in the 'end' 'binding_comp_list' to set something else..
>
> ATM - i've done it using a series of temporary variables - but its really
> messy (because these things can recurse - so I can't just declare once
> temporary binding_comp_list - I need to use a dynamic array..)
> It gets even worse when the structure contains structure or an array ( or an
> array of structures!)
>
>
>
> For reference - that binding_comp_list is defined as :
>
> struct binding_comp_list {
> long abind;
> int type;
> string data; // basically a char*
> };
>
>
>
> My current actions look like this (excuse any errors - i've modified this from
> the original for readability!):
>
> <start tag='something_using_a_binding_comp_list'>
> <![CDATA[
> Allocate("binding_comp_list", (void *)&tmp_binding_comp_list,
> &tmp_binding_comp_list_cnt, sizeof(struct binding_comp_list));
> ]]>
> </start>
>
>
>
> <end tag='something_using_a_binding_comp_list'>
> <![CDATA[
>
> setsomething=tmp_binding_comp_list[tmp_binding_comp_list_cnt-1];
>
> FreeMemory("binding_comp_list",(void ***)&tmp_binding_comp_list,
> &tmp_binding_comp_list_cnt,1);
>
> ]]>
> </end>
>
>
>
> <end tag='binding_comp_list__abind'>
> <![CDATA[
> tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->abind=atol({VALUE});
>
> ]]>
> </end>
>
>
> <end tag='binding_comp_list__type'>
> <![CDATA[
> tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->type=atol({VALUE});
> ]]>
> </end>
>
> <end tag='binding_comp_list__data'>
> <![CDATA[
> if (isyes({SET})) {
> tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=strdup({VALUE});
> } else {
> tmp_binding_comp_list[tmp_binding_comp_list_cnt-1]->data=0;
> }
>
> ]]>
> </end>
>
> Any thoughts ?
>
>
> (Or alternative ways of marshalling the C to XML and back ?!)
>
--
William F Dowling
wil...@th...
www.scientific.thomson.com
|