LCOV - code coverage report
Current view: top level - common/stream - bstream.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 56 88 63.6 %
Date: 2021-10-13 02:24:04 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "stream.h"
      11             : #include "stream_internal.h"
      12             : 
      13             : 
      14             : 
      15             : 
      16             : /* ------------------------------------------------------------------ */
      17             : 
      18             : bstream *
      19      170454 : bstream_create(stream *s, size_t size)
      20             : {
      21             :         bstream *b;
      22             : 
      23      170454 :         if (s == NULL)
      24             :                 return NULL;
      25      170454 :         if ((b = malloc(sizeof(*b))) == NULL)
      26             :                 return NULL;
      27      170454 :         *b = (bstream) {
      28             :                 .mode = size,
      29             :                 .s = s,
      30             :                 .eof = false,
      31             :         };
      32      170454 :         if (size == 0)
      33             :                 size = BUFSIZ;
      34      170454 :         b->buf = malloc(size + 1 + 1);
      35      170454 :         if (b->buf == NULL) {
      36           0 :                 free(b);
      37           0 :                 return NULL;
      38             :         }
      39      170454 :         b->size = size;
      40      170454 :         return b;
      41             : }
      42             : 
      43             : ssize_t
      44      718901 : bstream_read(bstream *s, size_t size)
      45             : {
      46             :         ssize_t rd, rd1 = 0;
      47             : 
      48      718901 :         if (s == NULL)
      49             :                 return -1;
      50             : 
      51      718901 :         if (s->eof)
      52             :                 return 0;
      53             : 
      54      718899 :         assert(s->buf != NULL);
      55             : 
      56      718899 :         if (s->pos > 0) {
      57      274489 :                 if (s->pos < s->len) {
      58             :                         /* move all data and end of string marker */
      59        1476 :                         memmove(s->buf, s->buf + s->pos, s->len - s->pos + 1);
      60        1476 :                         s->len -= s->pos;
      61             :                 } else
      62      273013 :                         s->len = 0;
      63      274489 :                 s->pos = 0;
      64             :         }
      65             : 
      66      718899 :         if (s->len == s->size) {
      67         105 :                 size_t sz = size > 8192 ? 8192 : size;
      68             :                 char tmpbuf[8192];
      69             : 
      70             :                 /* before we realloc more space, see if there is a need */
      71         105 :                 if ((rd1 = s->s->read(s->s, tmpbuf, 1, sz)) == 0) {
      72          10 :                         s->eof = true;
      73          10 :                         return 0;
      74             :                 }
      75          95 :                 if (rd1 < 0)
      76             :                         return rd1;
      77             :                 char *p;
      78          95 :                 size_t ns = s->size + size;
      79          95 :                 if ((p = realloc(s->buf, ns + 1)) == NULL) {
      80             :                         return -1;
      81             :                 }
      82          95 :                 s->size = ns;
      83          95 :                 s->buf = p;
      84          95 :                 memcpy(s->buf + s->len, tmpbuf, rd1);
      85          95 :                 s->len += rd1;
      86          95 :                 size -= rd1;
      87          95 :                 if (size == 0)
      88             :                         return rd1;
      89             :         }
      90             : 
      91      718889 :         if (s->len + size > s->size)
      92      121182 :                 size = s->size - s->len;
      93             : 
      94      718889 :         rd = s->s->read(s->s, s->buf + s->len, 1, size);
      95             : 
      96      718889 :         if (rd < 0)
      97             :                 return rd;
      98             : 
      99      718872 :         if (rd == 0) {
     100      280139 :                 s->eof = true;
     101      280139 :                 return rd1;
     102             :         }
     103      438733 :         s->len += (size_t) rd;
     104      438733 :         s->buf[s->len] = 0;       /* fill in the spare with EOS */
     105      438733 :         return rd + rd1;
     106             : }
     107             : 
     108             : #ifdef _POSIX2_LINE_MAX
     109             : #define STREAM_LINE_MAX _POSIX2_LINE_MAX
     110             : #else
     111             : #define STREAM_LINE_MAX 2048
     112             : #endif
     113             : 
     114             : static ssize_t
     115           0 : bstream_readline(bstream *s)
     116             : {
     117             :         size_t size = STREAM_LINE_MAX;
     118             :         size_t rd;
     119             : 
     120           0 :         if (s->eof)
     121             :                 return 0;
     122             : 
     123           0 :         if (s->pos > 0 && s->len + size >= s->size) {
     124           0 :                 if (s->pos < s->len) {
     125             :                         /* move all data and end of string marker */
     126           0 :                         memmove(s->buf, s->buf + s->pos, s->len - s->pos + 1);
     127           0 :                         s->len -= s->pos;
     128             :                 } else
     129           0 :                         s->len = 0;
     130           0 :                 s->pos = 0;
     131             :         }
     132             : 
     133           0 :         assert(s->buf != NULL);
     134           0 :         if (s->len == s->size) {
     135             :                 char *p;
     136           0 :                 size_t ns = s->size + size + 8192;
     137           0 :                 if ((p = realloc(s->buf, ns + 1)) == NULL) {
     138             :                         return -1;
     139             :                 }
     140           0 :                 s->size = ns;
     141           0 :                 s->buf = p;
     142             :         }
     143             : 
     144           0 :         if (size > s->size - s->len)
     145             :                 size = s->size - s->len;
     146             : 
     147           0 :         if (fgets(s->buf + s->len, (int) size, s->s->stream_data.p) == NULL)
     148             :                 return -1;
     149             : 
     150           0 :         rd = strlen(s->buf + s->len);
     151             : 
     152           0 :         if (rd == 0) {
     153           0 :                 s->eof = true;
     154           0 :                 return 0;
     155             :         }
     156           0 :         s->len += rd;
     157           0 :         s->buf[s->len] = 0;       /* fill in the spare with EOS */
     158           0 :         return (ssize_t) rd;
     159             : }
     160             : 
     161             : 
     162             : ssize_t
     163      717494 : bstream_next(bstream *s)
     164             : {
     165      717494 :         if (s == NULL)
     166             :                 return -1;
     167      717494 :         if (s->mode > 0) {
     168      717494 :                 return bstream_read(s, s->mode);
     169           0 :         } else if (s->s->read == file_read) {
     170           0 :                 return bstream_readline(s);
     171             :         } else {
     172             :                 size_t sz = 0;
     173             :                 ssize_t rd;
     174             : 
     175           0 :                 while ((rd = bstream_read(s, 1)) == 1 &&
     176           0 :                        s->buf[s->pos + sz] != '\n') {
     177           0 :                         sz++;   /* sz += rd, but rd == 1 */
     178             :                 }
     179           0 :                 if (rd < 0)
     180             :                         return rd;
     181           0 :                 return (ssize_t) sz;
     182             :         }
     183             : }
     184             : 
     185             : void
     186      170453 : bstream_destroy(bstream *s)
     187             : {
     188      170453 :         if (s) {
     189      170453 :                 if (s->s) {
     190      170143 :                         s->s->close(s->s);
     191      170143 :                         s->s->destroy(s->s);
     192             :                 }
     193      170453 :                 if (s->buf)
     194      170453 :                         free(s->buf);
     195      170453 :                 free(s);
     196             :         }
     197      170453 : }
     198             : 

Generated by: LCOV version 1.14