home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ibase.h>
- #include "example.h"
-
- #ifndef CHAR
- #define CHAR unsigned char
- #endif
-
- #ifndef SHORT
- #define SHORT unsigned short
- #endif
-
- static void set_statistics PROTO((char*, ISC_BLOB_CTL));
- static int read_text PROTO((SHORT, ISC_BLOB_CTL));
- static int dump_text PROTO((SHORT, ISC_BLOB_CTL));
- static int caller PROTO((SHORT, ISC_BLOB_CTL, SHORT, CHAR*, SHORT*));
-
- #define ACTION_open 0
- #define ACTION_get_segment 1
- #define ACTION_close 2
- #define ACTION_put_segment 3
- #define ACTION_create 4
-
- #define SUCCESS 0
- #define FAILURE 1
-
- #define BUFFER_LENGTH 512
-
- #ifdef SHLIB_DEFS
- #define system (*_libfun_system)
- #define fopen (*_libfun_fopen)
- #define unlink (*_libfun_unlink)
- #define fprintf (*_libfun_fprintf)
- #define fclose (*_libfun_fclose)
- #define fgetc (*_libfun_fgetc)
-
- extern int system();
- extern FILE *fopen();
- extern int unlink();
- extern int fprintf();
- extern int fclose();
- extern int fgetc();
- #endif
-
- static char prevbuf[BUFFER_LENGTH + 1];
- static int width = 40;
-
- int EXPORT desc_filter (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
- ARGLIST(SHORT action)
- ARGLIST(ISC_BLOB_CTL control)
- {
- /**************************************
- *
- * d e s c _ f i l t e r
- *
- **************************************
- *
- * Functional description
- * Format a blob into 40-character-wide
- * paragraphs.
- * Read the blob into a file and process
- * it on open, then read it back line by
- * line in the get_segment loop.
- *
- **************************************/
- int status;
- FILE *text_file;
- char *out_buffer;
-
- switch (action)
- {
- case ACTION_open:
- prevbuf[0] = '\0';
- if (status = dump_text (action, control))
- return status;
- set_statistics("desc.txt", control); /* set up stats in ctl struct */
- break;
-
- case ACTION_get_segment:
- /* open the file first time through and save the file pointer */
- if (!control->ctl_data [0])
- {
- text_file = fopen ("desc.txt", "r");
- control->ctl_data[0] = (long) text_file;
- }
- if (status = read_text (action, control))
- return status;
- break;
-
- case ACTION_close:
- /* don't need the temp files any more, so clean them up */
- /*unlink("desc.txt");*/
- break;
-
- case ACTION_create:
- case ACTION_put_segment:
- return isc_uns_ext;
- }
-
- return SUCCESS;
- }
-
- static int caller (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control),
- ARG(SHORT, buffer_length), ARG(CHAR*, buffer),
- ARG(SHORT*, return_length))
- ARGLIST(SHORT action)
- ARGLIST(ISC_BLOB_CTL control)
- ARGLIST(SHORT buffer_length)
- ARGLIST(CHAR *buffer)
- ARGLIST(SHORT *return_length)
- {
- /**************************************
- *
- * c a l l e r
- *
- **************************************
- *
- * Functional description
- * Call next source filter. This
- * is a useful service routine for
- * all blob filters.
- *
- **************************************/
- int status;
- ISC_BLOB_CTL source;
-
- source = control->ctl_source_handle;
- source->ctl_status = control->ctl_status;
- source->ctl_buffer = buffer;
- source->ctl_buffer_length = buffer_length;
-
- status = (*source->ctl_source) (action, source);
-
- if (return_length)
- *return_length = source->ctl_segment_length;
-
- return status;
- }
-
-
- static int dump_text (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
- ARGLIST(SHORT action)
- ARGLIST(ISC_BLOB_CTL control)
- {
- /**************************************
- *
- * d u m p _ t e x t
- *
- **************************************
- *
- * Functional description
- * Open a blob and write the
- * contents to a file
- *
- **************************************/
- FILE *text_file;
- CHAR buffer [BUFFER_LENGTH + 1];
- SHORT length;
- int status;
- int i, j;
- CHAR tbuf [BUFFER_LENGTH + 1];
-
-
- if (!(text_file = fopen ("desc.txt", "w")))
- return FAILURE;
-
- while (!(status = caller (ACTION_get_segment, control, sizeof(buffer) - 1,
- buffer, &length)))
- {
- buffer[length] = 0;
- sprintf(tbuf, "%s%s", prevbuf, buffer);
-
- length = strlen(tbuf);
-
- /* replace any new-lines with space */
- for (i = 0; i < length; i++) {
- if (tbuf[i] == '\n')
- tbuf[i] = ' ';
- }
-
- i = 0;
- /* break the line up into width-length pieces */
- for (; i < length; i++)
- {
- /* save the remainder */
- if (strlen(&tbuf[i]) <= 40) {
- sprintf(prevbuf, "%s ", &tbuf[i]);
- break;
- }
-
- /* find end-of-word to break the line at */
- for (j = width - 1; j >= 0; j--) {
- if (isspace(tbuf[i + j]))
- break;
- }
- if (j < 0)
- j = width;
- fprintf (text_file, "%*.*s\n", j, j, &tbuf[i]);
-
- i = i + j;
- }
- }
- /* print the remainder */
- fprintf(text_file, "%s\n", prevbuf);
-
- fclose (text_file);
-
- if (status != isc_segstr_eof)
- return status;
-
- return SUCCESS;
- }
-
- static void set_statistics (ARG(char*, filename), ARG(ISC_BLOB_CTL, control))
- ARGLIST(char filename)
- ARGLIST(ISC_BLOB_CTL control)
- {
- /*************************************
- *
- * s e t _ s t a t i s t i c s
- *
- *************************************
- *
- * Functional description
- * Sets up the statistical fields
- * in the passed in ctl structure.
- * These fields are:
- * ctl_max_segment - length of
- * longest seg in blob (in
- * bytes)
- * ctl_number_segments - # of
- * segments in blob
- * ctl_total_length - total length
- * of blob in bytes.
- * we should reset the
- * ctl structure, so that
- * blob_info calls get the right
- * values.
- *
- *************************************/
- register int max_seg_length;
- register int length;
- register int num_segs;
- register int cur_length;
- FILE *file;
- char *p;
- char c;
-
- num_segs = 0;
- length = 0;
- max_seg_length = 0;
- cur_length = 0;
-
- file = fopen ("desc.txt", "r");
-
- while (1)
- {
- c = fgetc (file);
- if (feof (file))
- break;
- length++;
- cur_length++;
-
- if (c == '\n') /* that means we are at end of seg */
- {
- if (cur_length > max_seg_length)
- max_seg_length = cur_length;
- num_segs++;
- cur_length = 0;
- }
- }
-
- control->ctl_max_segment = max_seg_length;
- control->ctl_number_segments = num_segs;
- control->ctl_total_length = length;
- }
-
- static int read_text (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
- ARGLIST(SHORT action)
- ARGLIST(ISC_BLOB_CTL control)
- {
- /**************************************
- *
- * r e a d _ t e x t
- *
- **************************************
- *
- * Functional description
- * Reads a file one line at a time
- * and puts the data out as if it
- * were coming from a blob.
- *
- **************************************/
- CHAR *p;
- FILE *file;
- SHORT length;
- int c, status;
-
-
- p = control->ctl_buffer;
- length = control->ctl_buffer_length;
- file = (FILE *)control->ctl_data [0];
-
- for (;;)
- {
- c = fgetc (file);
- if (feof (file))
- break;
- *p++ = c;
- if ((c == '\n') || p >= control->ctl_buffer + length)
- {
- control->ctl_segment_length = p - control->ctl_buffer;
- if (c == '\n')
- return SUCCESS;
- else
- return isc_segment;
- }
- }
-
- return isc_segstr_eof;
- }
-