VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/utf8-posix.cpp@ 1

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.9 KB
Line 
1/* $Id: utf8-posix.cpp 1 1970-01-01 00:00:00Z vboxsync $ */
2/** @file
3 * InnoTek Portable Runtime - UTF-8 helpers, POSIX.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <iprt/string.h>
27#include <iprt/alloc.h>
28#include <iprt/assert.h>
29#include <iprt/err.h>
30#include <iprt/string.h>
31
32#include <errno.h>
33#include <locale.h>
34#include <iconv.h>
35#include <wctype.h>
36
37
38/*******************************************************************************
39* Internal Functions *
40*******************************************************************************/
41static int rtstrConvert(const void *pvInput, size_t cbInput, const char *pszInputCS, void **ppvOutput, size_t cbOutput, const char *pszOutputCS, unsigned cFactor);
42
43
44/**
45 * Converts a string from one charset to another.
46 *
47 * @returns iprt status code.
48 * @param pvInput Pointer to intput string.
49 * @param cbInput Size (in bytes) of input string. Excludes any terminators.
50 * @param pszInputCS Codeset of the input string.
51 * @param ppvOutput Pointer to pointer to output buffer if cbOutput > 0.
52 * If cbOutput is 0 this is where the pointer to the allocated
53 * buffer is stored.
54 * @param cbOutput Size of the passed in buffer.
55 * @param pszOutputCS Codeset of the input string.
56 * @param cFactor Input vs. output size factor.
57 */
58static int rtstrConvert(const void *pvInput, size_t cbInput, const char *pszInputCS, void **ppvOutput, size_t cbOutput, const char *pszOutputCS, unsigned cFactor)
59{
60 /*
61 * Allocate buffer
62 */
63 void *pvOutput;
64 size_t cbOutput2;
65 if (!cbOutput)
66 {
67 cbOutput2 = cbInput * cFactor;
68 pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUCS2));
69 if (!pvOutput)
70 return VERR_NO_TMP_MEMORY;
71 }
72 else
73 {
74 pvOutput = *ppvOutput;
75 cbOutput2 = cbOutput - (!strcmp(pszOutputCS, "UCS-2") ? sizeof(RTUCS2) : 1);
76 if (cbOutput2 > cbOutput)
77 return VERR_BUFFER_OVERFLOW;
78 }
79
80 /*
81 * Use a loop here to retry with bigger buffers.
82 */
83 for (unsigned cTries = 10; cTries > 0; cTries--)
84 {
85 /*
86 * Create conversion object.
87 */
88 iconv_t icHandle = iconv_open(pszOutputCS, pszInputCS);
89 if (icHandle != (iconv_t)-1)
90 {
91 /*
92 * Do the conversion.
93 */
94 size_t cbInLeft = cbInput;
95 size_t cbOutLeft = cbOutput2;
96 const void *pvInputLeft = pvInput;
97 void *pvOutputLeft = pvOutput;
98#ifdef __LINUX__ /* glibc has an incorrect declaration of the api. */
99 if (iconv(icHandle, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1)
100#else
101 if (iconv(icHandle, (const char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1)
102#endif
103 {
104 if (!cbInLeft)
105 {
106 /*
107 * We're done, just add the terminator and return.
108 * (Two terminators to support UCS-2 output, too.)
109 */
110 iconv_close(icHandle);
111 if (!cbOutput || !strcmp(pszOutputCS, "UCS-2"))
112 *(PRTUCS2)pvOutputLeft = '\0';
113 else
114 *(char *)pvOutputLeft = '\0';
115 *ppvOutput = pvOutput;
116 return VINF_SUCCESS;
117 }
118 else
119 errno = E2BIG;
120 }
121 iconv_close(icHandle);
122
123 /*
124 * If we failed because of output buffer space we'll
125 * increase the output buffer size and retry.
126 */
127 if (errno == E2BIG)
128 {
129 if (!cbOutput)
130 {
131 RTMemTmpFree(pvOutput);
132 cbOutput2 *= 2;
133 pvOutput = RTMemTmpAlloc(cbOutput2);
134 if (!pvOutput)
135 return VERR_NO_TMP_MEMORY;
136 continue;
137 }
138 return VERR_BUFFER_OVERFLOW;
139 }
140 }
141 break;
142 }
143
144 /* failure */
145 if (!cbOutput)
146 RTMemTmpFree(pvOutput);
147 return VERR_NO_TRANSLATION;
148}
149
150
151/**
152 * Allocates tmp buffer, translates pszString from UTF8 to current codepage.
153 *
154 * @returns iprt status code.
155 * @param ppszString Receives pointer of allocated native CP string.
156 * The returned pointer must be freed using RTStrFree().
157 * @param pszString UTF-8 string to convert.
158 */
159RTR3DECL(int) RTStrUtf8ToCurrentCP(char **ppszString, const char *pszString)
160{
161 Assert(ppszString);
162 Assert(pszString);
163 *ppszString = NULL;
164
165 /*
166 * Assume result string length is not longer than UTF-8 string.
167 */
168 size_t cch = strlen(pszString);
169 if (cch <= 0)
170 {
171 /* zero length string passed. */
172 *ppszString = (char *)RTMemTmpAllocZ(sizeof(char));
173 if (*ppszString)
174 return VINF_SUCCESS;
175 return VERR_NO_TMP_MEMORY;
176 }
177 return rtstrConvert(pszString, cch, "UTF-8", (void **)ppszString, 0, "", 1);
178}
179
180
181/**
182 * Allocates tmp buffer, translates pszString from current codepage to UTF-8.
183 *
184 * @returns iprt status code.
185 * @param ppszString Receives pointer of allocated UTF-8 string.
186 * The returned pointer must be freed using RTStrFree().
187 * @param pszString Native string to convert.
188 */
189RTR3DECL(int) RTStrCurrentCPToUtf8(char **ppszString, const char *pszString)
190{
191 Assert(ppszString);
192 Assert(pszString);
193 *ppszString = NULL;
194
195 /*
196 * Attempt with UTF-8 length of 2x the native lenght.
197 */
198 size_t cch = strlen(pszString);
199 if (cch <= 0)
200 {
201 /* zero length string passed. */
202 *ppszString = (char *)RTMemTmpAllocZ(sizeof(char));
203 if (*ppszString)
204 return VINF_SUCCESS;
205 return VERR_NO_TMP_MEMORY;
206 }
207 return rtstrConvert(pszString, cch, "", (void **)ppszString, 0, "UTF-8", 2);
208}
209
210
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette