(root)/
glibc-2.38/
libio/
wmemstream.c
       1  /* Copyright (C) 1995-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include "libioP.h"
      19  #include "strfile.h"
      20  #include <stdio.h>
      21  #include <stdlib.h>
      22  #include <wchar.h>
      23  
      24  
      25  struct _IO_FILE_wmemstream
      26  {
      27    _IO_strfile _sf;
      28    wchar_t **bufloc;
      29    size_t *sizeloc;
      30  };
      31  
      32  
      33  /* Open a stream that writes into a malloc'd buffer that is expanded as
      34     necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
      35     and the number of characters written on fflush or fclose.  */
      36  FILE *
      37  open_wmemstream (wchar_t **bufloc, size_t *sizeloc)
      38  {
      39    struct locked_FILE
      40    {
      41      struct _IO_FILE_wmemstream fp;
      42  #ifdef _IO_MTSAFE_IO
      43      _IO_lock_t lock;
      44  #endif
      45      struct _IO_wide_data wd;
      46    } *new_f;
      47    wchar_t *buf;
      48  
      49    new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
      50    if (new_f == NULL)
      51      return NULL;
      52  #ifdef _IO_MTSAFE_IO
      53    new_f->fp._sf._sbf._f._lock = &new_f->lock;
      54  #endif
      55  
      56    buf = calloc (1, BUFSIZ);
      57    if (buf == NULL)
      58      {
      59        free (new_f);
      60        return NULL;
      61      }
      62    _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
      63    _IO_fwide (&new_f->fp._sf._sbf._f, 1);
      64    _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
      65  			BUFSIZ / sizeof (wchar_t), buf);
      66    new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
      67    new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
      68    new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
      69  
      70    new_f->fp.bufloc = bufloc;
      71    new_f->fp.sizeloc = sizeloc;
      72  
      73    /* Disable single thread optimization.  BZ 21735.  */
      74    new_f->fp._sf._sbf._f._flags2 |= _IO_FLAGS2_NEED_LOCK;
      75  
      76    return (FILE *) &new_f->fp._sf._sbf;
      77  }
      78  
      79  
      80  int
      81  _IO_wmem_sync (FILE *fp)
      82  {
      83    struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
      84  
      85    if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
      86      {
      87        _IO_wstr_overflow (fp, '\0');
      88        --fp->_wide_data->_IO_write_ptr;
      89      }
      90  
      91    *mp->bufloc = fp->_wide_data->_IO_write_base;
      92    *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
      93  		  - fp->_wide_data->_IO_write_base);
      94  
      95    return 0;
      96  }
      97  
      98  
      99  void
     100  _IO_wmem_finish (FILE *fp, int dummy)
     101  {
     102    struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
     103  
     104    *mp->bufloc = (wchar_t *) realloc (fp->_wide_data->_IO_write_base,
     105  				     (fp->_wide_data->_IO_write_ptr
     106  				      - fp->_wide_data->_IO_write_base + 1)
     107  				     * sizeof (wchar_t));
     108    if (*mp->bufloc != NULL)
     109      {
     110        size_t len = (fp->_wide_data->_IO_write_ptr
     111  		    - fp->_wide_data->_IO_write_base);
     112        (*mp->bufloc)[len] = '\0';
     113        *mp->sizeloc = len;
     114  
     115        fp->_wide_data->_IO_buf_base = NULL;
     116      }
     117  
     118    _IO_wstr_finish (fp, 0);
     119  }