summaryrefslogtreecommitdiff
path: root/gs/base/strimpl.h
diff options
context:
space:
mode:
authorRalph Giles <ralph.giles@artifex.com>2008-08-29 18:46:21 +0000
committerRalph Giles <ralph.giles@artifex.com>2008-08-29 18:46:21 +0000
commit6ff2582d038f99b79178082b200bdfe73f734456 (patch)
tree6db04fc72813760fdc6912a15875ad83d57943df /gs/base/strimpl.h
parent9d36ee856e41244d3cf0469fc0004d21e6911994 (diff)
downloadghostpdl-6ff2582d038f99b79178082b200bdfe73f734456.tar.gz
Split the source tree into two new directories.
PSSRC files are now in 'gs/psi'. GLSRC files are now in 'gs/base'. This is to facilitate build modularization and merging in the ghostpdl tree. NOTE: msvc32.mak is now in psi, not src. git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9048 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/base/strimpl.h')
-rw-r--r--gs/base/strimpl.h163
1 files changed, 163 insertions, 0 deletions
diff --git a/gs/base/strimpl.h b/gs/base/strimpl.h
new file mode 100644
index 000000000..981eecd57
--- /dev/null
+++ b/gs/base/strimpl.h
@@ -0,0 +1,163 @@
+/* Copyright (C) 2001-2006 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* Definitions for stream implementors */
+/* Requires stdio.h */
+
+#ifndef strimpl_INCLUDED
+# define strimpl_INCLUDED
+
+#include "scommon.h"
+#include "gstypes.h" /* for gsstruct.h */
+#include "gsstruct.h"
+
+/*
+ * The 'process' procedure does the real work of the stream.
+ * It must process as much input information (from pr->ptr + 1 through
+ * pr->limit) as it can, subject to space available for output
+ * (pw->ptr + 1 through pw->limit), updating pr->ptr and pw->ptr.
+ *
+ * The procedure return value must be one of:
+ * EOFC - an end-of-data pattern was detected in the input,
+ * or no more input can be processed for some other reason (e.g.,
+ * the stream was told only to read a certain amount of data).
+ * ERRC - a syntactic error was detected in the input.
+ * 0 - more input data is needed.
+ * 1 - more output space is needed.
+ * If the procedure returns EOFC, it can assume it will never be called
+ * again for that stream.
+ *
+ * If the procedure is called with last = 1, this is an indication that
+ * no more input will ever be supplied (after the input in the current
+ * buffer defined by *pr); the procedure should produce as much output
+ * as possible, including an end-of-data marker if applicable. In this
+ * case:
+ * - If the procedure returns 1, it may be called again (also with
+ * last = 1).
+ * - If the procedure returns any other value other than 1, the
+ * procedure will never be called again for that stream.
+ * - If the procedure returns 0, this is taken as equivalent to
+ * returning EOFC.
+ * - If the procedure returns EOFC (or 0), the stream's end_status
+ * is set to EOFC, meaning no more writing is allowed.
+ *
+ * Note that these specifications do not distinguish input from output
+ * streams. This is deliberate: The processing procedures should work
+ * regardless of which way they are oriented in a stream pipeline.
+ * (The PostScript language does take a position as whether any given
+ * filter may be used for input or output, but this occurs at a higher level.)
+ *
+ * The value returned by the process procedure of a stream whose data source
+ * or sink is external (i.e., not another stream) is interpreted slightly
+ * differently. For an external data source, a return value of 0 means
+ * "no more input data are available now, but more might become available
+ * later." For an external data sink, a return value of 1 means "there is
+ * no more room for output data now, but there might be room later."
+ *
+ * It appears that the Adobe specifications, read correctly, require that when
+ * the process procedure of a decoding filter has filled up the output
+ * buffer, it must still peek ahead in the input to determine whether or not
+ * the next thing in the input stream is EOD. If the next thing is an EOD (or
+ * end-of-data, indicated by running out of input data with last = true), the
+ * process procedure must return EOFC; if the next thing is definitely not
+ * an EOD, the process procedure must return 1 (output full) (without, of
+ * course, consuming the non-EOD datum); if the procedure cannot determine
+ * whether or not the next thing is an EOD, it must return 0 (need more input).
+ * Decoding filters that don't have EOD (for example, NullDecode) can use
+ * a simpler algorithm: if the output buffer is full, then if there is more
+ * input, return 1, otherwise return 0 (which is taken as EOFC if last
+ * is true). All this may seem a little awkward, but it is needed in order
+ * to have consistent behavior regardless of where buffer boundaries fall --
+ * in particular, if a buffer boundary falls just before an EOD. It is
+ * actually quite easy to implement if the main loop of the process
+ * procedure tests for running out of input rather than for filling the
+ * output: with this structure, exhausting the input always returns 0,
+ * and discovering that the output buffer is full when attempting to store
+ * more output always returns 1.
+ *
+ * Even this algorithm for handling end-of-buffer is not sufficient if an
+ * EOD falls just after a buffer boundary, but the generic stream code
+ * handles this case: the process procedures need only do what was just
+ * described.
+ */
+
+/*
+ * The set_defaults procedure in the template has a dual purpose: it sets
+ * default values for all parameters that the client can set before calling
+ * the init procedure, and it also must initialize all pointers in the
+ * stream state to a value that will be valid for the garbage collector
+ * (normally 0). The latter implies that:
+ *
+ * Any stream whose state includes additional pointers (beyond those
+ * in stream_state_common) must have a set_defaults procedure.
+ */
+
+/*
+ * Note that all decoding filters that require an explicit EOD in the
+ * source data must have an init procedure that sets min_left = 1.
+ * This effectively provides a 1-byte lookahead in the source data,
+ * which is required so that the stream can close itself "after reading
+ * the last byte of data" (per Adobe specification), as noted above.
+ */
+
+/*
+ * Define a template for creating a stream.
+ *
+ * The meaning of min_in_size and min_out_size is the following:
+ * If the amount of input information is at least min_in_size,
+ * and the available output space is at least min_out_size,
+ * the process procedure guarantees that it will make some progress.
+ * (It may make progress even if this condition is not met, but this is
+ * not guaranteed.)
+ */
+struct stream_template_s {
+
+ /* Define the structure type for the stream state. */
+ gs_memory_type_ptr_t stype;
+
+ /* Define an optional initialization procedure. */
+ stream_proc_init((*init));
+
+ /* Define the processing procedure. */
+ /* (The init procedure can reset other procs if it wants.) */
+ stream_proc_process((*process));
+
+ /* Define the minimum buffer sizes. */
+ uint min_in_size; /* minimum size for process input */
+ uint min_out_size; /* minimum size for process output */
+
+ /* Define an optional releasing procedure. */
+ stream_proc_release((*release));
+
+ /* Define an optional parameter defaulting and pointer initialization */
+ /* procedure. */
+ stream_proc_set_defaults((*set_defaults));
+
+ /* Define an optional reinitialization procedure. */
+ stream_proc_reinit((*reinit));
+
+};
+
+/* Utility procedures */
+int stream_move(stream_cursor_read *, stream_cursor_write *); /* in stream.c */
+
+/* Hex decoding utility procedure */
+typedef enum {
+ hex_ignore_garbage = 0,
+ hex_ignore_whitespace = 1,
+ hex_ignore_leading_whitespace = 2
+} hex_syntax;
+int s_hex_process(stream_cursor_read *, stream_cursor_write *, int *, hex_syntax); /* in sstring.c */
+
+#endif /* strimpl_INCLUDED */