LCOV - code coverage report
Current view: top level - common/stream - memio.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 69 89 77.5 %
Date: 2021-10-27 03:06:47 Functions: 9 11 81.8 %

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

Generated by: LCOV version 1.14