home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 May / PCWorld_1999-05_cd.bin / software / Vyzkuste / inprise / INTRBASE_55 / EXAMPLES / API / API9F.C < prev    next >
C/C++ Source or Header  |  1998-10-18  |  7KB  |  322 lines

  1. #include <stdio.h>
  2. #include <ibase.h>
  3. #include "example.h"
  4.  
  5. #ifndef CHAR
  6. #define CHAR        unsigned char
  7. #endif
  8.  
  9. #ifndef SHORT
  10. #define SHORT       unsigned short
  11. #endif
  12.  
  13. static void set_statistics PROTO((char*, ISC_BLOB_CTL));
  14. static int read_text PROTO((SHORT, ISC_BLOB_CTL));
  15. static int dump_text PROTO((SHORT, ISC_BLOB_CTL));
  16. static int caller PROTO((SHORT, ISC_BLOB_CTL, SHORT, CHAR*, SHORT*));
  17.  
  18. #define    ACTION_open 0
  19. #define    ACTION_get_segment 1
  20. #define    ACTION_close 2
  21. #define    ACTION_put_segment 3
  22. #define    ACTION_create 4
  23.  
  24. #define SUCCESS            0
  25. #define FAILURE            1
  26.  
  27. #define BUFFER_LENGTH        512
  28.  
  29. #ifdef SHLIB_DEFS
  30. #define system        (*_libfun_system)
  31. #define fopen        (*_libfun_fopen)
  32. #define unlink        (*_libfun_unlink)
  33. #define fprintf        (*_libfun_fprintf)
  34. #define fclose        (*_libfun_fclose)
  35. #define fgetc        (*_libfun_fgetc)
  36.  
  37. extern int    system();
  38. extern FILE    *fopen();
  39. extern int    unlink();
  40. extern int    fprintf();
  41. extern int    fclose();
  42. extern int    fgetc();
  43. #endif
  44.  
  45. static char prevbuf[BUFFER_LENGTH + 1];
  46. static int width = 40;
  47.  
  48. int EXPORT desc_filter (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
  49. ARGLIST(SHORT action)
  50. ARGLIST(ISC_BLOB_CTL control)
  51. {
  52. /**************************************
  53.  *
  54.  *    d e s c _  f i l t e r 
  55.  *
  56.  **************************************
  57.  *
  58.  * Functional description
  59.  *    Format a blob into 40-character-wide
  60.  *  paragraphs.
  61.  *  Read the blob into a file and process
  62.  *    it on open, then read it back line by
  63.  *    line in the get_segment loop.
  64.  *
  65.  **************************************/
  66. int    status;
  67. FILE    *text_file;
  68. char    *out_buffer;
  69.  
  70. switch (action)
  71.     {
  72.     case ACTION_open:
  73.         prevbuf[0] = '\0';
  74.         if (status = dump_text (action, control))
  75.             return status;
  76.         set_statistics("desc.txt", control);  /* set up stats in ctl struct */
  77.         break;
  78.  
  79.     case ACTION_get_segment:
  80.         /* open the file first time through and save the file pointer */
  81.         if (!control->ctl_data [0])
  82.         {
  83.             text_file = fopen ("desc.txt", "r");
  84.             control->ctl_data[0] = (long) text_file;
  85.         }
  86.         if (status = read_text (action, control))
  87.             return status;
  88.         break;
  89.  
  90.     case ACTION_close:
  91.         /* don't need the temp files any more, so clean them up */
  92.         /*unlink("desc.txt");*/
  93.         break;
  94.  
  95.     case ACTION_create:
  96.     case ACTION_put_segment:
  97.         return isc_uns_ext;
  98.     }
  99.  
  100.     return SUCCESS;
  101. }
  102.  
  103. static int caller (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control),
  104.                    ARG(SHORT, buffer_length), ARG(CHAR*, buffer),
  105.                    ARG(SHORT*, return_length))
  106. ARGLIST(SHORT action)
  107. ARGLIST(ISC_BLOB_CTL control)
  108. ARGLIST(SHORT buffer_length)
  109. ARGLIST(CHAR *buffer)
  110. ARGLIST(SHORT *return_length)
  111. {
  112. /**************************************
  113.  *
  114.  *        c a l l e r
  115.  *
  116.  **************************************
  117.  *
  118.  * Functional description
  119.  *        Call next source filter.  This 
  120.  *        is a useful service routine for
  121.  *        all blob filters.
  122.  *
  123.  **************************************/
  124. int        status;
  125. ISC_BLOB_CTL        source;
  126.  
  127. source = control->ctl_source_handle;
  128. source->ctl_status = control->ctl_status;
  129. source->ctl_buffer = buffer;
  130. source->ctl_buffer_length = buffer_length;
  131.  
  132. status = (*source->ctl_source) (action, source);
  133.  
  134. if (return_length)
  135.     *return_length = source->ctl_segment_length;
  136.  
  137. return status;
  138. }
  139.  
  140.  
  141. static int dump_text (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
  142. ARGLIST(SHORT action)
  143. ARGLIST(ISC_BLOB_CTL control)
  144. {
  145. /**************************************
  146.  *
  147.  *    d u m p _ t e x t 
  148.  *
  149.  **************************************
  150.  *
  151.  * Functional description
  152.  *    Open a blob and write the
  153.  *    contents to a file
  154.  *
  155.  **************************************/
  156.     FILE    *text_file;
  157.     CHAR    buffer [BUFFER_LENGTH + 1];
  158.     SHORT    length;
  159.     int        status;
  160.     int        i, j;
  161.     CHAR    tbuf [BUFFER_LENGTH + 1];
  162.  
  163.  
  164.     if (!(text_file = fopen ("desc.txt", "w")))
  165.         return FAILURE;
  166.  
  167.     while (!(status = caller (ACTION_get_segment, control, sizeof(buffer) - 1,
  168.         buffer, &length)))
  169.     {
  170.         buffer[length] = 0; 
  171.         sprintf(tbuf, "%s%s", prevbuf, buffer);
  172.  
  173.         length = strlen(tbuf);
  174.  
  175.         /* replace any new-lines with space */
  176.         for (i = 0; i < length; i++) {
  177.             if (tbuf[i] == '\n')    
  178.                 tbuf[i] = ' '; 
  179.         } 
  180.  
  181.         i = 0;
  182.         /* break the line up into width-length pieces */
  183.         for (; i < length; i++)
  184.         {
  185.             /* save the remainder */
  186.             if (strlen(&tbuf[i]) <= 40) {
  187.                 sprintf(prevbuf, "%s ", &tbuf[i]);
  188.                 break;
  189.             }
  190.  
  191.             /* find end-of-word to break the line at */
  192.             for (j = width - 1; j >= 0; j--) {
  193.                 if (isspace(tbuf[i + j]))
  194.                     break;
  195.             }
  196.             if (j < 0)
  197.                 j = width;
  198.             fprintf (text_file, "%*.*s\n", j, j, &tbuf[i]);
  199.  
  200.             i = i + j;
  201.         }
  202.     }
  203.     /* print the remainder */
  204.     fprintf(text_file, "%s\n", prevbuf);
  205.  
  206.     fclose (text_file);
  207.  
  208.     if (status != isc_segstr_eof)
  209.         return status;
  210.  
  211.     return SUCCESS;
  212. }
  213.  
  214. static void set_statistics (ARG(char*, filename), ARG(ISC_BLOB_CTL, control))
  215. ARGLIST(char filename)
  216. ARGLIST(ISC_BLOB_CTL control)
  217. {
  218. /*************************************
  219.  *
  220.  *    s e t _ s t a t i s t i c s
  221.  *
  222.  *************************************
  223.  *
  224.  * Functional description
  225.  *    Sets up the statistical fields
  226.  *    in the passed in ctl structure.
  227.  *    These fields are:
  228.  *      ctl_max_segment - length of
  229.  *         longest seg in blob (in
  230.  *         bytes)
  231.  *      ctl_number_segments - # of
  232.  *         segments in blob
  233.  *      ctl_total_length - total length
  234.  *         of blob in bytes.
  235.  *    we should reset the
  236.  *    ctl structure, so that 
  237.  *    blob_info calls get the right
  238.  *    values.
  239.  *
  240.  *************************************/
  241. register int    max_seg_length;
  242. register int    length;
  243. register int    num_segs;
  244. register int    cur_length;
  245. FILE        *file;
  246. char        *p;
  247. char        c;
  248.  
  249. num_segs = 0;
  250. length = 0;
  251. max_seg_length = 0;
  252. cur_length = 0;
  253.  
  254. file = fopen ("desc.txt", "r");
  255.  
  256. while (1)
  257.     {
  258.     c = fgetc (file);
  259.     if (feof (file))
  260.     break;
  261.     length++;
  262.     cur_length++;
  263.  
  264.     if (c == '\n')    /* that means we are at end of seg */
  265.     {
  266.     if (cur_length > max_seg_length)
  267.         max_seg_length = cur_length;
  268.     num_segs++;
  269.     cur_length = 0;
  270.     }
  271.     }
  272.  
  273. control->ctl_max_segment = max_seg_length;
  274. control->ctl_number_segments = num_segs;
  275. control->ctl_total_length = length;
  276. }
  277.  
  278. static int read_text (ARG(SHORT, action), ARG(ISC_BLOB_CTL, control))
  279. ARGLIST(SHORT action)
  280. ARGLIST(ISC_BLOB_CTL control)
  281. {
  282. /**************************************
  283.  *
  284.  *    r e a d _ t e x t 
  285.  *
  286.  **************************************
  287.  *
  288.  * Functional description
  289.  *    Reads a file one line at a time 
  290.  *    and puts the data out as if it 
  291.  *    were coming from a blob. 
  292.  *
  293.  **************************************/
  294. CHAR    *p;
  295. FILE    *file;
  296. SHORT    length;
  297. int    c, status;
  298.  
  299.  
  300. p = control->ctl_buffer;
  301. length = control->ctl_buffer_length;
  302. file = (FILE *)control->ctl_data [0];
  303.  
  304. for (;;)
  305. {
  306.     c = fgetc (file);
  307.     if (feof (file))
  308.         break;
  309.     *p++ = c;
  310.     if ((c == '\n')  || p >= control->ctl_buffer + length)
  311.     {
  312.         control->ctl_segment_length = p - control->ctl_buffer; 
  313.         if (c == '\n')
  314.             return SUCCESS; 
  315.         else
  316.             return isc_segment;
  317.     }
  318. }
  319.  
  320. return isc_segstr_eof;
  321. }
  322.