Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implements Open FileGDB OGR driver. 5 : * Author: Even Rouault, <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2022, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * Permission is hereby granted, free of charge, to any person obtaining a 11 : * copy of this software and associated documentation files (the "Software"), 12 : * to deal in the Software without restriction, including without limitation 13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 : * and/or sell copies of the Software, and to permit persons to whom the 15 : * Software is furnished to do so, subject to the following conditions: 16 : * 17 : * The above copyright notice and this permission notice shall be included 18 : * in all copies or substantial portions of the Software. 19 : * 20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 : * DEALINGS IN THE SOFTWARE. 27 : ****************************************************************************/ 28 : 29 : #include "cpl_port.h" 30 : #include "ogr_openfilegdb.h" 31 : 32 : #include <random> 33 : #include <sstream> 34 : 35 : /************************************************************************/ 36 : /* CPLGettimeofday() */ 37 : /************************************************************************/ 38 : 39 : #if defined(_WIN32) && !defined(__CYGWIN__) 40 : #include <sys/timeb.h> 41 : 42 : namespace 43 : { 44 : struct CPLTimeVal 45 : { 46 : time_t tv_sec; /* seconds */ 47 : long tv_usec; /* and microseconds */ 48 : }; 49 : } // namespace 50 : 51 : static int CPLGettimeofday(struct CPLTimeVal *tp, void * /* timezonep*/) 52 : { 53 : struct _timeb theTime; 54 : 55 : _ftime(&theTime); 56 : tp->tv_sec = static_cast<time_t>(theTime.time); 57 : tp->tv_usec = theTime.millitm * 1000; 58 : return 0; 59 : } 60 : #else 61 : #include <sys/time.h> /* for gettimeofday() */ 62 : #define CPLTimeVal timeval 63 : #define CPLGettimeofday(t, u) gettimeofday(t, u) 64 : #endif 65 : 66 : /***********************************************************************/ 67 : /* OFGDBGenerateUUID() */ 68 : /***********************************************************************/ 69 : 70 : // Probably not the best UUID generator ever. One issue is that mt19937 71 : // uses only a 32-bit seed. 72 : CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW 73 1026 : std::string OFGDBGenerateUUID() 74 : { 75 : struct CPLTimeVal tv; 76 1026 : memset(&tv, 0, sizeof(tv)); 77 : static uint32_t nCounter = 0; 78 : const bool bReproducibleUUID = 79 1026 : CPLTestBool(CPLGetConfigOption("OPENFILEGDB_REPRODUCIBLE_UUID", "NO")); 80 : 81 2052 : std::stringstream ss; 82 : 83 : { 84 1026 : if (!bReproducibleUUID) 85 1026 : CPLGettimeofday(&tv, nullptr); 86 2052 : std::mt19937 gen(++nCounter + 87 : (bReproducibleUUID 88 0 : ? 0 89 1026 : : static_cast<unsigned>(tv.tv_sec ^ tv.tv_usec))); 90 1026 : std::uniform_int_distribution<> dis(0, 15); 91 : 92 1026 : ss << "{"; 93 1026 : ss << std::hex; 94 9234 : for (int i = 0; i < 8; i++) 95 : { 96 8208 : ss << dis(gen); 97 : } 98 1026 : ss << "-"; 99 5130 : for (int i = 0; i < 4; i++) 100 : { 101 4104 : ss << dis(gen); 102 : } 103 1026 : ss << "-4"; 104 4104 : for (int i = 0; i < 3; i++) 105 : { 106 3078 : ss << dis(gen); 107 : } 108 : } 109 : 110 : { 111 1026 : if (!bReproducibleUUID) 112 1026 : CPLGettimeofday(&tv, nullptr); 113 2052 : std::mt19937 gen(++nCounter + 114 : (bReproducibleUUID 115 0 : ? 0 116 1026 : : static_cast<unsigned>(tv.tv_sec ^ tv.tv_usec))); 117 1026 : std::uniform_int_distribution<> dis(0, 15); 118 1026 : std::uniform_int_distribution<> dis2(8, 11); 119 : 120 1026 : ss << "-"; 121 1026 : ss << dis2(gen); 122 4104 : for (int i = 0; i < 3; i++) 123 : { 124 3078 : ss << dis(gen); 125 : } 126 1026 : ss << "-"; 127 13338 : for (int i = 0; i < 12; i++) 128 : { 129 12312 : ss << dis(gen); 130 : }; 131 1026 : ss << "}"; 132 2052 : return ss.str(); 133 : } 134 : }