xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/config/io/c_io_libio_codecvt.c (revision c2fb321235c8dbfba0909bc43913400e90646ae7)
103a78d15Sespie /* Copyright (C) 2000 Free Software Foundation, Inc.
203a78d15Sespie    This file is part of the GNU IO Library.
303a78d15Sespie 
403a78d15Sespie    This library is free software; you can redistribute it and/or
503a78d15Sespie    modify it under the terms of the GNU General Public License as
603a78d15Sespie    published by the Free Software Foundation; either version 2, or (at
703a78d15Sespie    your option) any later version.
803a78d15Sespie 
903a78d15Sespie    This library is distributed in the hope that it will be useful, but
1003a78d15Sespie    WITHOUT ANY WARRANTY; without even the implied warranty of
1103a78d15Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1203a78d15Sespie    General Public License for more details.
1303a78d15Sespie 
1403a78d15Sespie    You should have received a copy of the GNU General Public License
1503a78d15Sespie    along with this library; see the file COPYING.  If not, write to
1603a78d15Sespie    the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
1703a78d15Sespie    MA 02111-1307, USA.
1803a78d15Sespie 
1903a78d15Sespie    As a special exception, if you link this library with files
2003a78d15Sespie    compiled with a GNU compiler to produce an executable, this does
2103a78d15Sespie    not cause the resulting executable to be covered by the GNU General
2203a78d15Sespie    Public License.  This exception does not however invalidate any
2303a78d15Sespie    other reasons why the executable file might be covered by the GNU
2403a78d15Sespie    General Public License.  */
2503a78d15Sespie 
2619731d4fSespie // As a special exception, you may use this file as part of a free software
2719731d4fSespie // library without restriction.  Specifically, if other files instantiate
2819731d4fSespie // templates or use macros or inline functions from this file, or you compile
2919731d4fSespie // this file and link it with other files to produce an executable, this
3019731d4fSespie // file does not by itself cause the resulting executable to be covered by
3119731d4fSespie // the GNU General Public License.  This exception does not however
3219731d4fSespie // invalidate any other reasons why the executable file might be covered by
3319731d4fSespie // the GNU General Public License.
3403a78d15Sespie /* Slightly modified from glibc/libio/iofwide.c */
3503a78d15Sespie 
3603a78d15Sespie #include <libio.h>
3703a78d15Sespie 
38*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
3903a78d15Sespie 
4003a78d15Sespie /* Prototypes of libio's codecvt functions.  */
4103a78d15Sespie static enum __codecvt_result
4203a78d15Sespie do_out(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
4303a78d15Sespie        const wchar_t *from_start, const wchar_t *from_end,
4403a78d15Sespie        const wchar_t **from_stop, char *to_start, char *to_end,
4503a78d15Sespie        char **to_stop);
4603a78d15Sespie 
4703a78d15Sespie static enum __codecvt_result
4803a78d15Sespie do_unshift(struct _IO_codecvt *codecvt, __c_mbstate_t *statep, char *to_start,
4903a78d15Sespie 	   char *to_end, char **to_stop);
5003a78d15Sespie 
5103a78d15Sespie static enum __codecvt_result
5203a78d15Sespie do_in(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
5303a78d15Sespie       const char *from_start, const char *from_end, const char **from_stop,
5403a78d15Sespie       wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop);
5503a78d15Sespie 
5603a78d15Sespie static int
5703a78d15Sespie do_encoding(struct _IO_codecvt *codecvt);
5803a78d15Sespie 
5903a78d15Sespie static int
6003a78d15Sespie do_length(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
6103a78d15Sespie 	  const char *from_start, const char *from_end, _IO_size_t max);
6203a78d15Sespie 
6303a78d15Sespie static int
6403a78d15Sespie do_max_length(struct _IO_codecvt *codecvt);
6503a78d15Sespie 
6603a78d15Sespie static int
6703a78d15Sespie do_always_noconv(struct _IO_codecvt *codecvt);
6803a78d15Sespie 
6903a78d15Sespie 
7003a78d15Sespie /* The functions used in `codecvt' for libio are always the same.  */
7103a78d15Sespie struct _IO_codecvt __c_libio_codecvt =
7203a78d15Sespie {
7303a78d15Sespie   .__codecvt_destr = NULL,		/* Destructor, never used.  */
7403a78d15Sespie   .__codecvt_do_out = do_out,
7503a78d15Sespie   .__codecvt_do_unshift = do_unshift,
7603a78d15Sespie   .__codecvt_do_in = do_in,
7703a78d15Sespie   .__codecvt_do_encoding = do_encoding,
7803a78d15Sespie   .__codecvt_do_always_noconv = do_always_noconv,
7903a78d15Sespie   .__codecvt_do_length = do_length,
8003a78d15Sespie   .__codecvt_do_max_length = do_max_length
8103a78d15Sespie };
8203a78d15Sespie 
8303a78d15Sespie static enum __codecvt_result
do_out(struct _IO_codecvt * codecvt,__c_mbstate_t * statep,const wchar_t * from_start,const wchar_t * from_end,const wchar_t ** from_stop,char * to_start,char * to_end,char ** to_stop)8403a78d15Sespie do_out(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
8503a78d15Sespie        const wchar_t *from_start, const wchar_t *from_end,
8603a78d15Sespie        const wchar_t **from_stop, char *to_start, char *to_end,
8703a78d15Sespie        char **to_stop)
8803a78d15Sespie {
8903a78d15Sespie   enum __codecvt_result res = __codecvt_ok;
9003a78d15Sespie 
9103a78d15Sespie   while (from_start < from_end)
9203a78d15Sespie     {
9303a78d15Sespie       if (to_start >= to_end)
9403a78d15Sespie 	{
9503a78d15Sespie 	  res = __codecvt_partial;
9603a78d15Sespie 	  break;
9703a78d15Sespie 	}
9803a78d15Sespie       *to_start++ = (char) *from_start++;
9903a78d15Sespie     }
10003a78d15Sespie 
10103a78d15Sespie   *from_stop = from_start;
10203a78d15Sespie   *to_stop = to_start;
10303a78d15Sespie 
10403a78d15Sespie   return res;
10503a78d15Sespie }
10603a78d15Sespie 
10703a78d15Sespie 
10803a78d15Sespie static enum __codecvt_result
do_unshift(struct _IO_codecvt * codecvt,__c_mbstate_t * statep,char * to_start,char * to_end,char ** to_stop)10903a78d15Sespie do_unshift(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
11003a78d15Sespie 	   char *to_start, char *to_end, char **to_stop)
11103a78d15Sespie {
11203a78d15Sespie   *to_stop = to_start;
11303a78d15Sespie   return __codecvt_ok;
11403a78d15Sespie }
11503a78d15Sespie 
11603a78d15Sespie 
11703a78d15Sespie static enum __codecvt_result
do_in(struct _IO_codecvt * codecvt,__c_mbstate_t * statep,const char * from_start,const char * from_end,const char ** from_stop,wchar_t * to_start,wchar_t * to_end,wchar_t ** to_stop)11803a78d15Sespie do_in(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
11903a78d15Sespie       const char *from_start, const char *from_end, const char **from_stop,
12003a78d15Sespie       wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
12103a78d15Sespie {
12203a78d15Sespie   enum __codecvt_result res = __codecvt_ok;
12303a78d15Sespie 
12403a78d15Sespie   while (from_start < from_end)
12503a78d15Sespie     {
12603a78d15Sespie       if (to_start >= to_end)
12703a78d15Sespie 	{
12803a78d15Sespie 	  res = __codecvt_partial;
12903a78d15Sespie 	  break;
13003a78d15Sespie 	}
13103a78d15Sespie       *to_start++ = (wchar_t) *from_start++;
13203a78d15Sespie     }
13303a78d15Sespie 
13403a78d15Sespie   *from_stop = from_start;
13503a78d15Sespie   *to_stop = to_start;
13603a78d15Sespie 
13703a78d15Sespie   return res;
13803a78d15Sespie }
13903a78d15Sespie 
14003a78d15Sespie 
14103a78d15Sespie static int
do_encoding(struct _IO_codecvt * codecvt)14203a78d15Sespie do_encoding(struct _IO_codecvt *codecvt)
14303a78d15Sespie { return 1; }
14403a78d15Sespie 
14503a78d15Sespie 
14603a78d15Sespie static int
do_always_noconv(struct _IO_codecvt * codecvt)14703a78d15Sespie do_always_noconv(struct _IO_codecvt *codecvt)
14803a78d15Sespie { return 0; }
14903a78d15Sespie 
15003a78d15Sespie 
15103a78d15Sespie static int
do_length(struct _IO_codecvt * codecvt,__c_mbstate_t * statep,const char * from_start,const char * from_end,_IO_size_t max)15203a78d15Sespie do_length(struct _IO_codecvt *codecvt, __c_mbstate_t *statep,
15303a78d15Sespie 	  const char *from_start, const char *from_end, _IO_size_t max)
15403a78d15Sespie { return from_end - from_start; }
15503a78d15Sespie 
15603a78d15Sespie 
15703a78d15Sespie static int
do_max_length(struct _IO_codecvt * codecvt)15803a78d15Sespie do_max_length(struct _IO_codecvt *codecvt)
15903a78d15Sespie { return 1; }
16003a78d15Sespie 
16103a78d15Sespie #endif /* _GLIBCPP_USE_WCHAR_T */
162