(root)/
gettext-0.22.4/
libtextstyle/
lib/
memory-ostream.oo.c
       1  /* Output stream that accumulates the output in memory.
       2     Copyright (C) 2006-2007, 2019-2020, 2023 Free Software Foundation, Inc.
       3     Written by Bruno Haible <bruno@clisp.org>, 2006.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation; either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <config.h>
      19  
      20  /* Specification.  */
      21  #include "memory-ostream.h"
      22  
      23  #include <stdlib.h>
      24  #include <string.h>
      25  
      26  #include "error.h"
      27  #include "xalloc.h"
      28  #include "xsize.h"
      29  #include "gettext.h"
      30  
      31  #define _(str) gettext (str)
      32  
      33  struct memory_ostream : struct ostream
      34  {
      35  fields:
      36    char *buffer;                 /* Buffer containing the accumulated output.  */
      37    size_t buflen;                /* Number of bytes stored so far.  */
      38    size_t allocated;             /* Allocated size of the buffer.  */
      39  };
      40  
      41  /* Implementation of ostream_t methods.  */
      42  
      43  static void
      44  memory_ostream::write_mem (memory_ostream_t stream,
      45                             const void *data, size_t len)
      46  {
      47    if (len > 0)
      48      {
      49        if (len > stream->allocated - stream->buflen)
      50          {
      51            size_t new_allocated =
      52              xmax (xsum (stream->buflen, len),
      53                    xsum (stream->allocated, stream->allocated));
      54            if (size_overflow_p (new_allocated))
      55              error (EXIT_FAILURE, 0,
      56                     _("%s: too much output, buffer size overflow"),
      57                     "memory_ostream");
      58            stream->buffer = (char *) xrealloc (stream->buffer, new_allocated);
      59            stream->allocated = new_allocated;
      60          }
      61        memcpy (stream->buffer + stream->buflen, data, len);
      62        stream->buflen += len;
      63      }
      64  }
      65  
      66  static void
      67  memory_ostream::flush (memory_ostream_t stream, ostream_flush_scope_t scope)
      68  {
      69  }
      70  
      71  static void
      72  memory_ostream::free (memory_ostream_t stream)
      73  {
      74    free (stream->buffer);
      75    free (stream);
      76  }
      77  
      78  /* Implementation of memory_ostream_t methods.  */
      79  
      80  static void
      81  memory_ostream::contents (memory_ostream_t stream,
      82                            const void **bufp, size_t *buflenp)
      83  {
      84    *bufp = stream->buffer;
      85    *buflenp = stream->buflen;
      86  }
      87  
      88  /* Constructor.  */
      89  
      90  memory_ostream_t
      91  memory_ostream_create (void)
      92  {
      93    memory_ostream_t stream = XMALLOC (struct memory_ostream_representation);
      94  
      95    stream->base.vtable = &memory_ostream_vtable;
      96    stream->allocated = 250;
      97    stream->buffer = XNMALLOC (stream->allocated, char);
      98    stream->buflen = 0;
      99  
     100    return stream;
     101  }
     102  
     103  /* Instanceof test.  */
     104  
     105  bool
     106  is_instance_of_memory_ostream (ostream_t stream)
     107  {
     108    return IS_INSTANCE (stream, ostream, memory_ostream);
     109  }