LCOV - code coverage report
Current view: top level - common/stream - memio.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 76 101 75.2 %
Date: 2024-04-25 20:03:45 Functions: 9 11 81.8 %

          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             : void
      19      199708 : buffer_init(buffer *restrict b, char *restrict buf, size_t size)
      20             : {
      21      199708 :         if (b == NULL || buf == NULL)
      22             :                 return;
      23      199708 :         b->pos = 0;
      24      199708 :         b->buf = buf;
      25      199708 :         b->len = size;
      26             : }
      27             : 
      28             : buffer *
      29         484 : buffer_create(size_t size)
      30             : {
      31         484 :         buffer *b;
      32             : 
      33         484 :         if ((b = malloc(sizeof(*b))) == NULL)
      34             :                 return NULL;
      35         484 :         *b = (buffer) {
      36         484 :                 .buf = malloc(size),
      37             :                 .len = size,
      38             :         };
      39         484 :         if (b->buf == NULL) {
      40           0 :                 free(b);
      41           0 :                 return NULL;
      42             :         }
      43             :         return b;
      44             : }
      45             : 
      46             : char *
      47         190 : buffer_get_buf(buffer *b)
      48             : {
      49         190 :         char *r;
      50             : 
      51         190 :         if (b == NULL)
      52             :                 return NULL;
      53         190 :         if (b->pos == b->len) {
      54           0 :                 if ((r = realloc(b->buf, b->len + 1)) == NULL) {
      55             :                         /* keep b->buf in tact */
      56             :                         return NULL;
      57             :                 }
      58           0 :                 b->buf = r;
      59             :         }
      60         190 :         r = b->buf;
      61         190 :         r[b->pos] = '\0';
      62         190 :         b->buf = malloc(b->len);
      63         190 :         if (b->buf == NULL) {
      64             :                 /* restore b->buf */
      65           0 :                 b->buf = r;
      66           0 :                 return NULL;
      67             :         }
      68         190 :         b->pos = 0;
      69         190 :         return r;
      70             : }
      71             : 
      72             : void
      73      200192 : buffer_destroy(buffer *b)
      74             : {
      75      200192 :         if (b == NULL)
      76             :                 return;
      77      200192 :         if (b->buf)
      78      200192 :                 free(b->buf);
      79      200192 :         free(b);
      80             : }
      81             : 
      82             : buffer *
      83           0 : mnstr_get_buffer(stream *s)
      84             : {
      85           0 :         if (s == NULL)
      86             :                 return NULL;
      87           0 :         return (buffer *) s->stream_data.p;
      88             : }
      89             : 
      90             : static ssize_t
      91      199708 : buffer_read(stream *restrict s, void *restrict buf, size_t elmsize, size_t cnt)
      92             : {
      93      199708 :         size_t size = elmsize * cnt;
      94      199708 :         buffer *b;
      95             : 
      96      199708 :         b = (buffer *) s->stream_data.p;
      97      199708 :         assert(b);
      98      199708 :         if (size && b && b->pos + size <= b->len) {
      99      199708 :                 memcpy(buf, b->buf + b->pos, size);
     100      199708 :                 b->pos += size;
     101      199708 :                 return (ssize_t) (size / elmsize);
     102             :         }
     103           0 :         s->eof |= b->pos == b->len;
     104           0 :         return 0;
     105             : }
     106             : 
     107             : static ssize_t
     108       45713 : buffer_write(stream *restrict s, const void *restrict buf, size_t elmsize, size_t cnt)
     109             : {
     110       45713 :         size_t size = elmsize * cnt;
     111       45713 :         buffer *b;
     112             : 
     113       45713 :         b = (buffer *) s->stream_data.p;
     114       45713 :         assert(b);
     115       45713 :         if (b == NULL) {
     116             :                 mnstr_set_error(s, MNSTR_WRITE_ERROR, "buffer already deallocated");
     117             :                 return -1;
     118             :         }
     119       45713 :         if (b->pos + size > b->len) {
     120          15 :                 char *p;
     121          15 :                 size_t ns = b->pos + size + 8192;
     122             : 
     123          15 :                 if ((p = realloc(b->buf, ns)) == NULL) {
     124           0 :                         mnstr_set_error(s, MNSTR_WRITE_ERROR, "buffer reallocation failed");
     125           0 :                         return -1;
     126             :                 }
     127          15 :                 b->buf = p;
     128          15 :                 b->len = ns;
     129             :         }
     130       45713 :         memcpy(b->buf + b->pos, buf, size);
     131       45713 :         b->pos += size;
     132       45713 :         return (ssize_t) cnt;
     133             : }
     134             : 
     135             : static void
     136      200192 : buffer_close(stream *s)
     137             : {
     138      200192 :         (void) s;
     139      200192 : }
     140             : 
     141             : static int
     142           0 : buffer_flush(stream *s, mnstr_flush_level flush_level)
     143             : {
     144           0 :         buffer *b;
     145             : 
     146           0 :         b = (buffer *) s->stream_data.p;
     147           0 :         assert(b);
     148           0 :         if (b == NULL)
     149             :                 return -1;
     150           0 :         b->pos = 0;
     151           0 :         (void) flush_level;
     152           0 :         return 0;
     153             : }
     154             : 
     155             : stream *
     156      199708 : buffer_rastream(buffer *restrict b, const char *restrict name)
     157             : {
     158      199708 :         stream *s;
     159             : 
     160      199708 :         if (b == NULL || name == NULL) {
     161           0 :                 mnstr_set_open_error(name, 0, "no buffer or no name");
     162           0 :                 return NULL;
     163             :         }
     164             : #ifdef STREAM_DEBUG
     165             :         fprintf(stderr, "buffer_rastream %s\n", name);
     166             : #endif
     167      199708 :         if ((s = create_stream(name)) == NULL)
     168             :                 return NULL;
     169      199708 :         s->binary = false;
     170      199708 :         s->read = buffer_read;
     171      199708 :         s->write = buffer_write;
     172      199708 :         s->close = buffer_close;
     173      199708 :         s->flush = buffer_flush;
     174      199708 :         s->stream_data.p = (void *) b;
     175      199708 :         return s;
     176             : }
     177             : 
     178             : stream *
     179         484 : buffer_wastream(buffer *restrict b, const char *restrict name)
     180             : {
     181         484 :         stream *s;
     182             : 
     183         484 :         if (b == NULL || name == NULL) {
     184           0 :                 mnstr_set_open_error(name, 0, "no buffer or no name");
     185           0 :                 return NULL;
     186             :         }
     187             : #ifdef STREAM_DEBUG
     188             :         fprintf(stderr, "buffer_wastream %s\n", name);
     189             : #endif
     190         484 :         if ((s = create_stream(name)) == NULL)
     191             :                 return NULL;
     192         484 :         s->readonly = false;
     193         484 :         s->binary = false;
     194         484 :         s->read = buffer_read;
     195         484 :         s->write = buffer_write;
     196         484 :         s->close = buffer_close;
     197         484 :         s->flush = buffer_flush;
     198         484 :         s->stream_data.p = (void *) b;
     199         484 :         return s;
     200             : }

Generated by: LCOV version 1.14