From 7d7fc47a2a2ce31a3726e422b1c35c9a213add61 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 21 Nov 2014 19:22:54 -0800 Subject: [PATCH] Split the low-level print stream code into a separate file. Put the low-level print stream code from epan/print.c into epan/print_stream.c, leaving the higher-level stuff in print.c Change-Id: Iae961f168ec655a29f434257b1af0937fca9f025 Reviewed-on: https://code.wireshark.org/review/5436 Reviewed-by: Guy Harris --- epan/CMakeLists.txt | 1 + epan/Makefile.common | 2 + epan/print.c | 368 ++----------------------------------------- epan/print.h | 39 +---- epan/print_stream.c | 367 ++++++++++++++++++++++++++++++++++++++++++ epan/print_stream.h | 73 +++++++++ 6 files changed, 463 insertions(+), 387 deletions(-) create mode 100644 epan/print_stream.c create mode 100644 epan/print_stream.h diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 7183de42bc..9827d71679 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1586,6 +1586,7 @@ set(LIBWIRESHARK_FILES packet-range.c packet.c print.c + print_stream.c prefs.c proto.c ps.c diff --git a/epan/Makefile.common b/epan/Makefile.common index e0d4d333e9..7d193a40d4 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -74,6 +74,7 @@ LIBWIRESHARK_SRC = \ packet.c \ prefs.c \ print.c \ + print_stream.c \ proto.c \ range.c \ reassemble.c \ @@ -226,6 +227,7 @@ LIBWIRESHARK_INCLUDES = \ params.h \ ppptypes.h \ print.h \ + print_stream.h \ prefs.h \ prefs-int.h \ proto.h \ diff --git a/epan/print.c b/epan/print.c index 4336c6ad00..b0e0f0c7be 100644 --- a/epan/print.c +++ b/epan/print.c @@ -40,10 +40,8 @@ #include #include -#include "print.h" -#include "ps.h" +#include #include "version_info.h" -#include #include #include #include @@ -98,40 +96,12 @@ static const guint8 *get_field_data(GSList *src_list, field_info *fi); static void write_pdml_field_hex_value(write_pdml_data *pdata, field_info *fi); static gboolean print_hex_data_buffer(print_stream_t *stream, const guchar *cp, guint length, packet_char_enc encoding); -static void ps_clean_string(char *out, const char *in, - int outbuf_size); static void print_escaped_xml(FILE *fh, const char *unescaped_string); static void print_pdml_geninfo(proto_tree *tree, FILE *fh); static void proto_tree_get_node_field_values(proto_node *node, gpointer data); -static FILE * -open_print_dest(gboolean to_file, const char *dest) -{ - FILE *fh; - - /* Open the file or command for output */ - if (to_file) - fh = ws_fopen(dest, "w"); - else - fh = popen(dest, "w"); - - return fh; -} - -static gboolean -close_print_dest(gboolean to_file, FILE *fh) -{ - /* Close the file or command */ - if (to_file) - return (fclose(fh) == 0); - else - return (pclose(fh) == 0); -} - -#define MAX_PS_LINE_LENGTH 256 - gboolean proto_tree_print(print_args_t *print_args, epan_dissect_t *edt, print_stream_t *stream) @@ -154,8 +124,6 @@ proto_tree_print(print_args_t *print_args, epan_dissect_t *edt, return data.success; } -#define MAX_INDENT 160 - /* Print a tree's data, and any child nodes. */ static void proto_tree_print_node(proto_node *node, gpointer data) @@ -1049,325 +1017,6 @@ print_hex_data_buffer(print_stream_t *stream, const guchar *cp, return TRUE; } -static -void ps_clean_string(char *out, const char *in, int outbuf_size) -{ - int rd, wr; - char c; - - if (in == NULL) { - out[0] = '\0'; - return; - } - - for (rd = 0, wr = 0 ; wr < outbuf_size; rd++, wr++ ) { - c = in[rd]; - switch (c) { - case '(': - case ')': - case '\\': - out[wr] = '\\'; - out[++wr] = c; - break; - - default: - out[wr] = c; - break; - } - - if (c == 0) { - break; - } - } -} - -/* Some formats need stuff at the beginning of the output */ -gboolean -print_preamble(print_stream_t *self, gchar *filename, const char *version_string) -{ - return self->ops->print_preamble ? (self->ops->print_preamble)(self, filename, version_string) : TRUE; -} - -gboolean -print_line(print_stream_t *self, int indent, const char *line) -{ - return (self->ops->print_line)(self, indent, line); -} - -/* Insert bookmark */ -gboolean -print_bookmark(print_stream_t *self, const gchar *name, const gchar *title) -{ - return self->ops->print_bookmark ? (self->ops->print_bookmark)(self, name, title) : TRUE; -} - -gboolean -new_page(print_stream_t *self) -{ - return self->ops->new_page ? (self->ops->new_page)(self) : TRUE; -} - -/* Some formats need stuff at the end of the output */ -gboolean -print_finale(print_stream_t *self) -{ - return self->ops->print_finale ? (self->ops->print_finale)(self) : TRUE; -} - -gboolean -destroy_print_stream(print_stream_t *self) -{ - return self->ops->destroy ? (self->ops->destroy)(self) : TRUE; -} - -typedef struct { - gboolean to_file; - FILE *fh; -} output_text; - -static gboolean -print_line_text(print_stream_t *self, int indent, const char *line) -{ - static char spaces[MAX_INDENT]; - size_t ret; - - output_text *output = (output_text *)self->data; - unsigned int num_spaces; - - /* should be space, if NUL -> initialize */ - if (!spaces[0]) { - int i; - - for (i = 0; i < MAX_INDENT; i++) - spaces[i] = ' '; - } - - /* Prepare the tabs for printing, depending on tree level */ - num_spaces = indent * 4; - if (num_spaces > MAX_INDENT) - num_spaces = MAX_INDENT; - - ret = fwrite(spaces, 1, num_spaces, output->fh); - if (ret == num_spaces) { - fputs(line, output->fh); - putc('\n', output->fh); - } - return !ferror(output->fh); -} - -static gboolean -new_page_text(print_stream_t *self) -{ - output_text *output = (output_text *)self->data; - - fputs("\f", output->fh); - return !ferror(output->fh); -} - -static gboolean -destroy_text(print_stream_t *self) -{ - output_text *output = (output_text *)self->data; - gboolean ret; - - ret = close_print_dest(output->to_file, output->fh); - g_free(output); - g_free(self); - return ret; -} - -static const print_stream_ops_t print_text_ops = { - NULL, /* preamble */ - print_line_text, - NULL, /* bookmark */ - new_page_text, - NULL, /* finale */ - destroy_text -}; - -static print_stream_t * -print_stream_text_alloc(gboolean to_file, FILE *fh) -{ - print_stream_t *stream; - output_text *output; - - output = (output_text *)g_malloc(sizeof *output); - output->to_file = to_file; - output->fh = fh; - stream = (print_stream_t *)g_malloc(sizeof (print_stream_t)); - stream->ops = &print_text_ops; - stream->data = output; - - return stream; -} - -print_stream_t * -print_stream_text_new(gboolean to_file, const char *dest) -{ - FILE *fh; - - fh = open_print_dest(to_file, dest); - if (fh == NULL) - return NULL; - - return print_stream_text_alloc(to_file, fh); -} - -print_stream_t * -print_stream_text_stdio_new(FILE *fh) -{ - return print_stream_text_alloc(TRUE, fh); -} - -typedef struct { - gboolean to_file; - FILE *fh; -} output_ps; - -static gboolean -print_preamble_ps(print_stream_t *self, gchar *filename, const char *version_string) -{ - output_ps *output = (output_ps *)self->data; - char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ - - print_ps_preamble(output->fh); - - fputs("%% the page title\n", output->fh); - ps_clean_string(psbuffer, filename, MAX_PS_LINE_LENGTH); - fprintf(output->fh, "/ws_pagetitle (%s - Wireshark %s) def\n", psbuffer, version_string); - fputs("\n", output->fh); - return !ferror(output->fh); -} - -static gboolean -print_line_ps(print_stream_t *self, int indent, const char *line) -{ - output_ps *output = (output_ps *)self->data; - char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ - - ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH); - fprintf(output->fh, "%d (%s) putline\n", indent, psbuffer); - return !ferror(output->fh); -} - -static gboolean -print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title) -{ - output_ps *output = (output_ps *)self->data; - char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ - - /* - * See the Adobe "pdfmark reference": - * - * http://partners.adobe.com/asn/acrobat/docs/pdfmark.pdf - * - * The pdfmark stuff tells code that turns PostScript into PDF - * things that it should do. - * - * The /OUT stuff creates a bookmark that goes to the - * destination with "name" as the name and "title" as the title. - * - * The "/DEST" creates the destination. - */ - ps_clean_string(psbuffer, title, MAX_PS_LINE_LENGTH); - fprintf(output->fh, "[/Dest /%s /Title (%s) /OUT pdfmark\n", name, - psbuffer); - fputs("[/View [/XYZ -4 currentpoint matrix currentmatrix matrix defaultmatrix\n", - output->fh); - fputs("matrix invertmatrix matrix concatmatrix transform exch pop 20 add null]\n", - output->fh); - fprintf(output->fh, "/Dest /%s /DEST pdfmark\n", name); - return !ferror(output->fh); -} - -static gboolean -new_page_ps(print_stream_t *self) -{ - output_ps *output = (output_ps *)self->data; - - fputs("formfeed\n", output->fh); - return !ferror(output->fh); -} - -static gboolean -print_finale_ps(print_stream_t *self) -{ - output_ps *output = (output_ps *)self->data; - - print_ps_finale(output->fh); - return !ferror(output->fh); -} - -static gboolean -destroy_ps(print_stream_t *self) -{ - output_ps *output = (output_ps *)self->data; - gboolean ret; - - ret = close_print_dest(output->to_file, output->fh); - g_free(output); - g_free(self); - return ret; -} - -static const print_stream_ops_t print_ps_ops = { - print_preamble_ps, - print_line_ps, - print_bookmark_ps, - new_page_ps, - print_finale_ps, - destroy_ps -}; - -static print_stream_t * -print_stream_ps_alloc(gboolean to_file, FILE *fh) -{ - print_stream_t *stream; - output_ps *output; - - output = (output_ps *)g_malloc(sizeof *output); - output->to_file = to_file; - output->fh = fh; - stream = (print_stream_t *)g_malloc(sizeof (print_stream_t)); - stream->ops = &print_ps_ops; - stream->data = output; - - return stream; -} - -print_stream_t * -print_stream_ps_new(gboolean to_file, const char *dest) -{ - FILE *fh; - - fh = open_print_dest(to_file, dest); - if (fh == NULL) - return NULL; - - return print_stream_ps_alloc(to_file, fh); -} - -print_stream_t * -print_stream_ps_stdio_new(FILE *fh) -{ - return print_stream_ps_alloc(TRUE, fh); -} - -output_fields_t* output_fields_new(void) -{ - output_fields_t* fields = g_new(output_fields_t, 1); - fields->print_header = FALSE; - fields->separator = '\t'; - fields->occurrence = 'a'; - fields->aggregator = ','; - fields->fields = NULL; /*Do lazy initialisation */ - fields->field_indicies = NULL; - fields->field_values = NULL; - fields->quote ='\0'; - fields->includes_col_fields = FALSE; - return fields; -} - gsize output_fields_num_fields(output_fields_t* fields) { g_assert(fields); @@ -1851,6 +1500,21 @@ get_field_hex_value(GSList *src_list, field_info *fi) } } +output_fields_t* output_fields_new(void) +{ + output_fields_t* fields = g_new(output_fields_t, 1); + fields->print_header = FALSE; + fields->separator = '\t'; + fields->occurrence = 'a'; + fields->aggregator = ','; + fields->fields = NULL; /*Do lazy initialisation */ + fields->field_indicies = NULL; + fields->field_values = NULL; + fields->quote ='\0'; + fields->includes_col_fields = FALSE; + return fields; +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/epan/print.h b/epan/print.h index 9832d575a4..816c401660 100644 --- a/epan/print.h +++ b/epan/print.h @@ -30,47 +30,16 @@ #include #include +#include + #include +#include "ws_symbol_export.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -/* - * Print stream code; this provides a "print stream" class with subclasses - * of various sorts. Additional subclasses might be implemented elsewhere. - */ -struct print_stream; - -typedef struct print_stream_ops { - gboolean (*print_preamble)(struct print_stream *self, gchar *filename, const char *version_string); - gboolean (*print_line)(struct print_stream *self, int indent, - const char *line); - gboolean (*print_bookmark)(struct print_stream *self, - const gchar *name, const gchar *title); - gboolean (*new_page)(struct print_stream *self); - gboolean (*print_finale)(struct print_stream *self); - gboolean (*destroy)(struct print_stream *self); -} print_stream_ops_t; - -typedef struct print_stream { - const print_stream_ops_t *ops; - void *data; -} print_stream_t; - -WS_DLL_PUBLIC print_stream_t *print_stream_text_new(gboolean to_file, const char *dest); -WS_DLL_PUBLIC print_stream_t *print_stream_text_stdio_new(FILE *fh); -WS_DLL_PUBLIC print_stream_t *print_stream_ps_new(gboolean to_file, const char *dest); -WS_DLL_PUBLIC print_stream_t *print_stream_ps_stdio_new(FILE *fh); - -WS_DLL_PUBLIC gboolean print_preamble(print_stream_t *self, gchar *filename, const char *version_string); -WS_DLL_PUBLIC gboolean print_line(print_stream_t *self, int indent, const char *line); -WS_DLL_PUBLIC gboolean print_bookmark(print_stream_t *self, const gchar *name, - const gchar *title); -WS_DLL_PUBLIC gboolean new_page(print_stream_t *self); -WS_DLL_PUBLIC gboolean print_finale(print_stream_t *self); -WS_DLL_PUBLIC gboolean destroy_print_stream(print_stream_t *self); - /* print output format */ typedef enum { PR_FMT_TEXT, /* plain text */ diff --git a/epan/print_stream.c b/epan/print_stream.c new file mode 100644 index 0000000000..5f93072c98 --- /dev/null +++ b/epan/print_stream.c @@ -0,0 +1,367 @@ +/* print.c + * Routines for printing packet analysis trees. + * + * Gilbert Ramirez + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include + +#include + +#include + +#include + +#include + +static FILE * +open_print_dest(gboolean to_file, const char *dest) +{ + FILE *fh; + + /* Open the file or command for output */ + if (to_file) + fh = ws_fopen(dest, "w"); + else + fh = popen(dest, "w"); + + return fh; +} + +static gboolean +close_print_dest(gboolean to_file, FILE *fh) +{ + /* Close the file or command */ + if (to_file) + return (fclose(fh) == 0); + else + return (pclose(fh) == 0); +} + +/* Some formats need stuff at the beginning of the output */ +gboolean +print_preamble(print_stream_t *self, gchar *filename, const char *version_string) +{ + return self->ops->print_preamble ? (self->ops->print_preamble)(self, filename, version_string) : TRUE; +} + +gboolean +print_line(print_stream_t *self, int indent, const char *line) +{ + return (self->ops->print_line)(self, indent, line); +} + +/* Insert bookmark */ +gboolean +print_bookmark(print_stream_t *self, const gchar *name, const gchar *title) +{ + return self->ops->print_bookmark ? (self->ops->print_bookmark)(self, name, title) : TRUE; +} + +gboolean +new_page(print_stream_t *self) +{ + return self->ops->new_page ? (self->ops->new_page)(self) : TRUE; +} + +/* Some formats need stuff at the end of the output */ +gboolean +print_finale(print_stream_t *self) +{ + return self->ops->print_finale ? (self->ops->print_finale)(self) : TRUE; +} + +gboolean +destroy_print_stream(print_stream_t *self) +{ + return self->ops->destroy ? (self->ops->destroy)(self) : TRUE; +} + +typedef struct { + gboolean to_file; + FILE *fh; +} output_text; + +#define MAX_INDENT 160 + +static gboolean +print_line_text(print_stream_t *self, int indent, const char *line) +{ + static char spaces[MAX_INDENT]; + size_t ret; + + output_text *output = (output_text *)self->data; + unsigned int num_spaces; + + /* should be space, if NUL -> initialize */ + if (!spaces[0]) { + int i; + + for (i = 0; i < MAX_INDENT; i++) + spaces[i] = ' '; + } + + /* Prepare the tabs for printing, depending on tree level */ + num_spaces = indent * 4; + if (num_spaces > MAX_INDENT) + num_spaces = MAX_INDENT; + + ret = fwrite(spaces, 1, num_spaces, output->fh); + if (ret == num_spaces) { + fputs(line, output->fh); + putc('\n', output->fh); + } + return !ferror(output->fh); +} + +static gboolean +new_page_text(print_stream_t *self) +{ + output_text *output = (output_text *)self->data; + + fputs("\f", output->fh); + return !ferror(output->fh); +} + +static gboolean +destroy_text(print_stream_t *self) +{ + output_text *output = (output_text *)self->data; + gboolean ret; + + ret = close_print_dest(output->to_file, output->fh); + g_free(output); + g_free(self); + return ret; +} + +static const print_stream_ops_t print_text_ops = { + NULL, /* preamble */ + print_line_text, + NULL, /* bookmark */ + new_page_text, + NULL, /* finale */ + destroy_text +}; + +static print_stream_t * +print_stream_text_alloc(gboolean to_file, FILE *fh) +{ + print_stream_t *stream; + output_text *output; + + output = (output_text *)g_malloc(sizeof *output); + output->to_file = to_file; + output->fh = fh; + stream = (print_stream_t *)g_malloc(sizeof (print_stream_t)); + stream->ops = &print_text_ops; + stream->data = output; + + return stream; +} + +print_stream_t * +print_stream_text_new(gboolean to_file, const char *dest) +{ + FILE *fh; + + fh = open_print_dest(to_file, dest); + if (fh == NULL) + return NULL; + + return print_stream_text_alloc(to_file, fh); +} + +print_stream_t * +print_stream_text_stdio_new(FILE *fh) +{ + return print_stream_text_alloc(TRUE, fh); +} + +typedef struct { + gboolean to_file; + FILE *fh; +} output_ps; + +#define MAX_PS_LINE_LENGTH 256 + +static +void ps_clean_string(char *out, const char *in, int outbuf_size) +{ + int rd, wr; + char c; + + if (in == NULL) { + out[0] = '\0'; + return; + } + + for (rd = 0, wr = 0 ; wr < outbuf_size; rd++, wr++ ) { + c = in[rd]; + switch (c) { + case '(': + case ')': + case '\\': + out[wr] = '\\'; + out[++wr] = c; + break; + + default: + out[wr] = c; + break; + } + + if (c == 0) { + break; + } + } +} + +static gboolean +print_preamble_ps(print_stream_t *self, gchar *filename, const char *version_string) +{ + output_ps *output = (output_ps *)self->data; + char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ + + print_ps_preamble(output->fh); + + fputs("%% the page title\n", output->fh); + ps_clean_string(psbuffer, filename, MAX_PS_LINE_LENGTH); + fprintf(output->fh, "/ws_pagetitle (%s - Wireshark %s) def\n", psbuffer, version_string); + fputs("\n", output->fh); + return !ferror(output->fh); +} + +static gboolean +print_line_ps(print_stream_t *self, int indent, const char *line) +{ + output_ps *output = (output_ps *)self->data; + char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ + + ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH); + fprintf(output->fh, "%d (%s) putline\n", indent, psbuffer); + return !ferror(output->fh); +} + +static gboolean +print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title) +{ + output_ps *output = (output_ps *)self->data; + char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */ + + /* + * See the Adobe "pdfmark reference": + * + * http://partners.adobe.com/asn/acrobat/docs/pdfmark.pdf + * + * The pdfmark stuff tells code that turns PostScript into PDF + * things that it should do. + * + * The /OUT stuff creates a bookmark that goes to the + * destination with "name" as the name and "title" as the title. + * + * The "/DEST" creates the destination. + */ + ps_clean_string(psbuffer, title, MAX_PS_LINE_LENGTH); + fprintf(output->fh, "[/Dest /%s /Title (%s) /OUT pdfmark\n", name, + psbuffer); + fputs("[/View [/XYZ -4 currentpoint matrix currentmatrix matrix defaultmatrix\n", + output->fh); + fputs("matrix invertmatrix matrix concatmatrix transform exch pop 20 add null]\n", + output->fh); + fprintf(output->fh, "/Dest /%s /DEST pdfmark\n", name); + return !ferror(output->fh); +} + +static gboolean +new_page_ps(print_stream_t *self) +{ + output_ps *output = (output_ps *)self->data; + + fputs("formfeed\n", output->fh); + return !ferror(output->fh); +} + +static gboolean +print_finale_ps(print_stream_t *self) +{ + output_ps *output = (output_ps *)self->data; + + print_ps_finale(output->fh); + return !ferror(output->fh); +} + +static gboolean +destroy_ps(print_stream_t *self) +{ + output_ps *output = (output_ps *)self->data; + gboolean ret; + + ret = close_print_dest(output->to_file, output->fh); + g_free(output); + g_free(self); + return ret; +} + +static const print_stream_ops_t print_ps_ops = { + print_preamble_ps, + print_line_ps, + print_bookmark_ps, + new_page_ps, + print_finale_ps, + destroy_ps +}; + +static print_stream_t * +print_stream_ps_alloc(gboolean to_file, FILE *fh) +{ + print_stream_t *stream; + output_ps *output; + + output = (output_ps *)g_malloc(sizeof *output); + output->to_file = to_file; + output->fh = fh; + stream = (print_stream_t *)g_malloc(sizeof (print_stream_t)); + stream->ops = &print_ps_ops; + stream->data = output; + + return stream; +} + +print_stream_t * +print_stream_ps_new(gboolean to_file, const char *dest) +{ + FILE *fh; + + fh = open_print_dest(to_file, dest); + if (fh == NULL) + return NULL; + + return print_stream_ps_alloc(to_file, fh); +} + +print_stream_t * +print_stream_ps_stdio_new(FILE *fh) +{ + return print_stream_ps_alloc(TRUE, fh); +} diff --git a/epan/print_stream.h b/epan/print_stream.h new file mode 100644 index 0000000000..3a326c45e8 --- /dev/null +++ b/epan/print_stream.h @@ -0,0 +1,73 @@ +/* print.h + * Definitions for printing packet analysis trees. + * + * Gilbert Ramirez + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __PRINT_STREAM_H__ +#define __PRINT_STREAM_H__ + +#include "ws_symbol_export.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Print stream code; this provides a "print stream" class with subclasses + * of various sorts. Additional subclasses might be implemented elsewhere. + */ +struct print_stream; + +typedef struct print_stream_ops { + gboolean (*print_preamble)(struct print_stream *self, gchar *filename, const char *version_string); + gboolean (*print_line)(struct print_stream *self, int indent, + const char *line); + gboolean (*print_bookmark)(struct print_stream *self, + const gchar *name, const gchar *title); + gboolean (*new_page)(struct print_stream *self); + gboolean (*print_finale)(struct print_stream *self); + gboolean (*destroy)(struct print_stream *self); +} print_stream_ops_t; + +typedef struct print_stream { + const print_stream_ops_t *ops; + void *data; +} print_stream_t; + +WS_DLL_PUBLIC print_stream_t *print_stream_text_new(gboolean to_file, const char *dest); +WS_DLL_PUBLIC print_stream_t *print_stream_text_stdio_new(FILE *fh); +WS_DLL_PUBLIC print_stream_t *print_stream_ps_new(gboolean to_file, const char *dest); +WS_DLL_PUBLIC print_stream_t *print_stream_ps_stdio_new(FILE *fh); + +WS_DLL_PUBLIC gboolean print_preamble(print_stream_t *self, gchar *filename, const char *version_string); +WS_DLL_PUBLIC gboolean print_line(print_stream_t *self, int indent, const char *line); +WS_DLL_PUBLIC gboolean print_bookmark(print_stream_t *self, const gchar *name, + const gchar *title); +WS_DLL_PUBLIC gboolean new_page(print_stream_t *self); +WS_DLL_PUBLIC gboolean print_finale(print_stream_t *self); +WS_DLL_PUBLIC gboolean destroy_print_stream(print_stream_t *self); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* print_stream.h */ -- 2.34.1