SDL  2.0
geniconv.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 /*
23  Universal iconv implementation for OS/2.
24 
25  Andrey Vasilkin, 2016.
26 */
27 
28 #define INCL_DOSMODULEMGR /* Module Manager values */
29 #define INCL_DOSERRORS /* Error values */
30 #include <os2.h>
31 
32 #include "geniconv.h"
33 
34 /*#define DEBUG*/
35 
36 #ifdef DEBUG
37 # include <stdio.h>
38 # define debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__)
39 #else
40 # define debug(s,...) do {} while (0)
41 #endif
42 
43 /* Exports from os2iconv.c */
44 extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode);
45 extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
46  size_t *inbytesleft, char* * outbuf,
47  size_t *outbytesleft);
48 extern int _System os2_iconv_close(iconv_t cd);
49 
50 /* Functions pointers types */
51 typedef iconv_t _System (*FNICONV_OPEN)(const char* tocode, const char* fromcode);
52 typedef size_t _System (*FNICONV)(iconv_t cd, char* * inbuf,
53  size_t *inbytesleft, char* * outbuf,
54  size_t *outbytesleft);
55 typedef int _System (*FNICONV_CLOSE)(iconv_t cd);
56 
57 /* Used DLL module handle */
58 static HMODULE hmIconv = NULLHANDLE;
59 /* Functions pointers */
63 
64 
65 static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv,
66  PSZ pszIconvClose)
67 {
68  ULONG ulRC;
69  CHAR acError[256];
70 
71  ulRC = DosLoadModule(acError, sizeof(acError), pszName, &hmIconv);
72  if (ulRC != NO_ERROR) {
73  debug("DLL not loaded: %s", &acError);
74  return FALSE;
75  }
76 
77  do {
78  ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvOpen, (PFN *)&fn_iconv_open);
79  if (ulRC != NO_ERROR) {
80  debug("Error: cannot find entry %s in %s", pszIconvOpen, pszName);
81  break;
82  }
83 
84  ulRC = DosQueryProcAddr(hmIconv, 0, pszIconv, (PFN *)&fn_iconv);
85  if (ulRC != NO_ERROR) {
86  debug("Error: cannot find entry %s in %s", pszIconv, pszName);
87  break;
88  }
89 
90  ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvClose, (PFN *)&fn_iconv_close);
91  if (ulRC != NO_ERROR) {
92  debug("Error: cannot find entry %s in %s", pszIconvClose, pszName);
93  break;
94  }
95 
96  debug("DLL %s used", pszName);
97  return TRUE;
98  } while (FALSE);
99 
100  DosFreeModule(hmIconv);
101  hmIconv = NULLHANDLE;
102  return FALSE;
103 }
104 
105 static void _init(void)
106 {
107  if (fn_iconv_open != NULL) /* Already was initialized */
108  return;
109 
110  /* Try to load kiconv.dll, iconv2.dll or iconv.dll */
111  if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") &&
112  !_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") &&
113  !_loadDLL("ICONV", "_iconv_open", "_iconv", "_iconv_close") ) {
114  /* No DLL was loaded - use OS/2 conversion objects API */
115  debug("Uni*() API used");
119  }
120 }
121 
122 
123 /* Public routines.
124  * ----------------
125  */
126 
127 /* Non-standard function for iconv to unload the used dynamic library */
128 void libiconv_clean(void)
129 {
130  if (hmIconv != NULLHANDLE) {
131  DosFreeModule(hmIconv);
132  hmIconv = NULLHANDLE;
133 
135  fn_iconv = NULL;
137  }
138 }
139 
140 iconv_t libiconv_open(const char* tocode, const char* fromcode)
141 {
142  _init();
143  return fn_iconv_open(tocode, fromcode);
144 }
145 
146 size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft,
147  char* * outbuf, size_t *outbytesleft)
148 {
149  return fn_iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);
150 }
151 
153 {
154  return fn_iconv_close(cd);
155 }
156 
157 /* vi: set ts=4 sw=4 expandtab: */
#define NULL
Definition: begin_code.h:163
#define TRUE
Definition: edid-parse.c:33
#define FALSE
Definition: edid-parse.c:34
int _System os2_iconv_close(iconv_t cd)
Definition: os2iconv.c:250
static FNICONV_CLOSE fn_iconv_close
Definition: geniconv.c:62
static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv, PSZ pszIconvClose)
Definition: geniconv.c:65
int libiconv_close(iconv_t cd)
Definition: geniconv.c:152
static void _init(void)
Definition: geniconv.c:105
iconv_t libiconv_open(const char *tocode, const char *fromcode)
Definition: geniconv.c:140
static HMODULE hmIconv
Definition: geniconv.c:58
#define debug(s,...)
Definition: geniconv.c:40
static FNICONV fn_iconv
Definition: geniconv.c:61
iconv_t _System os2_iconv_open(const char *tocode, const char *fromcode)
Definition: os2iconv.c:103
iconv_t _System(* FNICONV_OPEN)(const char *tocode, const char *fromcode)
Definition: geniconv.c:51
int _System(* FNICONV_CLOSE)(iconv_t cd)
Definition: geniconv.c:55
void libiconv_clean(void)
Definition: geniconv.c:128
size_t libiconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: geniconv.c:146
size_t _System os2_iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: os2iconv.c:146
size_t _System(* FNICONV)(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: geniconv.c:52
static FNICONV_OPEN fn_iconv_open
Definition: geniconv.c:60
void * iconv_t
Definition: iconv.h:7