"Fossies" - the Fresh Open Source Software Archive

Member "libgcgi.a-0.9.5/src/crlfstringbuf.c" (22 Jun 2002, 8116 Bytes) of package /linux/www/old/gcgi-0.9.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crlfstringbuf.c" see the Fossies "Dox" file reference documentation.

    1 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
    2 /*
    3  * GCGI Library, implementing NCSA'a Common Gateway Interface and RFC2338.
    4  * Copyright (C) 2001-2002 Julian Catchen, julian@catchen.org
    5  *
    6  * This library is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU Lesser General Public
    8  * License as published by the Free Software Foundation; either
    9  * version 2.1 of the License, or (at your option) any later version.
   10  *
   11  * This library is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14  * Lesser General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU Lesser General Public
   17  * License along with this library; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  */
   20 
   21 #include "crlfstringbuf.h"
   22 
   23 static int  readCRLFLine(FILE *stream, char **line, size_t *size, size_t linelimit, int *endofstream, int *truncated);
   24 static void fillBuffer(CRLFStringBuf *crlfsbuf, int startPos, int endPos);
   25 
   26 CRLFStringBuf *
   27 crlfsbuf_new(int bufferSize, FILE *stream, size_t linelimit, size_t buflimit)
   28 {
   29     static CRLFStringBuf *crlfsbuf;
   30     int i;
   31 
   32     if (bufferSize <= 2)
   33     return NULL;
   34     
   35     crlfsbuf         = XMALLOC(CRLFStringBuf, 1);
   36     crlfsbuf->numb   = bufferSize;
   37     crlfsbuf->stream = stream;
   38 
   39     /* Malloc the array of buffers. */
   40     crlfsbuf->buf    = XMALLOC(char *, crlfsbuf->numb);
   41 
   42     /* Initialize char pointers to NULL */
   43     for (i = 0; i < crlfsbuf->numb; i++)
   44     (crlfsbuf->buf)[i] = NULL;
   45 
   46     /* Malloc the array of buffer sizes. */
   47     crlfsbuf->size    = XMALLOC(size_t, crlfsbuf->numb);
   48 
   49     /* Initialize buffer sizes to 0. */
   50     for (i = 0; i < crlfsbuf->numb; i++)
   51     (crlfsbuf->size)[i] = 0;
   52 
   53     /* Malloc the array of buffer sizes. */
   54     crlfsbuf->length = XMALLOC(size_t, crlfsbuf->numb);
   55 
   56     /* Initialize buffer sizes to 0. */
   57     for (i = 0; i < crlfsbuf->numb; i++)
   58     (crlfsbuf->length)[i] = 0;
   59 
   60     /* Start index off at position 0. */
   61     crlfsbuf->index = 0;
   62 
   63     /* Start Number of buffers full at 0. */
   64     crlfsbuf->bufsfull = 0;
   65 
   66     /* Set the line length limit. */
   67     crlfsbuf->lineLimit = linelimit;
   68 
   69     /* Set the buffer length limit. */
   70     crlfsbuf->bufLimit = buflimit;
   71 
   72     /* Set endofstream indicator flag to 0. */
   73     crlfsbuf->endofstream = 0;
   74 
   75     /* Set the truncation flag to 0. */
   76     crlfsbuf->truncated = 0;
   77 
   78     /* Set total number of bytes read from stream to 0. */
   79     crlfsbuf->bytesread = 0;
   80 
   81     /* Fill the buffer. */
   82     fillBuffer(crlfsbuf, 0, crlfsbuf->numb);
   83     
   84     return crlfsbuf;
   85 }
   86 
   87 
   88 char *
   89 crlfsbuf_read(CRLFStringBuf *sb)
   90 {
   91     int cur;
   92 
   93     /* Reached end of stream and no buffers left.  CRLFStringBuf is empty. */
   94     if (sb->endofstream && sb->bufsfull == 0)
   95     return NULL;
   96 
   97     cur = sb->index % sb->numb;
   98     
   99     sb->index++;
  100     sb->bufsfull--;
  101 
  102     /* Make sure we have at least two buffers left or        *
  103      * crlfsbuf_peek() won't work. If the number of buffers  * 
  104      * is 2 and we haven't reached the end of the stream,    * 
  105      * then fill the buffer back up.                         */
  106     if (sb->bufsfull <= 1 && !sb->endofstream) {
  107     fillBuffer(sb, sb->index + 1, sb->numb - 1);
  108     }
  109 
  110     //fprintf(stderr, "Reading CRLF String: %s", sb->buf[cur]);
  111 
  112     return (sb->buf)[cur];
  113 }
  114 
  115 
  116 size_t
  117 crlfsbuf_readdata(CRLFStringBuf *sb, char **buffer, size_t *size, size_t *length)
  118 {
  119     int cur;
  120 
  121     /* Reached end of stream and no buffers left.  CRLFStringBuf is empty. */
  122     if (sb->endofstream && sb->bufsfull == 0) {
  123     *buffer = NULL;
  124     *size   = 0;
  125     *length = 0; 
  126     return 0;
  127     }
  128 
  129     cur = sb->index % sb->numb;
  130     
  131     sb->index++;
  132     sb->bufsfull--;
  133 
  134     /* Make sure we have at least two buffers left or        *
  135      * crlfsbuf_peek() won't work. If the number of buffers  * 
  136      * is 2 and we haven't reached the end of the stream,    * 
  137      * then fill the buffer back up.                         */
  138     if (sb->bufsfull <= 1 && !sb->endofstream) {
  139     fillBuffer(sb, sb->index + 1, sb->numb - 1);
  140     }
  141 
  142     *buffer = (sb->buf)[cur];
  143     *size   = (sb->size)[cur];
  144     *length = (sb->length)[cur];
  145 
  146     //fprintf(stderr, "Reading CRLF Data: %s", *buffer);
  147 
  148     return sb->length[cur];
  149 }
  150 
  151 
  152 char *
  153 crlfsbuf_peek(CRLFStringBuf *sb)
  154 {
  155     return ((sb->buf)[sb->index % sb->numb]);
  156 }
  157 
  158 
  159 size_t
  160 crlfsbuf_linesread(CRLFStringBuf *sb)
  161 {
  162     return sb->index;
  163 }
  164 
  165 
  166 int
  167 crlfsbuf_truncated(CRLFStringBuf *sb)
  168 {
  169     return sb->truncated;
  170 }
  171 
  172 
  173 size_t
  174 crlfsbuf_bytesread(CRLFStringBuf *sb)
  175 {
  176     return sb->bytesread;
  177 }
  178 
  179 
  180 void
  181 crlfsbuf_dump(CRLFStringBuf *sb, FILE *stream)
  182 {
  183     int i;
  184 
  185     for (i = 0; i < sb->numb; i++) {
  186     if ((sb->buf)[i] != NULL)
  187         fwrite((sb->buf)[i], sizeof(char), (sb->length)[i], stream);
  188     }
  189 }
  190 
  191 
  192 void
  193 crlfsbuf_free(CRLFStringBuf *sb)
  194 {
  195     int i;
  196 
  197     /* Free buffer array. */
  198     for (i = 0; i < sb->numb; i++) {
  199     /*fprintf(stderr, 
  200         "[%d] Attempting to free crlfsbuf: size: %d, length: %d\n", 
  201         i, sb->size[i], sb->length[i]);
  202     */
  203     XFREE((sb->buf)[i]);
  204     }
  205 
  206     XFREE(sb->buf);
  207 
  208     /* Free buffer size array. */
  209     XFREE(sb->size);
  210 
  211     /* Free buffer length array. */
  212     XFREE(sb->length);
  213 
  214     XFREE(sb);
  215 }
  216 
  217 
  218 /* Fill the internal buffer back up.  Check that we have  *
  219  * not violated either the line limit or the buffer limit *
  220  * in the process.                                        */
  221 static void 
  222 fillBuffer(CRLFStringBuf *crlfsbuf, int startPos, int endPos)
  223 {
  224     int i, blimit, limit, truncated;
  225 
  226     limit     = 0;
  227     blimit    = 0;
  228     truncated = 0;
  229 
  230     for (; crlfsbuf->bufsfull < endPos && !crlfsbuf->endofstream; startPos++) {
  231     i = startPos % crlfsbuf->numb;
  232 
  233     /* If the buffer limit is less than the line limit, make sure we only read that much. */
  234     (crlfsbuf->bufLimit > 0) ? (blimit = crlfsbuf->bufLimit - crlfsbuf->bytesread) : (blimit = 0);
  235     (crlfsbuf->lineLimit > 0 && crlfsbuf->lineLimit <= blimit) ? (limit = crlfsbuf->lineLimit) : (limit = blimit);  
  236 
  237     crlfsbuf->length[i] = readCRLFLine(crlfsbuf->stream, &(crlfsbuf->buf[i]), &(crlfsbuf->size[i]),
  238                            limit, &crlfsbuf->endofstream, &truncated);
  239 
  240     crlfsbuf->bytesread += crlfsbuf->length[i];
  241     crlfsbuf->bufsfull++;
  242 
  243     if (truncated && crlfsbuf->bytesread >= crlfsbuf->bufLimit)
  244         crlfsbuf->truncated++;
  245 
  246     /*fprintf(stderr, "[End of Stream: %d] [Index: %d] Reading CRLF String: %s", 
  247       crlfsbuf->endofstream, i, crlfsbuf->buf[i]);*/
  248     }
  249 }
  250 
  251 
  252 /* Read a line in from the file stream and check to make  *
  253  * sure that the entire string was read. The string is    *
  254  * terminated by "\r\n" (CRLF). If the character array is *
  255  * too short, make it bigger.                             *
  256  *                                                        *
  257  * Return the number of characters read.                  */
  258 static int
  259 readCRLFLine(FILE *stream, char **line, size_t *size, size_t linelimit, int *endofstream, int *truncated)
  260 {
  261     unsigned char c;
  262     size_t        llen;
  263 
  264     /* Return if end of stream. */
  265     if (feof(stream) || *endofstream)
  266     return 0;
  267     
  268     /* If the string is NULL malloc it to an initial size. */
  269     if ((*line) == NULL && (*size) == 0) {
  270     (*size) = 256;
  271     (*line) = XMALLOC(char, *size);
  272     }
  273 
  274     memset(*line, 0, *size);
  275     llen = 0;
  276 
  277     /* Make sure we read an entire line ending with CRLF ("\r\n"). */
  278     do {        
  279     c = fgetc(stream);
  280 
  281     if (feof(stream))
  282         break;
  283 
  284     if (llen + 1 <= (*size) - 1) {
  285         (*line)[llen] = c;
  286         llen++;
  287     }
  288     else {
  289         *size *= 2;
  290         *line  = XREALLOC(char, *line, *size);
  291         (*line)[llen] = c;
  292         llen++;
  293     }
  294 
  295     /* Check that we have not read in more than the limit. */
  296     if (linelimit > 0 && llen >= linelimit) {
  297         fprintf(stderr, "readCRLFLine: LineLimit: %d, Line Length: %d\n", linelimit, llen);
  298         (*truncated)++;
  299         break;
  300     }
  301 
  302     } while ((*line)[llen - 1] != '\n');
  303     
  304     /* Ensure that the line is always NULL-terminated. */
  305     (*line)[llen] = '\0';
  306 
  307     if (feof(stream))
  308     *endofstream = 1;
  309     else 
  310     *endofstream = 0;
  311 
  312     return llen;
  313 }