]> granicus.if.org Git - graphviz/commitdiff
a first cut at rendering to in-memory strings for script bindings.
authorellson <devnull@localhost>
Fri, 2 Nov 2007 17:02:07 +0000 (17:02 +0000)
committerellson <devnull@localhost>
Fri, 2 Nov 2007 17:02:07 +0000 (17:02 +0000)
lib/gvc/gvc.c
lib/gvc/gvc.h
lib/gvc/gvcjob.h
lib/gvc/gvdevice.c
tclpkg/gv/gv.cpp
tclpkg/gv/gv.i

index 84b12303a97f1a91677370ca4517c796cc1f53d6..b46d3f8bd37f6b97c1056de88955889b412de33e 100644 (file)
@@ -149,6 +149,51 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename)
     return 0;
 }
 
+/* Render layout in a specified format to a malloc'ed string */
+int gvRenderData(GVC_t *gvc, graph_t *g, char *format, char **result)
+{
+    int rc;
+    GVJ_t *job;
+
+    g = g->root;
+
+    /* create a job for the required format */
+    rc = gvjobs_output_langname(gvc, format);
+    job = gvc->job;
+    if (rc == NO_SUPPORT) {
+       agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n",
+                format, gvplugin_list(gvc, API_device, format));
+       return -1;
+    }
+
+    job->output_lang = gvrender_select(job, job->output_langname);
+    if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
+       fprintf(stderr, "Layout was not done\n");
+       return -1;
+    }
+
+#define OUTPUT_DATA_INITIAL_ALLOCATION 1000
+
+    if(!result || !(*result = malloc(OUTPUT_DATA_INITIAL_ALLOCATION))) {
+       agerr(AGERR, "failure malloc'ing for result string");
+       return -1;
+    }
+
+    **result = '\0';
+    job->output_data = *result;
+    job->output_data_allocated = OUTPUT_DATA_INITIAL_ALLOCATION;
+    job->output_data_position = 0;
+
+    gvRenderJobs(gvc, g);
+    gvrender_end_job(job);
+    gvdevice_finalize(job);
+
+    *result = job->output_data;
+    gvjobs_delete(gvc);
+
+    return 0;
+}
+
 char **gvcInfo(GVC_t* gvc) { return gvc->common.info; }
 char *gvcUsername(GVC_t* gvc) { return gvc->common.user; }
 char *gvcVersion(GVC_t* gvc) { return gvc->common.info[1]; }
index 8ce1547a44f58706c3f225d19b44ca890f83b539..d8103e5fe69adc80837b91de532ab3aef77f62bc 100644 (file)
@@ -90,6 +90,9 @@ extern int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out);
 /* Render layout in a specified format to an open FILE */
 extern int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename);
 
+/* Render layout in a specified format to a malloc'ed string */
+extern int gvRenderData(GVC_t *gvc, graph_t *g, char *format, char **result);
+
 /* Render layout according to -T and -o options found by gvParseArgs */
 extern int gvRenderJobs(GVC_t *gvc, graph_t *g);
 
index 22a7534ed7dc7460d9eb83764fd1accd2a585f96..7de64ab1750f0631e070fe7fecf2b77ee459ea50 100644 (file)
@@ -237,8 +237,12 @@ extern "C" {
        char *layout_type;
 
        char *output_filename;
-       char *output_langname;
        FILE *output_file;
+       char *output_data;
+       unsigned int output_data_allocated;
+       unsigned int output_data_position;
+
+       char *output_langname;
        int output_lang;
 
        gvplugin_active_render_t render;
index cee1761120999d17f86d2d2f40a5022e759eddd7..aef5b54aad4d0afb8c0b93ba24e88509c87d9557 100644 (file)
@@ -84,6 +84,18 @@ size_t gvdevice_write (GVJ_t * job, const unsigned char *s, unsigned int len)
        return gzwrite((gzFile *) (job->output_file), s, len);
 #endif
     }
+    else if (job->output_data) {
+       if (len > (job->output_data_allocated - (job->output_data_position + 1))) {
+           job->output_data_allocated = job->output_data_position + len + 1000;
+           job->output_data = realloc(job->output_data, job->output_data_allocated);
+           if (!job->output_data) {
+               fprintf(stderr, "failure realloc'ing for result string\n");
+               return 0;
+           }
+       }
+       strcpy(job->output_data + job->output_data_position, s);
+        job->output_data_position += len;
+    }
     else
        return fwrite(s, sizeof(char), len, job->output_file);
 }
@@ -138,48 +150,48 @@ void gvdevice_initialize(GVJ_t * job)
     if (gvde && gvde->initialize) {
        gvde->initialize(job);
     }
-    else {
-        /* if the device has no initialization then it uses file output */
-        if (!job->output_file) {        /* if not yet opened */
-            if (gvc->common.auto_outfile_names)
-                 auto_output_filename(job);
-            if (job->output_filename) {
-                 job->output_file = fopen(job->output_filename, "w");
-                 if (job->output_file == NULL) {
-                     perror(job->output_filename);
-                     exit(1);
-                 }
+    else if (job->output_data) {
+    }
+    /* if the device has no initialization then it uses file output */
+    else if (!job->output_file) {        /* if not yet opened */
+        if (gvc->common.auto_outfile_names)
+            auto_output_filename(job);
+        if (job->output_filename) {
+            job->output_file = fopen(job->output_filename, "w");
+            if (job->output_file == NULL) {
+                perror(job->output_filename);
+                exit(1);
             }
-            else
-                 job->output_file = stdout;
+        }
+        else
+            job->output_file = stdout;
 
 #ifdef WITH_CODEGENS
-            Output_file = job->output_file;
+        Output_file = job->output_file;
 #endif
 
 #ifdef HAVE_SETMODE
 #ifdef O_BINARY
-            if (job->flags & GVDEVICE_BINARY_FORMAT)
-                setmode(fileno(job->output_file), O_BINARY);
+        if (job->flags & GVDEVICE_BINARY_FORMAT)
+            setmode(fileno(job->output_file), O_BINARY);
 #endif
 #endif
 
-            if (job->flags & GVDEVICE_COMPRESSED_FORMAT) {
+        if (job->flags & GVDEVICE_COMPRESSED_FORMAT) {
 #if HAVE_LIBZ
-               int fd;
-
-               /* open dup so can gzclose independent of FILE close */
-               fd = dup(fileno(job->output_file));
-               job->output_file = (FILE *) (gzdopen(fd, "wb"));
-               if (!job->output_file) {
-                   (job->common->errorfn) ("Error initializing compression on output file\n");
-                   exit(1);
-               }
-#else
-               (job->common->errorfn) ("No libz support.\n");
+           int fd;
+
+           /* open dup so can gzclose independent of FILE close */
+           fd = dup(fileno(job->output_file));
+           job->output_file = (FILE *) (gzdopen(fd, "wb"));
+           if (!job->output_file) {
+               (job->common->errorfn) ("Error initializing compression on output file\n");
                exit(1);
-#endif
            }
+#else
+           (job->common->errorfn) ("No libz support.\n");
+           exit(1);
+#endif
         }
     }
 }
index b5042da32a905f24d580ca2f9a80b0c5a29fe4f6..2c37a6e2c65cb4e595bb3682ecb219e489db893e 100644 (file)
@@ -862,14 +862,14 @@ void render(Agraph_t *g, char *format, FILE *f)
     err = gvRender(gvc, g, format, f);
 }
 
-// FIXME - render to a caller provided memory blob
-void render(Agraph_t *g, char *format, void **data)
-{
-//    FIXME
-//
-//    int err;
-//
-//    err = gvRenderData(gvc, g, format, data);
+// render to a data string
+char* renderdata(Agraph_t *g, char *format)
+{
+    int err;
+    char *data;
+
+    err = gvRenderData(gvc, g, format, &data);
+    return data;
 }
 
 void write(Agraph_t *g, FILE *f)
index d5e76a9562fee1723b41a3177ff44d3fc6536234..9fdae98f8da0cd026f954ac13f35ec632f38dd07 100644 (file)
@@ -190,7 +190,7 @@ extern void render(Agraph_t *g);
 extern void render(Agraph_t *g, char *format);
 extern void render(Agraph_t *g, char *format, char *filename);
 extern void render(Agraph_t *g, char *format, FILE *f);
-extern void render(Agraph_t *g, char *format, void **data);
+extern char* renderdata(Agraph_t *g, char *format);
 
 /*** Writing graph back to file */
 void write(Agraph_t *g, FILE *f);