Add tests for ANSI BSTRs (#20985)
[platform/upstream/coreclr.git] / tests / src / Interop / common / xplatform.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 #ifndef __XPLAT_H__
6 #define __XPLAT_H__
7
8 #ifdef _MSC_VER
9 // Our tests don't care about secure CRT
10 #define _CRT_SECURE_NO_WARNINGS 1
11 #endif
12
13 // Ensure that both UNICODE and _UNICODE are set.
14 #ifndef _UNICODE
15 #define _UNICODE
16 #endif
17 #ifndef UNICODE
18 #define UNICODE
19 #endif
20
21 // common headers
22 #include <stdio.h>
23 #include <memory.h>
24 #include <stdlib.h>
25
26 // This macro is used to standardize the wide character string literals between UNIX and Windows.
27 // Unix L"" is UTF32, and on windows it's UTF16.  Because of built-in assumptions on the size
28 // of string literals, it's important to match behaviour between Unix and Windows.  Unix will be defined
29 // as u"" (char16_t)
30 #ifdef _WIN32
31 #define W(str)  L##str
32 #else // !_WIN32
33 #define W(str)  u##str
34 #endif //_WIN32
35
36
37 //  include 
38 #ifdef _WIN32
39     #define NOMINMAX
40     #include <windows.h>
41     #include <combaseapi.h>
42
43     #ifndef snprintf
44     #define snprintf _snprintf
45     #endif //snprintf
46
47 #else
48     #include "types.h"
49 #endif
50 #include <wchar.h>
51
52 // dllexport
53 #if defined _WIN32
54 #define DLL_EXPORT __declspec(dllexport)
55
56 #else //!_Win32
57
58 #if __GNUC__ >= 4
59 #define DLL_EXPORT __attribute__ ((visibility ("default")))
60 #else
61 #define DLL_EXPORT
62 #endif
63
64 #endif //_WIN32
65
66 // Calling conventions
67 #ifndef _WIN32
68
69 #define STDMETHODCALLTYPE
70
71 #if __i386__
72 #define __stdcall __attribute__((stdcall))
73 #define __cdecl __attribute__((cdecl))
74 #else
75 #define __stdcall
76 #define __cdecl
77 #endif
78 #endif //!_WIN32
79
80 inline void *CoreClrAlloc(size_t cb)
81 {
82 #ifdef _WIN32
83     return ::CoTaskMemAlloc(cb);
84 #else
85     return ::malloc(cb);
86 #endif
87 }
88
89 inline void CoreClrFree(void *p)
90 {
91 #ifdef _WIN32
92     return ::CoTaskMemFree(p);
93 #else
94     return ::free(p);
95 #endif
96 }
97
98 inline void *CoreClrBstrAlloc(size_t cb)
99 {
100 #ifdef _WIN32
101     // A null is automatically applied in the SysAllocStringByteLen API.
102     // Remove a single OLECHAR for the implied null.
103     // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/oleauto/nf-oleauto-sysallocstringbytelen
104     if (cb >= sizeof(OLECHAR))
105         cb -= sizeof(OLECHAR);
106
107     return ::SysAllocStringByteLen(nullptr, static_cast<UINT>(cb));
108 #else
109     return nullptr;
110 #endif
111 }
112
113 inline void CoreClrBstrFree(void *p)
114 {
115 #ifdef _WIN32
116     return ::SysFreeString((BSTR)p);
117 #endif
118 }
119
120 // redirected types not-windows only
121 #ifndef  _WIN32
122
123 class IUnknown
124 {
125 public:
126     virtual int QueryInterface(void* riid,void** ppvObject) = 0;
127     virtual unsigned long AddRef() = 0;
128     virtual unsigned long Release() = 0;
129 };
130
131 // function implementation
132 size_t strncpy_s(char* strDest, size_t numberOfElements, const char *strSource, size_t count)
133 {
134     // NOTE: Need to pass count + 1 since strncpy_s does not count null,
135     // while snprintf does. 
136     return snprintf(strDest, count + 1, "%s", strSource);
137 }
138
139 size_t strcpy_s(char *dest, size_t n, char const *src)
140 {
141     return snprintf(dest, n, "%s", src);
142 }
143
144 #ifndef wcslen
145 size_t wcslen(const WCHAR *str)
146 {
147     size_t len = 0;
148     while ('\0' != *(str + len)) len++;
149     return len;
150 }
151 #endif
152
153 int wcsncpy_s(LPWSTR strDestination, size_t size1, LPCWSTR strSource, size_t size2)
154 {
155     // copy sizeInBytes bytes of strSource into strDestination
156     if (NULL == strDestination || NULL == strSource) return 1;
157
158     int cnt = 0;
159     while (cnt < size1 && '\0' != strSource[cnt])
160     {
161         strDestination[cnt] = strSource[cnt];
162         cnt++;
163     }
164
165     strDestination[cnt] = '\0';
166     return 0;
167 }
168
169 int wcsncpy_s(LPWSTR strDestination, size_t size1, LPCWSTR strSource)
170 {
171     return wcsncpy_s(strDestination, size1, strSource, 0);
172 }
173
174 int wcsncmp(LPCWSTR str1, LPCWSTR str2,size_t len)
175 {
176     // < 0 str1 less than str2
177     // 0  str1 identical to str2
178     // > 0 str1 greater than str2
179     if (NULL == str1 && NULL != str2) return -1;
180     if (NULL != str1 && NULL == str2) return 1;
181     if (NULL == str1 && NULL == str2) return 0;
182
183     while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2 && len--!= 0)
184     {
185         str1++;
186         str2++;
187     }
188
189     if ('\0' == *str1 && '\0' == *str2) return 0;
190     if ('\0' != *str1) return -1;
191     if ('\0' != *str2) return 1;
192
193     return (*str1 > *str2) ? 1 : -1;
194 }
195
196 int wmemcmp(LPCWSTR str1, LPCWSTR str2,size_t len)
197 {
198     return wcsncmp(str1, str2, len);
199 }
200
201 #endif //!_Win32
202
203 #endif // __XPLAT_H__