1 /*
2  *  unicode.h
3  *
4  *  $Id$
5  *
6  *  ODBC unicode support
7  *
8  *  The iODBC driver manager.
9  *
10  *  Copyright (C) 1996-2021 OpenLink Software <iodbc@openlinksw.com>
11  *  All Rights Reserved.
12  *
13  *  This software is released under the terms of either of the following
14  *  licenses:
15  *
16  *      - GNU Library General Public License (see LICENSE.LGPL)
17  *      - The BSD License (see LICENSE.BSD).
18  *
19  *  Note that the only valid version of the LGPL license as far as this
20  *  project is concerned is the original GNU Library General Public License
21  *  Version 2, dated June 1991.
22  *
23  *  While not mandated by the BSD license, any patches you make to the
24  *  iODBC source code may be contributed back into the iODBC project
25  *  at your discretion. Contributions will benefit the Open Source and
26  *  Data Access community as a whole. Submissions may be made at:
27  *
28  *      http://www.iodbc.org
29  *
30  *
31  *  GNU Library Generic Public License Version 2
32  *  ============================================
33  *  This library is free software; you can redistribute it and/or
34  *  modify it under the terms of the GNU Library General Public
35  *  License as published by the Free Software Foundation; only
36  *  Version 2 of the License dated June 1991.
37  *
38  *  This library is distributed in the hope that it will be useful,
39  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
40  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41  *  Library General Public License for more details.
42  *
43  *  You should have received a copy of the GNU Library General Public
44  *  License along with this library; if not, write to the Free
45  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
46  *
47  *
48  *  The BSD License
49  *  ===============
50  *  Redistribution and use in source and binary forms, with or without
51  *  modification, are permitted provided that the following conditions
52  *  are met:
53  *
54  *  1. Redistributions of source code must retain the above copyright
55  *     notice, this list of conditions and the following disclaimer.
56  *  2. Redistributions in binary form must reproduce the above copyright
57  *     notice, this list of conditions and the following disclaimer in
58  *     the documentation and/or other materials provided with the
59  *     distribution.
60  *  3. Neither the name of OpenLink Software Inc. nor the names of its
61  *     contributors may be used to endorse or promote products derived
62  *     from this software without specific prior written permission.
63  *
64  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
65  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
66  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
67  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
68  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
69  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
70  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
71  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
72  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
73  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75  */
76 
77 #ifndef _UNICODE_H
78 #define _UNICODE_H
79 
80 #include <iodbc.h>
81 #include <iodbcext.h>
82 
83 #if defined (HAVE_WCHAR_H)
84 #include <wchar.h>
85 #endif
86 
87 typedef unsigned char  utf8_t;
88 typedef unsigned short ucs2_t;
89 typedef unsigned int   ucs4_t;
90 
91 typedef enum
92   {
93     CP_UCS4    = SQL_DM_CP_UCS4,
94     CP_UTF16   = SQL_DM_CP_UTF16,
95     CP_UTF8    = SQL_DM_CP_UTF8
96   }
97 IODBC_CHARSET;
98 
99 #if defined(SIZEOF_WCHAR)
100 
101 # if (SIZEOF_WCHAR == 2)
102 #  define CP_DEF  CP_UTF16
103 # else
104 #  define CP_DEF  CP_UCS4
105 # endif
106 
107 #else
108 
109 #  define CP_DEF  CP_UCS4
110 
111 #endif
112 
113 
114 
115 #define WCHAR_MAXSIZE  4
116 
117 
118 typedef struct _dm_conv
119   {
120     IODBC_CHARSET dm_cp;
121     IODBC_CHARSET drv_cp;
122   }
123 DM_CONV;
124 
125 
126 typedef enum
127   {
128     CD_NONE		= 0,
129     CD_A2W		= 1,
130     CD_W2A		= 2,
131     CD_W2W		= 3
132   }
133 CONV_DIRECT;
134 
135 
136 
137 /*
138  *  Max length of a UTF-8 encoded character sequence
139  */
140 #define UTF8_MAX_CHAR_LEN	4	/* According to RFC3629 */
141 
142 #ifndef MB_CUR_MAX
143 #define MB_CUR_MAX		UTF8_MAX_CHAR_LEN
144 #endif
145 
146 
147 /*
148  *  Function Prototypes
149  */
150 SQLCHAR *dm_SQL_W2A (SQLWCHAR * inStr, int size);
151 SQLCHAR *dm_SQL_WtoU8 (SQLWCHAR * inStr, int size);
152 SQLCHAR *dm_strcpy_W2A (SQLCHAR * destStr, SQLWCHAR * sourStr);
153 
154 SQLWCHAR *dm_SQL_A2W (SQLCHAR * inStr, int size);
155 SQLWCHAR *dm_SQL_U8toW (SQLCHAR * inStr, int size);
156 SQLWCHAR *dm_strcpy_A2W (SQLWCHAR * destStr, SQLCHAR * sourStr);
157 
158 int dm_StrCopyOut2_A2W (SQLCHAR * inStr, SQLWCHAR * outStr, SQLSMALLINT size,
159     WORD * result);
160 int dm_StrCopyOut2_U8toW (SQLCHAR * inStr, SQLWCHAR * outStr, int size,
161     WORD * result);
162 int dm_StrCopyOut2_W2A (SQLWCHAR * inStr, SQLCHAR * outStr, SQLSMALLINT size,
163     WORD * result);
164 
165 
166 # ifdef WIN32
167 #define OPL_W2A(w, a, cb)     \
168 	WideCharToMultiByte(CP_ACP, 0, w, cb, a, cb, NULL, NULL)
169 
170 #define OPL_A2W(a, w, cb)     \
171 	MultiByteToWideChar(CP_ACP, 0, a, cb, w, cb)
172 
173 # else
174 #define OPL_W2A(XW, XA, SIZE)      wcstombs((char *) XA, (wchar_t *) XW, SIZE)
175 #define OPL_A2W(XA, XW, SIZE)      mbstowcs((wchar_t *) XW, (char *) XA, SIZE)
176 # endif
177 
178 int dm_conv_W2W(void *inStr, int len, void *outStr, int size,
179 	IODBC_CHARSET icharset, IODBC_CHARSET ocharset);
180 int dm_conv_W2A(void *inStr, int inLen, char *outStr, int size,
181 	IODBC_CHARSET charset);
182 int dm_conv_A2W(char *inStr, int inLen, void *outStr, int size,
183 	IODBC_CHARSET charset);
184 
185 void DM_strcpy_U8toW (DM_CONV *conv, void *dest, SQLCHAR *sour);
186 
187 size_t DRV_WCHARSIZE(DM_CONV *conv);
188 size_t DM_WCHARSIZE(DM_CONV *conv);
189 size_t DRV_WCHARSIZE_ALLOC(DM_CONV *conv);
190 size_t DM_WCHARSIZE_ALLOC(DM_CONV *conv);
191 
192 void *DM_A2W(DM_CONV *conv, SQLCHAR * inStr, int size);
193 SQLCHAR *DM_W2A(DM_CONV *conv, void * inStr, int size);
194 SQLCHAR *DRV_W2A(DM_CONV *conv, void * inStr, int size);
195 
196 void DM_SetWCharAt(DM_CONV *conv, void *str, int pos, int ch);
197 void DRV_SetWCharAt(DM_CONV *conv, void *str, int pos, int ch);
198 SQLWCHAR DM_GetWCharAt(DM_CONV *conv, void *str, int pos);
199 
200 void *DM_WCSCPY(DM_CONV *conv, void *dest, void *sour);
201 void *DM_WCSNCPY(DM_CONV *conv, void *dest, void *sour, size_t count);
202 void *DRV_WCSNCPY(DM_CONV *conv, void *dest, void *sour, size_t count);
203 
204 size_t DM_WCSLEN(DM_CONV *conv, void *str);
205 size_t DRV_WCSLEN(DM_CONV *conv, void *str);
206 
207 SQLCHAR *DM_WtoU8(DM_CONV *conv, void *inStr, int size);
208 SQLCHAR *DRV_WtoU8(DM_CONV *conv, void *inStr, int size);
209 void *DM_U8toW(DM_CONV *conv, SQLCHAR *inStr, int size);
210 
211 int dm_StrCopyOut2_A2W_d2m (DM_CONV *conv, SQLCHAR *inStr,
212 		void *outStr, int size, SQLSMALLINT *result, int *copied);
213 int dm_StrCopyOut2_W2A_d2m (DM_CONV *conv, void *inStr,
214 		SQLCHAR *outStr, int size, SQLSMALLINT *result, int *copied);
215 int dm_StrCopyOut2_U8toW_d2m (DM_CONV *conv, SQLCHAR *inStr,
216 		void *outStr, int size, SQLSMALLINT *result, int *copied);
217 int dm_StrCopyOut2_W2W_d2m (DM_CONV *conv, void *inStr,
218 		void *outStr, int size, SQLSMALLINT *result, int *copied);
219 
220 int dm_StrCopyOut2_W2A_m2d (DM_CONV *conv, void *inStr,
221 		SQLCHAR *outStr, int size, SQLSMALLINT *result, int *copied);
222 int dm_StrCopyOut2_W2W_m2d (DM_CONV *conv, void *inStr,
223 		void *outStr, int size, SQLSMALLINT *result, int *copied);
224 
225 
226 void *conv_text_d2m(DM_CONV *conv, void *inStr, int size,
227 	CONV_DIRECT direct);
228 void *conv_text_m2d(DM_CONV *conv, void *inStr, int size,
229 	CONV_DIRECT direct);
230 
231 void * conv_text_m2d_W2W(DM_CONV *conv, void *inStr, SQLLEN size,
232         SQLLEN *copied);
233 
234 
235 
236 /*
237  *  Replacement functions
238  */
239 #if !defined(HAVE_WCSLEN)
240 size_t wcslen (const wchar_t * wcs);
241 #endif
242 #if !defined(HAVE_WCSCPY)
243 wchar_t * wcscpy (wchar_t * wcd, const wchar_t * wcs);
244 #endif
245 #if !defined(HAVE_WCSNCPY)
246 wchar_t * wcsncpy (wchar_t * wcd, const wchar_t * wcs, size_t n);
247 #endif
248 #if !defined(HAVE_WCSCHR)
249 wchar_t* wcschr(const wchar_t *wcs, const wchar_t wc);
250 #endif
251 #if !defined(HAVE_WCSCAT)
252 wchar_t* wcscat(wchar_t *dest, const wchar_t *src);
253 #endif
254 #if !defined(HAVE_WCSCMP)
255 int wcscmp (const wchar_t* s1, const wchar_t* s2);
256 #endif
257 #if !defined(HAVE_WCSNCASECMP)
258 int wcsncasecmp (const wchar_t* s1, const wchar_t* s2, size_t n);
259 #endif
260 
261 #endif /* _UNICODE_H */
262