FreeRDP
Loading...
Searching...
No Matches
unicode_apple.m
1
21#import <Foundation/Foundation.h>
22
23#include <winpr/config.h>
24#include <winpr/assert.h>
25
26#include <errno.h>
27#include <wctype.h>
28
29#include <winpr/crt.h>
30#include <winpr/error.h>
31#include <winpr/print.h>
32
33#include "unicode.h"
34
35#ifndef MIN
36#define MIN(a, b) (a) < (b) ? (a) : (b)
37#endif
38
39#include "../log.h"
40#define TAG WINPR_TAG("unicode")
41
42int int_MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte,
43 LPWSTR lpWideCharStr, int cchWideChar)
44{
45 const BOOL isNullTerminated = cbMultiByte < 0;
46
47 /* If cbMultiByte is 0, the function fails */
48 if ((cbMultiByte == 0) || (cbMultiByte < -1))
49 return 0;
50
51 /* If cbMultiByte is -1, the string is null-terminated */
52 if (isNullTerminated)
53 {
54 size_t len = strnlen(lpMultiByteStr, INT32_MAX);
55 if (len >= INT32_MAX)
56 return 0;
57 cbMultiByte = (int)len + 1;
58 }
59
60 NSString *utf = [[NSString alloc] initWithBytes:lpMultiByteStr
61 length:cbMultiByte
62 encoding:NSUTF8StringEncoding];
63 if (!utf)
64 {
65 WLog_WARN(TAG, "[NSString alloc] NSUTF8StringEncoding failed [%d] '%s'", cbMultiByte,
66 lpMultiByteStr);
67 return -1;
68 }
69
70 const WCHAR *utf16 =
71 (const WCHAR *)[utf cStringUsingEncoding:NSUTF16LittleEndianStringEncoding];
72 const size_t utf16ByteLen = [utf lengthOfBytesUsingEncoding:NSUTF16LittleEndianStringEncoding];
73 const size_t utf16CharLen = utf16ByteLen / sizeof(WCHAR);
74 if (!utf16)
75 {
76 WLog_WARN(TAG, "[utf cStringUsingEncoding:NSUTF16LittleEndianStringEncoding] failed");
77 return -1;
78 }
79
80 if (cchWideChar == 0)
81 return utf16CharLen;
82 else if (cchWideChar < utf16CharLen)
83 {
84 SetLastError(ERROR_INSUFFICIENT_BUFFER);
85 return 0;
86 }
87 else
88 {
89 const size_t mlen = MIN((size_t)utf16CharLen, cchWideChar);
90 const size_t len = _wcsnlen(utf16, mlen);
91 memcpy(lpWideCharStr, utf16, len * sizeof(WCHAR));
92 if ((len < (size_t)cchWideChar) &&
93 ((len == 0) || ((len > 0) && (lpWideCharStr[len - 1] != '\0'))))
94 lpWideCharStr[len] = '\0';
95 return utf16CharLen;
96 }
97}
98
99int int_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
100 LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
101 LPBOOL lpUsedDefaultChar)
102{
103 const BOOL isNullTerminated = cchWideChar < 0;
104
105 /* If cchWideChar is 0, the function fails */
106 if ((cchWideChar == 0) || (cchWideChar < -1))
107 return 0;
108
109 /* If cchWideChar is -1, the string is null-terminated */
110 if (isNullTerminated)
111 {
112 size_t len = _wcslen(lpWideCharStr);
113 if (len >= INT32_MAX)
114 return 0;
115 cchWideChar = (int)len + 1;
116 }
117
118 NSString *utf = [[NSString alloc] initWithCharacters:lpWideCharStr length:cchWideChar];
119 if (!utf)
120 {
121 WLog_WARN(TAG, "[NSString alloc] initWithCharacters failed [%d] 'XXX'", cchWideChar);
122 return -1;
123 }
124
125 const char *utf8 = [utf cStringUsingEncoding:NSUTF8StringEncoding];
126 const size_t utf8Len = [utf lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
127 if (!utf8)
128 {
129 WLog_WARN(TAG, "[utf cStringUsingEncoding:NSUTF8StringEncoding] failed");
130 return -1;
131 }
132
133 if (cbMultiByte == 0)
134 return utf8Len;
135 else if (cbMultiByte < utf8Len)
136 {
137 SetLastError(ERROR_INSUFFICIENT_BUFFER);
138 return 0;
139 }
140 else
141 {
142 const size_t mlen = MIN((size_t)cbMultiByte, utf8Len);
143 const size_t len = strnlen(utf8, mlen);
144 memcpy(lpMultiByteStr, utf8, len * sizeof(char));
145 if ((len < (size_t)cbMultiByte) && (len > 0) && (lpMultiByteStr[len - 1] != '\0'))
146 lpMultiByteStr[len] = '\0';
147 return utf8Len;
148 }
149}