#include "output/spv/spv-legacy-decoder.h"
#include "output/spv/spv-light-decoder.h"
#include "output/spv/structure-xml-parser.h"
+#include "output/spv/vizml-parser.h"
#include "gl/c-ctype.h"
#include "gl/intprops.h"
return item->type == SPV_ITEM_TABLE;
}
+bool
+spv_item_is_graph (const struct spv_item *item)
+{
+ return item->type == SPV_ITEM_GRAPH;
+}
+
bool
spv_item_is_text (const struct spv_item *item)
{
{
if (spv_item_is_table (item))
spv_item_get_table (item);
+ else if (spv_item_is_graph (item))
+ spv_item_get_graph (item);
}
bool
spv_item_get_raw_legacy_data (const struct spv_item *item,
void **data, size_t *size)
{
- if (!spv_item_is_legacy_table (item))
- return xstrdup ("not a legacy table object");
+ if (!spv_item_is_legacy_table (item) && !spv_item_is_graph (item))
+ return xstrdup ("not a graph or legacy table object");
+
+ if (!item->bin_member)
+ return xstrdup ("graph or legacy table lacks legacy data");
return zip_member_read_all (item->spv->zip, item->bin_member, data, size);
}
return item->table;
}
+static char * WARN_UNUSED_RESULT
+spv_open_graph (struct spv_item *item)
+{
+ assert (spv_item_is_graph (item));
+
+ struct spv_data data;
+ char *error = spv_item_get_legacy_data (item, &data);
+ if (error)
+ {
+ struct string s = DS_EMPTY_INITIALIZER;
+ spv_item_format_path (item, &s);
+ ds_put_format (&s, " (%s): %s", item->bin_member, error);
+
+ free (error);
+ return ds_steal_cstr (&s);
+ }
+
+ xmlDoc *doc;
+ error = spv_read_xml_member (item->spv, item->xml_member, false,
+ "visualization", &doc);
+ if (error)
+ {
+ spv_data_uninit (&data);
+ return error;
+ }
+
+ struct spvxml_context ctx = SPVXML_CONTEXT_INIT (ctx);
+ struct vizml_visualization *v;
+ vizml_parse_visualization (&ctx, xmlDocGetRootElement (doc), &v);
+ error = spvxml_context_finish (&ctx, &v->node_);
+
+ if (error)
+ {
+ struct string s = DS_EMPTY_INITIALIZER;
+ spv_item_format_path (item, &s);
+ ds_put_format (&s, " (%s): %s", item->xml_member, error);
+
+ free (error);
+ error = ds_steal_cstr (&s);
+ }
+
+ spv_data_uninit (&data);
+ vizml_free_visualization (v);
+ if (doc)
+ xmlFreeDoc (doc);
+
+ return error;
+}
+
+void
+spv_item_get_graph (const struct spv_item *item_)
+{
+ struct spv_item *item = CONST_CAST (struct spv_item *, item_);
+
+ assert (spv_item_is_graph (item));
+ if (!item->graph)
+ {
+ item->graph = true;
+ char *error = spv_open_graph (item);
+ if (error)
+ {
+ item->error = true;
+ msg (ME, "%s", error);
+ free (error);
+ }
+ }
+}
+
/* Constructs a new spv_item from XML and stores it in *ITEMP. Returns NULL if
successful, otherwise an error message for the caller to use and free (with
free()).
item->subtype = xstrdup_if_nonempty (table->sub_type);
if (ts->path)
{
- item->xml_member = ts->path ? xstrdup (ts->path->text) : NULL;
+ item->xml_member = xstrdup_if_nonempty (ts->path->text);
char *error = decode_spvsx_legacy_properties (
table->table_properties, &item->legacy_properties);
if (error)
}
else if (spvsx_is_graph (content))
{
- struct spvsx_graph *graph = spvsx_cast_graph (content);
item->type = SPV_ITEM_GRAPH;
+
+ struct spvsx_graph *graph = spvsx_cast_graph (content);
+ item->bin_member = xstrdup_if_nonempty (graph->data_path->text);
item->command_id = xstrdup_if_nonempty (graph->command_name);
- /* XXX */
+ item->xml_member = xstrdup_if_nonempty (graph->path->text);
}
else if (spvsx_is_model (content))
{