Back to index

glibc  2.9
wmemstream.c
Go to the documentation of this file.
00001 /* Copyright (C) 1995-97,99,2000,2002-2004,2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include "libioP.h"
00020 #include "strfile.h"
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <wchar.h>
00024 
00025 
00026 struct _IO_FILE_wmemstream
00027 {
00028   _IO_strfile _sf;
00029   wchar_t **bufloc;
00030   _IO_size_t *sizeloc;
00031 };
00032 
00033 
00034 static int _IO_wmem_sync (_IO_FILE* fp) __THROW;
00035 static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW;
00036 
00037 
00038 static const struct _IO_jump_t _IO_wmem_jumps =
00039 {
00040   JUMP_INIT_DUMMY,
00041   JUMP_INIT (finish, _IO_wmem_finish),
00042   JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
00043   JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
00044   JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)),
00045   JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
00046   JUMP_INIT (xsputn, INTUSE(_IO_wdefault_xsputn)),
00047   JUMP_INIT (xsgetn, INTUSE(_IO_wdefault_xsgetn)),
00048   JUMP_INIT (seekoff, _IO_wstr_seekoff),
00049   JUMP_INIT (seekpos, _IO_default_seekpos),
00050   JUMP_INIT (setbuf, _IO_default_setbuf),
00051   JUMP_INIT (sync, _IO_wmem_sync),
00052   JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)),
00053   JUMP_INIT (read, _IO_default_read),
00054   JUMP_INIT (write, _IO_default_write),
00055   JUMP_INIT (seek, _IO_default_seek),
00056   JUMP_INIT (close, _IO_default_close),
00057   JUMP_INIT (stat, _IO_default_stat),
00058   JUMP_INIT (showmanyc, _IO_default_showmanyc),
00059   JUMP_INIT (imbue, _IO_default_imbue)
00060 };
00061 
00062 /* Open a stream that writes into a malloc'd buffer that is expanded as
00063    necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
00064    and the number of characters written on fflush or fclose.  */
00065 _IO_FILE *
00066 open_wmemstream (bufloc, sizeloc)
00067      wchar_t **bufloc;
00068      _IO_size_t *sizeloc;
00069 {
00070   struct locked_FILE
00071   {
00072     struct _IO_FILE_wmemstream fp;
00073 #ifdef _IO_MTSAFE_IO
00074     _IO_lock_t lock;
00075 #endif
00076     struct _IO_wide_data wd;
00077   } *new_f;
00078   wchar_t *buf;
00079 
00080   new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
00081   if (new_f == NULL)
00082     return NULL;
00083 #ifdef _IO_MTSAFE_IO
00084   new_f->fp._sf._sbf._f._lock = &new_f->lock;
00085 #endif
00086 
00087   buf = calloc (1, _IO_BUFSIZ);
00088   if (buf == NULL)
00089     return NULL;
00090 
00091   _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
00092   _IO_fwide (&new_f->fp._sf._sbf._f, 1);
00093   _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
00094                      _IO_BUFSIZ / sizeof (wchar_t), buf);
00095   new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
00096   new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
00097   new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
00098 
00099   new_f->fp.bufloc = bufloc;
00100   new_f->fp.sizeloc = sizeloc;
00101 
00102   return (_IO_FILE *) &new_f->fp._sf._sbf;
00103 }
00104 
00105 
00106 static int
00107 _IO_wmem_sync (fp)
00108      _IO_FILE* fp;
00109 {
00110   struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
00111 
00112   if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
00113     {
00114       _IO_wstr_overflow (fp, '\0');
00115       --fp->_wide_data->_IO_write_ptr;
00116     }
00117   else
00118     *fp->_wide_data->_IO_write_ptr = '\0';
00119 
00120   *mp->bufloc = fp->_wide_data->_IO_write_base;
00121   *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
00122                 - fp->_wide_data->_IO_write_base);
00123 
00124   return 0;
00125 }
00126 
00127 
00128 static void
00129 _IO_wmem_finish (fp, dummy)
00130      _IO_FILE* fp;
00131      int dummy;
00132 {
00133   struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
00134 
00135   *mp->bufloc = (wchar_t *) realloc (fp->_wide_data->_IO_write_base,
00136                                  (fp->_wide_data->_IO_write_ptr
00137                                   - fp->_wide_data->_IO_write_base + 1)
00138                                  * sizeof (wchar_t));
00139   if (*mp->bufloc != NULL)
00140     {
00141       size_t len = (fp->_wide_data->_IO_write_ptr
00142                   - fp->_wide_data->_IO_write_base);
00143       (*mp->bufloc)[len] = '\0';
00144       *mp->sizeloc = len;
00145 
00146       fp->_wide_data->_IO_buf_base = NULL;
00147     }
00148 
00149   _IO_wstr_finish (fp, 0);
00150 }