• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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 #include "core/fxcrt/fx_extension.h"
8 
9 #include <wchar.h>
10 
11 #include "core/fxcrt/check.h"
12 #include "core/fxcrt/compiler_specific.h"
13 #include "core/fxcrt/fx_system.h"
14 #include "core/fxcrt/utf16.h"
15 #include "core/fxcrt/widestring.h"
16 
17 namespace {
18 
DefaultTimeFunction()19 time_t DefaultTimeFunction() {
20   return time(nullptr);
21 }
22 
DefaultLocaltimeFunction(const time_t * tp)23 struct tm* DefaultLocaltimeFunction(const time_t* tp) {
24   return localtime(tp);
25 }
26 
27 time_t (*g_time_func)() = DefaultTimeFunction;
28 struct tm* (*g_localtime_func)(const time_t*) = DefaultLocaltimeFunction;
29 
30 }  // namespace
31 
FXSYS_wcstof(WideStringView pwsStr,size_t * pUsedLen)32 float FXSYS_wcstof(WideStringView pwsStr, size_t* pUsedLen) {
33   // Force NUL-termination via copied buffer.
34   auto copied = WideString(pwsStr);
35   wchar_t* endptr = nullptr;
36   float result = wcstof(copied.c_str(), &endptr);
37   if (result != result) {
38     result = 0.0f;  // Convert NAN to 0.0f;
39   }
40   if (pUsedLen) {
41     *pUsedLen = endptr - copied.c_str();
42   }
43   return result;
44 }
45 
FXSYS_wcsncpy(wchar_t * dstStr,const wchar_t * srcStr,size_t count)46 wchar_t* FXSYS_wcsncpy(wchar_t* dstStr, const wchar_t* srcStr, size_t count) {
47   DCHECK(dstStr);
48   DCHECK(srcStr);
49   DCHECK(count > 0);
50 
51   // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE in header.
52   UNSAFE_BUFFERS({
53     for (size_t i = 0; i < count; ++i) {
54       dstStr[i] = srcStr[i];
55       if (dstStr[i] == L'\0') {
56         break;
57       }
58     }
59   });
60   return dstStr;
61 }
62 
63 // TODO(tsepez): should be UNSAFE_BUFFER_USAGE.
FXSYS_IntToTwoHexChars(uint8_t n,char * buf)64 void FXSYS_IntToTwoHexChars(uint8_t n, char* buf) {
65   static const char kHex[] = "0123456789ABCDEF";
66   // SAFETY: range of uint8_t keeps indices in bound.
67   UNSAFE_BUFFERS({
68     buf[0] = kHex[n / 16];
69     buf[1] = kHex[n % 16];
70   });
71 }
72 
73 // TODO(tsepez): This is UNSAFE_BUFFER_USAGE as well.
FXSYS_IntToFourHexChars(uint16_t n,char * buf)74 void FXSYS_IntToFourHexChars(uint16_t n, char* buf) {
75   // SAFETY: required from caller.
76   UNSAFE_BUFFERS({
77     FXSYS_IntToTwoHexChars(n / 256, buf);
78     FXSYS_IntToTwoHexChars(n % 256, buf + 2);
79   });
80 }
81 
82 // TODO(tsepez): This is UNSAFE_BUFFER_USAGE as well.
FXSYS_ToUTF16BE(uint32_t unicode,char * buf)83 size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf) {
84   DCHECK(unicode <= pdfium::kMaximumSupplementaryCodePoint);
85   DCHECK(!pdfium::IsHighSurrogate(unicode));
86   DCHECK(!pdfium::IsLowSurrogate(unicode));
87 
88   if (unicode <= 0xFFFF) {
89     FXSYS_IntToFourHexChars(unicode, buf);
90     return 4;
91   }
92   // SAFETY: required from caller.
93   UNSAFE_BUFFERS({
94     pdfium::SurrogatePair surrogate_pair(unicode);
95     FXSYS_IntToFourHexChars(surrogate_pair.high(), buf);
96     FXSYS_IntToFourHexChars(surrogate_pair.low(), buf + 4);
97   });
98   return 8;
99 }
100 
FXSYS_SetTimeFunction(time_t (* func)())101 void FXSYS_SetTimeFunction(time_t (*func)()) {
102   g_time_func = func ? func : DefaultTimeFunction;
103 }
104 
FXSYS_SetLocaltimeFunction(struct tm * (* func)(const time_t *))105 void FXSYS_SetLocaltimeFunction(struct tm* (*func)(const time_t*)) {
106   g_localtime_func = func ? func : DefaultLocaltimeFunction;
107 }
108 
FXSYS_time(time_t * tloc)109 time_t FXSYS_time(time_t* tloc) {
110   time_t ret_val = g_time_func();
111   if (tloc)
112     *tloc = ret_val;
113   return ret_val;
114 }
115 
FXSYS_localtime(const time_t * tp)116 struct tm* FXSYS_localtime(const time_t* tp) {
117   return g_localtime_func(tp);
118 }
119