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 #include "core/fxcrt/fx_basic.h" 8 #include "core/fxcrt/fx_ext.h" 9 10 #include <algorithm> 11 #include <cctype> 12 #include <limits> 13 #include <memory> 14 15 bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { 16 if (strc.Find('.') != -1) { 17 FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData); 18 *pFloat = FX_atof(strc); 19 return false; 20 } 21 22 // Note, numbers in PDF are typically of the form 123, -123, etc. But, 23 // for things like the Permissions on the encryption hash the number is 24 // actually an unsigned value. We use a uint32_t so we can deal with the 25 // unsigned and then check for overflow if the user actually signed the value. 26 // The Permissions flag is listed in Table 3.20 PDF 1.7 spec. 27 pdfium::base::CheckedNumeric<uint32_t> integer = 0; 28 bool bNegative = false; 29 bool bSigned = false; 30 int cc = 0; 31 if (strc[0] == '+') { 32 cc++; 33 bSigned = true; 34 } else if (strc[0] == '-') { 35 bNegative = true; 36 bSigned = true; 37 cc++; 38 } 39 40 while (cc < strc.GetLength() && std::isdigit(strc[cc])) { 41 integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc)); 42 if (!integer.IsValid()) 43 break; 44 cc++; 45 } 46 47 // We have a sign, and the value was greater then a regular integer 48 // we've overflowed, reset to the default value. 49 if (bSigned) { 50 if (bNegative) { 51 if (integer.ValueOrDefault(0) > 52 static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) { 53 integer = 0; 54 } 55 } else if (integer.ValueOrDefault(0) > 56 static_cast<uint32_t>(std::numeric_limits<int>::max())) { 57 integer = 0; 58 } 59 } 60 61 // Switch back to the int space so we can flip to a negative if we need. 62 uint32_t uValue = integer.ValueOrDefault(0); 63 int32_t value = static_cast<int>(uValue); 64 if (bNegative) 65 value = -value; 66 67 int* pInt = static_cast<int*>(pData); 68 *pInt = value; 69 return true; 70 } 71 72 static const FX_FLOAT fraction_scales[] = { 73 0.1f, 0.01f, 0.001f, 0.0001f, 74 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 75 0.000000001f, 0.0000000001f, 0.00000000001f}; 76 77 int FXSYS_FractionalScaleCount() { 78 return FX_ArraySize(fraction_scales); 79 } 80 81 FX_FLOAT FXSYS_FractionalScale(size_t scale_factor, int value) { 82 return fraction_scales[scale_factor] * value; 83 } 84 85 FX_FLOAT FX_atof(const CFX_ByteStringC& strc) { 86 if (strc.IsEmpty()) 87 return 0.0; 88 89 int cc = 0; 90 bool bNegative = false; 91 int len = strc.GetLength(); 92 if (strc[0] == '+') { 93 cc++; 94 } else if (strc[0] == '-') { 95 bNegative = true; 96 cc++; 97 } 98 while (cc < len) { 99 if (strc[cc] != '+' && strc[cc] != '-') 100 break; 101 cc++; 102 } 103 FX_FLOAT value = 0; 104 while (cc < len) { 105 if (strc[cc] == '.') 106 break; 107 value = value * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc)); 108 cc++; 109 } 110 int scale = 0; 111 if (cc < len && strc[cc] == '.') { 112 cc++; 113 while (cc < len) { 114 value += 115 FXSYS_FractionalScale(scale, FXSYS_toDecimalDigit(strc.CharAt(cc))); 116 scale++; 117 if (scale == FXSYS_FractionalScaleCount()) 118 break; 119 cc++; 120 } 121 } 122 return bNegative ? -value : value; 123 } 124 125 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 126 void FXSYS_snprintf(char* str, 127 size_t size, 128 _Printf_format_string_ const char* fmt, 129 ...) { 130 va_list ap; 131 va_start(ap, fmt); 132 FXSYS_vsnprintf(str, size, fmt, ap); 133 va_end(ap); 134 } 135 136 void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap) { 137 (void)_vsnprintf(str, size, fmt, ap); 138 if (size) 139 str[size - 1] = 0; 140 } 141 #endif // _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 142 143 FX_FileHandle* FX_OpenFolder(const FX_CHAR* path) { 144 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 145 std::unique_ptr<CFindFileDataA> pData(new CFindFileDataA); 146 pData->m_Handle = FindFirstFileExA((CFX_ByteString(path) + "/*.*").c_str(), 147 FindExInfoStandard, &pData->m_FindData, 148 FindExSearchNameMatch, nullptr, 0); 149 if (pData->m_Handle == INVALID_HANDLE_VALUE) 150 return nullptr; 151 152 pData->m_bEnd = false; 153 return pData.release(); 154 #else 155 return opendir(path); 156 #endif 157 } 158 159 bool FX_GetNextFile(FX_FileHandle* handle, 160 CFX_ByteString* filename, 161 bool* bFolder) { 162 if (!handle) 163 return false; 164 165 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 166 if (handle->m_bEnd) 167 return false; 168 169 *filename = handle->m_FindData.cFileName; 170 *bFolder = 171 (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; 172 if (!FindNextFileA(handle->m_Handle, &handle->m_FindData)) 173 handle->m_bEnd = true; 174 return true; 175 #elif defined(__native_client__) 176 abort(); 177 return false; 178 #else 179 struct dirent* de = readdir(handle); 180 if (!de) 181 return false; 182 *filename = de->d_name; 183 *bFolder = de->d_type == DT_DIR; 184 return true; 185 #endif 186 } 187 188 void FX_CloseFolder(FX_FileHandle* handle) { 189 if (!handle) 190 return; 191 192 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 193 FindClose(handle->m_Handle); 194 delete handle; 195 #else 196 closedir(handle); 197 #endif 198 } 199 200 FX_WCHAR FX_GetFolderSeparator() { 201 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 202 return '\\'; 203 #else 204 return '/'; 205 #endif 206 } 207 208 CFX_Matrix_3by3 CFX_Matrix_3by3::Inverse() { 209 FX_FLOAT det = 210 a * (e * i - f * h) - b * (i * d - f * g) + c * (d * h - e * g); 211 if (FXSYS_fabs(det) < 0.0000001) 212 return CFX_Matrix_3by3(); 213 214 return CFX_Matrix_3by3( 215 (e * i - f * h) / det, -(b * i - c * h) / det, (b * f - c * e) / det, 216 -(d * i - f * g) / det, (a * i - c * g) / det, -(a * f - c * d) / det, 217 (d * h - e * g) / det, -(a * h - b * g) / det, (a * e - b * d) / det); 218 } 219 220 CFX_Matrix_3by3 CFX_Matrix_3by3::Multiply(const CFX_Matrix_3by3& m) { 221 return CFX_Matrix_3by3( 222 a * m.a + b * m.d + c * m.g, a * m.b + b * m.e + c * m.h, 223 a * m.c + b * m.f + c * m.i, d * m.a + e * m.d + f * m.g, 224 d * m.b + e * m.e + f * m.h, d * m.c + e * m.f + f * m.i, 225 g * m.a + h * m.d + i * m.g, g * m.b + h * m.e + i * m.h, 226 g * m.c + h * m.f + i * m.i); 227 } 228 229 CFX_Vector_3by1 CFX_Matrix_3by3::TransformVector(const CFX_Vector_3by1& v) { 230 return CFX_Vector_3by1(a * v.a + b * v.b + c * v.c, 231 d * v.a + e * v.b + f * v.c, 232 g * v.a + h * v.b + i * v.c); 233 } 234 235 uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) { 236 ASSERT(0 < nbits && nbits <= 32); 237 const uint8_t* dataPtr = &pData[bitpos / 8]; 238 int bitShift; 239 int bitMask; 240 int dstShift; 241 int bitCount = bitpos & 0x07; 242 if (nbits < 8 && nbits + bitCount <= 8) { 243 bitShift = 8 - nbits - bitCount; 244 bitMask = (1 << nbits) - 1; 245 dstShift = 0; 246 } else { 247 bitShift = 0; 248 int bitOffset = 8 - bitCount; 249 bitMask = (1 << std::min(bitOffset, nbits)) - 1; 250 dstShift = nbits - bitOffset; 251 } 252 uint32_t result = 253 static_cast<uint32_t>((*dataPtr++ >> bitShift & bitMask) << dstShift); 254 while (dstShift >= 8) { 255 dstShift -= 8; 256 result |= *dataPtr++ << dstShift; 257 } 258 if (dstShift > 0) { 259 bitShift = 8 - dstShift; 260 bitMask = (1 << dstShift) - 1; 261 result |= *dataPtr++ >> bitShift & bitMask; 262 } 263 return result; 264 } 265