2 * Routines for print streams.
4 * Gilbert Ramirez <gram@alumni.rice.edu>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/print_stream.h>
35 #include <wsutil/file_util.h>
38 open_print_dest(gboolean to_file, const char *dest)
42 /* Open the file or command for output */
44 fh = ws_fopen(dest, "w");
46 fh = popen(dest, "w");
52 close_print_dest(gboolean to_file, FILE *fh)
54 /* Close the file or command */
56 return (fclose(fh) == 0);
58 return (pclose(fh) == 0);
61 /* Some formats need stuff at the beginning of the output */
63 print_preamble(print_stream_t *self, gchar *filename, const char *version_string)
65 return self->ops->print_preamble ? (self->ops->print_preamble)(self, filename, version_string) : TRUE;
69 print_line(print_stream_t *self, int indent, const char *line)
71 return (self->ops->print_line)(self, indent, line);
76 print_bookmark(print_stream_t *self, const gchar *name, const gchar *title)
78 return self->ops->print_bookmark ? (self->ops->print_bookmark)(self, name, title) : TRUE;
82 new_page(print_stream_t *self)
84 return self->ops->new_page ? (self->ops->new_page)(self) : TRUE;
87 /* Some formats need stuff at the end of the output */
89 print_finale(print_stream_t *self)
91 return self->ops->print_finale ? (self->ops->print_finale)(self) : TRUE;
95 destroy_print_stream(print_stream_t *self)
97 return self->ops->destroy ? (self->ops->destroy)(self) : TRUE;
105 #define MAX_INDENT 160
108 print_line_text(print_stream_t *self, int indent, const char *line)
110 static char spaces[MAX_INDENT];
113 output_text *output = (output_text *)self->data;
114 unsigned int num_spaces;
116 /* should be space, if NUL -> initialize */
120 for (i = 0; i < MAX_INDENT; i++)
124 /* Prepare the tabs for printing, depending on tree level */
125 num_spaces = indent * 4;
126 if (num_spaces > MAX_INDENT)
127 num_spaces = MAX_INDENT;
129 ret = fwrite(spaces, 1, num_spaces, output->fh);
130 if (ret == num_spaces) {
131 fputs(line, output->fh);
132 putc('\n', output->fh);
134 return !ferror(output->fh);
138 new_page_text(print_stream_t *self)
140 output_text *output = (output_text *)self->data;
142 fputs("\f", output->fh);
143 return !ferror(output->fh);
147 destroy_text(print_stream_t *self)
149 output_text *output = (output_text *)self->data;
152 ret = close_print_dest(output->to_file, output->fh);
158 static const print_stream_ops_t print_text_ops = {
167 static print_stream_t *
168 print_stream_text_alloc(gboolean to_file, FILE *fh)
170 print_stream_t *stream;
173 output = (output_text *)g_malloc(sizeof *output);
174 output->to_file = to_file;
176 stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
177 stream->ops = &print_text_ops;
178 stream->data = output;
184 print_stream_text_new(gboolean to_file, const char *dest)
188 fh = open_print_dest(to_file, dest);
192 return print_stream_text_alloc(to_file, fh);
196 print_stream_text_stdio_new(FILE *fh)
198 return print_stream_text_alloc(TRUE, fh);
206 #define MAX_PS_LINE_LENGTH 256
209 void ps_clean_string(char *out, const char *in, int outbuf_size)
219 for (rd = 0, wr = 0 ; wr < outbuf_size; rd++, wr++ ) {
241 print_preamble_ps(print_stream_t *self, gchar *filename, const char *version_string)
243 output_ps *output = (output_ps *)self->data;
244 char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
246 print_ps_preamble(output->fh);
248 fputs("%% the page title\n", output->fh);
249 ps_clean_string(psbuffer, filename, MAX_PS_LINE_LENGTH);
250 fprintf(output->fh, "/ws_pagetitle (%s - Wireshark %s) def\n", psbuffer, version_string);
251 fputs("\n", output->fh);
252 return !ferror(output->fh);
256 print_line_ps(print_stream_t *self, int indent, const char *line)
258 output_ps *output = (output_ps *)self->data;
259 char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
261 ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH);
262 fprintf(output->fh, "%d (%s) putline\n", indent, psbuffer);
263 return !ferror(output->fh);
267 print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title)
269 output_ps *output = (output_ps *)self->data;
270 char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
273 * See the Adobe "pdfmark reference":
275 * http://partners.adobe.com/asn/acrobat/docs/pdfmark.pdf
277 * The pdfmark stuff tells code that turns PostScript into PDF
278 * things that it should do.
280 * The /OUT stuff creates a bookmark that goes to the
281 * destination with "name" as the name and "title" as the title.
283 * The "/DEST" creates the destination.
285 ps_clean_string(psbuffer, title, MAX_PS_LINE_LENGTH);
286 fprintf(output->fh, "[/Dest /%s /Title (%s) /OUT pdfmark\n", name,
288 fputs("[/View [/XYZ -4 currentpoint matrix currentmatrix matrix defaultmatrix\n",
290 fputs("matrix invertmatrix matrix concatmatrix transform exch pop 20 add null]\n",
292 fprintf(output->fh, "/Dest /%s /DEST pdfmark\n", name);
293 return !ferror(output->fh);
297 new_page_ps(print_stream_t *self)
299 output_ps *output = (output_ps *)self->data;
301 fputs("formfeed\n", output->fh);
302 return !ferror(output->fh);
306 print_finale_ps(print_stream_t *self)
308 output_ps *output = (output_ps *)self->data;
310 print_ps_finale(output->fh);
311 return !ferror(output->fh);
315 destroy_ps(print_stream_t *self)
317 output_ps *output = (output_ps *)self->data;
320 ret = close_print_dest(output->to_file, output->fh);
326 static const print_stream_ops_t print_ps_ops = {
335 static print_stream_t *
336 print_stream_ps_alloc(gboolean to_file, FILE *fh)
338 print_stream_t *stream;
341 output = (output_ps *)g_malloc(sizeof *output);
342 output->to_file = to_file;
344 stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
345 stream->ops = &print_ps_ops;
346 stream->data = output;
352 print_stream_ps_new(gboolean to_file, const char *dest)
356 fh = open_print_dest(to_file, dest);
360 return print_stream_ps_alloc(to_file, fh);
364 print_stream_ps_stdio_new(FILE *fh)
366 return print_stream_ps_alloc(TRUE, fh);
370 * Editor modelines - http://www.wireshark.org/tools/modelines.html
375 * indent-tabs-mode: nil
378 * vi: set shiftwidth=4 tabstop=8 expandtab:
379 * :indentSize=4:tabSize=8:noTabs=true: