1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#ifndef CORE_FXCRT_FX_SYSTEM_H_
8#define CORE_FXCRT_FX_SYSTEM_H_
9
10#include <assert.h>
11#include <math.h>
12#include <stdarg.h>
13#include <stddef.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <wchar.h>
19
20// _FX_OS_ values:
21#define _FX_OS_WIN32_ 1
22#define _FX_OS_WIN64_ 2
23#define _FX_OS_LINUX_ 4
24#define _FX_OS_MACOSX_ 7
25#define _FX_OS_ANDROID_ 12
26#define _FX_OS_WASM_ 13
27
28// _FX_PLATFORM_ values;
29#define _FX_PLATFORM_WINDOWS_ 1  // _FX_OS_WIN32_ or _FX_OS_WIN64_.
30#define _FX_PLATFORM_LINUX_ 2    // _FX_OS_LINUX_ or _FX_OS_WASM_.
31#define _FX_PLATFORM_APPLE_ 3    // _FX_OS_MACOSX_ always.
32#define _FX_PLATFORM_ANDROID_ 4  // _FX_OS_ANDROID_ always.
33
34#ifndef _FX_OS_
35#if defined(__ANDROID__)
36#define _FX_OS_ _FX_OS_ANDROID_
37#define _FX_PLATFORM_ _FX_PLATFORM_ANDROID_
38#elif defined(_WIN32)
39#define _FX_OS_ _FX_OS_WIN32_
40#define _FX_PLATFORM_ _FX_PLATFORM_WINDOWS_
41#elif defined(_WIN64)
42#define _FX_OS_ _FX_OS_WIN64_
43#define _FX_PLATFORM_ _FX_PLATFORM_WINDOWS_
44#elif defined(__linux__)
45#define _FX_OS_ _FX_OS_LINUX_
46#define _FX_PLATFORM_ _FX_PLATFORM_LINUX_
47#elif defined(__APPLE__)
48#define _FX_OS_ _FX_OS_MACOSX_
49#define _FX_PLATFORM_ _FX_PLATFORM_APPLE_
50#elif defined(__asmjs__) || defined(__wasm__)
51#define _FX_OS_ _FX_OS_WASM_
52#define _FX_PLATFORM_ _FX_PLATFORM_LINUX_
53#endif
54#endif  // _FX_OS_
55
56#if !defined(_FX_OS_) || _FX_OS_ == 0
57#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro.
58#endif
59
60#if defined(_MSC_VER) && _MSC_VER < 1900
61#error Sorry, VC++ 2015 or later is required to compile PDFium.
62#endif  // defined(_MSC_VER) && _MSC_VER < 1900
63
64#if _FX_OS_ == _FX_OS_WASM_ && defined(PDF_ENABLE_V8)
65#error Cannot compile v8 with wasm.
66#endif  // PDF_ENABLE_V8
67
68#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
69#include <windows.h>
70#include <sal.h>
71#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
72
73#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
74#include <Carbon/Carbon.h>
75#include <libkern/OSAtomic.h>
76#endif  // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
77
78#ifdef __cplusplus
79extern "C" {
80#endif  // __cplusplus
81
82#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
83#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
84#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
85#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
86
87// PDFium file sizes match the platform, but PDFium itself does not support
88// files larger than 2GB even if the platform does. The value must be signed
89// to support -1 error returns.
90// TODO(tsepez): support larger files.
91#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
92#define FX_FILESIZE int32_t
93#else  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
94#define FX_FILESIZE off_t
95#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
96
97#ifndef ASSERT
98#ifndef NDEBUG
99#define ASSERT assert
100#else
101#define ASSERT(a)
102#endif  // NDEBUG
103#endif  // ASSERT
104
105#if defined(__clang__) || defined(__GNUC__)
106#define PDFIUM_IMMEDIATE_CRASH() __builtin_trap()
107#else
108#define PDFIUM_IMMEDIATE_CRASH() ((void)(*(volatile char*)0 = 0))
109#endif  // defined(__clang__) || defined(__GNUC__)
110
111// M_PI not universally present on all platforms.
112#define FX_PI 3.1415926535897932384626433832795f
113#define FX_BEZIER 0.5522847498308f
114
115// NOTE: prevent use of the return value from snprintf() since some platforms
116// have different return values.
117#define FXSYS_snprintf (void)snprintf
118#define FXSYS_vsnprintf (void)vsnprintf
119#define FXSYS_sprintf DO_NOT_USE_SPRINTF_DIE_DIE_DIE
120#define FXSYS_vsprintf DO_NOT_USE_VSPRINTF_DIE_DIE_DIE
121
122#ifdef __cplusplus
123}  // extern "C"
124
125#include "third_party/base/numerics/safe_conversions.h"
126
127// Overloaded functions for C++ templates
128inline size_t FXSYS_len(const char* ptr) {
129  return strlen(ptr);
130}
131
132inline size_t FXSYS_len(const wchar_t* ptr) {
133  return wcslen(ptr);
134}
135
136inline int FXSYS_cmp(const char* ptr1, const char* ptr2, size_t len) {
137  return memcmp(ptr1, ptr2, len);
138}
139
140inline int FXSYS_cmp(const wchar_t* ptr1, const wchar_t* ptr2, size_t len) {
141  return wmemcmp(ptr1, ptr2, len);
142}
143
144inline const char* FXSYS_chr(const char* ptr, char ch, size_t len) {
145  return reinterpret_cast<const char*>(memchr(ptr, ch, len));
146}
147
148inline const wchar_t* FXSYS_chr(const wchar_t* ptr, wchar_t ch, size_t len) {
149  return wmemchr(ptr, ch, len);
150}
151
152extern "C" {
153#endif  // __cplusplus
154
155#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
156#define FXSYS_GetACP GetACP
157#define FXSYS_itoa _itoa
158#define FXSYS_strlwr _strlwr
159#define FXSYS_strupr _strupr
160#define FXSYS_stricmp _stricmp
161#define FXSYS_pow(a, b) (float)powf(a, b)
162size_t FXSYS_wcsftime(wchar_t* strDest,
163                      size_t maxsize,
164                      const wchar_t* format,
165                      const struct tm* timeptr);
166#ifdef _NATIVE_WCHAR_T_DEFINED
167#define FXSYS_wcsicmp(str1, str2) _wcsicmp((wchar_t*)(str1), (wchar_t*)(str2))
168#define FXSYS_WideCharToMultiByte(p1, p2, p3, p4, p5, p6, p7, p8) \
169  WideCharToMultiByte(p1, p2, (const wchar_t*)(p3), p4, p5, p6, p7, p8)
170#define FXSYS_MultiByteToWideChar(p1, p2, p3, p4, p5, p6) \
171  MultiByteToWideChar(p1, p2, p3, p4, (wchar_t*)(p5), p6)
172#define FXSYS_wcslwr(str) _wcslwr((wchar_t*)(str))
173#define FXSYS_wcsupr(str) _wcsupr((wchar_t*)(str))
174#else  // _NATIVE_WCHAR_T_DEFINED
175#define FXSYS_wcsicmp _wcsicmp
176#define FXSYS_WideCharToMultiByte WideCharToMultiByte
177#define FXSYS_MultiByteToWideChar MultiByteToWideChar
178#define FXSYS_wcslwr _wcslwr
179#define FXSYS_wcsupr _wcsupr
180#endif  // _NATIVE_WCHAR_T_DEFINED
181
182#else  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
183
184int FXSYS_GetACP();
185char* FXSYS_itoa(int value, char* str, int radix);
186int FXSYS_WideCharToMultiByte(uint32_t codepage,
187                              uint32_t dwFlags,
188                              const wchar_t* wstr,
189                              int wlen,
190                              char* buf,
191                              int buflen,
192                              const char* default_str,
193                              int* pUseDefault);
194int FXSYS_MultiByteToWideChar(uint32_t codepage,
195                              uint32_t dwFlags,
196                              const char* bstr,
197                              int blen,
198                              wchar_t* buf,
199                              int buflen);
200char* FXSYS_strlwr(char* str);
201char* FXSYS_strupr(char* str);
202int FXSYS_stricmp(const char*, const char*);
203int FXSYS_wcsicmp(const wchar_t* str1, const wchar_t* str2);
204wchar_t* FXSYS_wcslwr(wchar_t* str);
205wchar_t* FXSYS_wcsupr(wchar_t* str);
206#define FXSYS_pow(a, b) (float)pow(a, b)
207#define FXSYS_wcsftime wcsftime
208#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
209
210#define FXWORD_GET_LSBFIRST(p)                                \
211  (static_cast<uint16_t>((static_cast<uint16_t>(p[1]) << 8) | \
212                         (static_cast<uint16_t>(p[0]))))
213#define FXWORD_GET_MSBFIRST(p)                                \
214  (static_cast<uint16_t>((static_cast<uint16_t>(p[0]) << 8) | \
215                         (static_cast<uint16_t>(p[1]))))
216#define FXDWORD_GET_LSBFIRST(p)                                                \
217  ((static_cast<uint32_t>(p[3]) << 24) | (static_cast<uint32_t>(p[2]) << 16) | \
218   (static_cast<uint32_t>(p[1]) << 8) | (static_cast<uint32_t>(p[0])))
219#define FXDWORD_GET_MSBFIRST(p)                                                \
220  ((static_cast<uint32_t>(p[0]) << 24) | (static_cast<uint32_t>(p[1]) << 16) | \
221   (static_cast<uint32_t>(p[2]) << 8) | (static_cast<uint32_t>(p[3])))
222int32_t FXSYS_atoi(const char* str);
223uint32_t FXSYS_atoui(const char* str);
224int32_t FXSYS_wtoi(const wchar_t* str);
225int64_t FXSYS_atoi64(const char* str);
226const char* FXSYS_i64toa(int64_t value, char* str, int radix);
227int FXSYS_round(float f);
228#define FXSYS_sqrt2(a, b) (float)sqrt((a) * (a) + (b) * (b))
229#ifdef __cplusplus
230}  // extern C
231#endif  // __cplusplus
232
233// To print a size_t value in a portable way:
234//   size_t size;
235//   printf("xyz: %" PRIuS, size);
236// The "u" in the macro corresponds to %u, and S is for "size".
237#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
238
239#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64)
240#error "inttypes.h has already been included before this header file, but "
241#error "without __STDC_FORMAT_MACROS defined."
242#endif
243
244#if !defined(__STDC_FORMAT_MACROS)
245#define __STDC_FORMAT_MACROS
246#endif
247
248#include <inttypes.h>
249
250#if !defined(PRIuS)
251#define PRIuS "zu"
252#endif
253
254#else  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
255
256#if !defined(PRIuS)
257#define PRIuS "Iu"
258#endif
259
260#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
261
262// Prevent a function from ever being inlined, typically because we'd
263// like it to appear in stack traces.
264#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
265#define NEVER_INLINE __declspec(noinline)
266#else  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
267#define NEVER_INLINE __attribute__((__noinline__))
268#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
269
270#endif  // CORE_FXCRT_FX_SYSTEM_H_
271