mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-16 16:25:54 +01:00
328 lines
7.1 KiB
C
328 lines
7.1 KiB
C
/*
|
||
* The contents of this file are subject to the Interbase Public
|
||
* License Version 1.0 (the "License"); you may not use this file
|
||
* except in compliance with the License. You may obtain a copy
|
||
* of the License at http://www.Inprise.com/IPL.html
|
||
*
|
||
* Software distributed under the License is distributed on an
|
||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||
* or implied. See the License for the specific language governing
|
||
* rights and limitations under the License.
|
||
*
|
||
* The Original Code was created by Inprise Corporation
|
||
* and its predecessors. Portions created by Inprise Corporation are
|
||
* Copyright (C) Inprise Corporation.
|
||
*
|
||
* All Rights Reserved.
|
||
* Contributor(s): ______________________________________.
|
||
*/
|
||
|
||
#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 (char*, ISC_BLOB_CTL);
|
||
static int read_text (SHORT, ISC_BLOB_CTL);
|
||
static int dump_text (SHORT, ISC_BLOB_CTL);
|
||
static int caller (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 FB_SUCCESS 0
|
||
#define FB_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 (SHORT action, 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 FB_SUCCESS;
|
||
}
|
||
|
||
static int caller (SHORT action, ISC_BLOB_CTL control, SHORT buffer_length,
|
||
CHAR *buffer, 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 (SHORT action, 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 FB_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 FB_SUCCESS;
|
||
}
|
||
|
||
static void set_statistics (char* filename, 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.
|
||
*
|
||
*************************************/
|
||
int max_seg_length;
|
||
int length;
|
||
int num_segs;
|
||
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 (SHORT action, 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 FB_SUCCESS;
|
||
else
|
||
return isc_segment;
|
||
}
|
||
}
|
||
|
||
return isc_segstr_eof;
|
||
}
|
||
|