dvidelabs / flatcc

FlatBuffers Compiler and Library in C for C
Apache License 2.0
632 stars 180 forks source link

Is there a implemention for printing flat-buffers to XML? #189

Closed Dweller closed 3 years ago

Dweller commented 3 years ago

Hi There, great C based resource just about got my head around building flatbuffers..

I would like to choose to dump the finalised flatbuffers into JSON and XML syntax output..

JSON is easy enough but is there any implementation for printing out to XML syntax?

Thanks in advance

mikkelfj commented 3 years ago

Hi, there is only JSON output.

It should not be too difficult to adapt the current JSON printer to print XML instead for private use, but I would not accept such a contribution without a parser as well.

I have an alternative unpublished branch with a more pluggable parser structure where it would be possible to add XML parsing. It is comparatively much harder to parse than to print.

There is also no common standard for how XML is translated to and from FlatBuffers.

Dweller commented 3 years ago

Thanks.. I was just looking at the codegen_c_json_printer which does look relatively easy to hack into a XML version..

I doubt I'll need a XML parser on our current roadmap.. I'm only doing the XML output as a legacy option.. Going forwards will be responding with flatbuffers ;-)

mikkelfj commented 3 years ago

Most of the formatting is done in

https://github.com/dvidelabs/flatcc/blob/master/src/runtime/json_printer.c

So you might be able to print XML by replacing just that file. Of course it is cleaner with function names containing xml instead of json, but as a starting point it might work.

Dweller commented 3 years ago

OK I've finally got my flatcc implementation working for raw FBS and JSON.. So I've taken a copy fo the json print files/methods and created renamed xml versions..

Now my plan is to default all of the flat buffer values as text unless an tag attribute is set on against field entries in the schema..

attribute "tag";

table user
{
   name : string (tag);
   age: int (tag) ;
   address: string;
}

Which means the XML output would look like..

Users address

And the JSON output would be.. (AS it doesn't have a concept of tags))

{ user: { name: "Simon", age: 57, address: "Users address' } }

Can you point me at in the direction for checking the schema defined attributes from codegen_c_json_printer.c level so I can alter the generated code format for xml?

I can see fb_attribute defined.. and used in semantics.c and parser.c and it appears to store the known attributes in the root_schema attribute_table. But it would be great to have some clarification.

mikkelfj commented 3 years ago

I'm not sure if there is a method to look up attributes - it's not very well supported. But you can have a look at the function export_attributes and how it is called in compiler/codegen_schema.c This function iterates over all the attributes of a symbol such as a table field and extracts the string as a pointer and length before storing it in a new flatbuffer representing the schema. You can create a similar loop to search for the attributes that you are interested in.

I think maybe there is an easier way, but I can't seem to find it, and I'm not sure there is one.

Dweller commented 3 years ago

I've worked around the issue by make my tag attribute a 'known' type which means its a simple meta flag check.. Its more of a change to the flatc code that I wanted todo.. As it will make pulls and rebases more work but it will do for now..

if (member->metadata_flags & fb_f_tag) { blah }

mikkelfj commented 3 years ago

Yeah, I wouldn't recommend it, but it is for the same reason I don't think there is more support for it - it's easier to add a flag.

Dweller commented 3 years ago

Thanks Mike.. your set my mind at rest I'm not on a wild goose chase :-)

mikkelfj commented 3 years ago

Personally, I would write a small utility function int fb_find_attr_n(const fb_metadata_t *m, const char *s, size_t len, const char **s_out, size_t *len_out). Returns 0 if found, -1 if not with unchanged output. Not sure about the s_out param type exactly. Finds first match among multiple. If there are multiple, it is considered an error the parser does not check for (recently agreed upon semantics). EDIT: and if s_out is null, just return 0 if exists.

I wonder if there is such a function somewhere already. Otherwise it could be merged upstream.

Dweller commented 3 years ago

Yes that's probably a more sustainable approach.. :-), however since I've already done it as a new known type I'll see how it pans out.. If it comes back to haunt me I can revisit then.. I'll focus on getting the XML output working and leave that part of the implementation as fine tuning..