LCOV - code coverage report
Current view: top level - common/stream - bstream.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 60 97 61.9 %
Date: 2024-10-07 21:21:43 Functions: 5 6 83.3 %

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

Generated by: LCOV version 1.14