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;
|
|||
|
}
|
|||
|
|