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
80inline void *CoreClrAlloc(size_t cb)
81{
82#ifdef _WIN32
83 return ::CoTaskMemAlloc(cb);
84#else
85 return ::malloc(cb);
86#endif
87}
88
89inline void CoreClrFree(void *p)
90{
91#ifdef _WIN32
92 return ::CoTaskMemFree(p);
93#else
94 return ::free(p);
95#endif
96}
97
98inline 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
113inline 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
123class IUnknown
124{
125public:
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
132size_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
139size_t strcpy_s(char *dest, size_t n, char const *src)
140{
141 return snprintf(dest, n, "%s", src);
142}
143
144#ifndef wcslen
145size_t wcslen(const WCHAR *str)
146{
147 size_t len = 0;
148 while ('\0' != *(str + len)) len++;
149 return len;
150}
151#endif
152
153int 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
169int wcsncpy_s(LPWSTR strDestination, size_t size1, LPCWSTR strSource)
170{
171 return wcsncpy_s(strDestination, size1, strSource, 0);
172}
173
174int 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
196int wmemcmp(LPCWSTR str1, LPCWSTR str2,size_t len)
197{
198 return wcsncmp(str1, str2, len);
199}
200
201#define DECIMAL_NEG ((BYTE)0x80)
202#define DECIMAL_SCALE(dec) ((dec).u.u.scale)
203#define DECIMAL_SIGN(dec) ((dec).u.u.sign)
204#define DECIMAL_SIGNSCALE(dec) ((dec).u.signscale)
205#define DECIMAL_LO32(dec) ((dec).v.v.Lo32)
206#define DECIMAL_MID32(dec) ((dec).v.v.Mid32)
207#define DECIMAL_HI32(dec) ((dec).Hi32)
208#define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
209#define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
210
211#define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
212
213#endif //!_Win32
214
215#endif // __XPLAT_H__
216