LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/openfilegdb - filegdbtable_priv.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 180 189 95.2 %
Date: 2024-05-02 22:57:13 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  Implements reading of FileGDB tables
       6             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #ifndef FILEGDBTABLE_PRIV_H_INCLUDED
      31             : #define FILEGDBTABLE_PRIV_H_INCLUDED
      32             : 
      33             : #include "filegdbtable.h"
      34             : 
      35             : #include "cpl_conv.h"
      36             : #include "cpl_error.h"
      37             : #include "cpl_time.h"
      38             : 
      39             : #include <algorithm>
      40             : #include <cwchar>
      41             : #include <vector>
      42             : #include <limits>
      43             : 
      44             : #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
      45             : 
      46             : #define TEST_BIT(ar, bit) (ar[(bit) / 8] & (1 << ((bit) % 8)))
      47             : #define BIT_ARRAY_SIZE_IN_BYTES(bitsize) (((bitsize) + 7) / 8)
      48             : 
      49             : namespace OpenFileGDB
      50             : {
      51             : 
      52             : /************************************************************************/
      53             : /*                              GetInt16()                              */
      54             : /************************************************************************/
      55             : 
      56        7681 : inline GInt16 GetInt16(const GByte *pBaseAddr, int iOffset)
      57             : {
      58             :     GInt16 nVal;
      59        7681 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
      60        7681 :     CPL_LSBPTR16(&nVal);
      61        7681 :     return nVal;
      62             : }
      63             : 
      64             : /************************************************************************/
      65             : /*                              GetUInt16()                             */
      66             : /************************************************************************/
      67             : 
      68        7064 : inline GUInt16 GetUInt16(const GByte *pBaseAddr, int iOffset)
      69             : {
      70             :     GUInt16 nVal;
      71        7064 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
      72        7064 :     CPL_LSBPTR16(&nVal);
      73        7064 :     return nVal;
      74             : }
      75             : 
      76             : /************************************************************************/
      77             : /*                              GetInt32()                              */
      78             : /************************************************************************/
      79             : 
      80       44825 : inline GInt32 GetInt32(const GByte *pBaseAddr, int iOffset)
      81             : {
      82             :     GInt32 nVal;
      83       44825 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
      84       44825 :     CPL_LSBPTR32(&nVal);
      85       44825 :     return nVal;
      86             : }
      87             : 
      88             : /************************************************************************/
      89             : /*                              GetUInt32()                             */
      90             : /************************************************************************/
      91             : 
      92      532901 : inline GUInt32 GetUInt32(const GByte *pBaseAddr, int iOffset)
      93             : {
      94             :     GUInt32 nVal;
      95      532901 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
      96      532901 :     CPL_LSBPTR32(&nVal);
      97      532901 :     return nVal;
      98             : }
      99             : 
     100             : /************************************************************************/
     101             : /*                              GetInt64()                              */
     102             : /************************************************************************/
     103             : 
     104       83016 : inline int64_t GetInt64(const GByte *pBaseAddr, int iOffset)
     105             : {
     106             :     int64_t nVal;
     107       83016 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
     108       83016 :     CPL_LSBPTR64(&nVal);
     109       83016 :     return nVal;
     110             : }
     111             : 
     112             : /************************************************************************/
     113             : /*                              GetUInt64()                             */
     114             : /************************************************************************/
     115             : 
     116        4360 : inline uint64_t GetUInt64(const GByte *pBaseAddr, int iOffset)
     117             : {
     118             :     uint64_t nVal;
     119        4360 :     memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal));
     120        4360 :     CPL_LSBPTR64(&nVal);
     121        4360 :     return nVal;
     122             : }
     123             : 
     124             : /************************************************************************/
     125             : /*                             GetFloat32()                             */
     126             : /************************************************************************/
     127             : 
     128        7697 : inline float GetFloat32(const GByte *pBaseAddr, int iOffset)
     129             : {
     130             :     float fVal;
     131        7697 :     memcpy(&fVal, pBaseAddr + sizeof(fVal) * iOffset, sizeof(fVal));
     132        7697 :     CPL_LSBPTR32(&fVal);
     133        7697 :     return fVal;
     134             : }
     135             : 
     136             : /************************************************************************/
     137             : /*                             GetFloat64()                             */
     138             : /************************************************************************/
     139             : 
     140       72227 : inline double GetFloat64(const GByte *pBaseAddr, int iOffset)
     141             : {
     142             :     double dfVal;
     143       72227 :     memcpy(&dfVal, pBaseAddr + sizeof(dfVal) * iOffset, sizeof(dfVal));
     144       72227 :     CPL_LSBPTR64(&dfVal);
     145       72227 :     return dfVal;
     146             : }
     147             : 
     148             : /************************************************************************/
     149             : /*                          ReadUInt32()                                */
     150             : /************************************************************************/
     151             : 
     152        7999 : inline bool ReadUInt32(VSILFILE *fp, uint32_t &nVal)
     153             : {
     154        7999 :     const bool bRet = VSIFReadL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal);
     155        7999 :     CPL_LSBPTR32(&nVal);
     156        7999 :     return bRet;
     157             : }
     158             : 
     159             : /************************************************************************/
     160             : /*                          WriteUInt32()                               */
     161             : /************************************************************************/
     162             : 
     163       76074 : inline bool WriteUInt32(VSILFILE *fp, uint32_t nVal)
     164             : {
     165       76074 :     CPL_LSBPTR32(&nVal);
     166       76074 :     return VSIFWriteL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal);
     167             : }
     168             : 
     169             : /************************************************************************/
     170             : /*                          WriteUInt64()                               */
     171             : /************************************************************************/
     172             : 
     173       10336 : inline bool WriteUInt64(VSILFILE *fp, uint64_t nVal)
     174             : {
     175       10336 :     CPL_LSBPTR64(&nVal);
     176       10336 :     return VSIFWriteL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal);
     177             : }
     178             : 
     179             : /************************************************************************/
     180             : /*                          WriteFloat64()                               */
     181             : /************************************************************************/
     182             : 
     183         641 : inline bool WriteFloat64(VSILFILE *fp, double dfVal)
     184             : {
     185         641 :     CPL_LSBPTR64(&dfVal);
     186         641 :     return VSIFWriteL(&dfVal, 1, sizeof(dfVal), fp) == sizeof(dfVal);
     187             : }
     188             : 
     189             : /************************************************************************/
     190             : /*                          WriteUInt32()                               */
     191             : /************************************************************************/
     192             : 
     193       21596 : inline void WriteUInt32(std::vector<GByte> &abyBuffer, uint32_t nVal)
     194             : {
     195       21596 :     CPL_LSBPTR32(&nVal);
     196       21596 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     197       21596 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     198       21596 : }
     199             : 
     200             : /************************************************************************/
     201             : /*                          WriteUInt32()                               */
     202             : /************************************************************************/
     203             : 
     204       10166 : inline void WriteUInt32(std::vector<GByte> &abyBuffer, uint32_t nVal,
     205             :                         size_t nPos)
     206             : {
     207       10166 :     CPL_LSBPTR32(&nVal);
     208       10166 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     209       10166 :     memcpy(&abyBuffer[nPos], pabyInput, sizeof(nVal));
     210       10166 : }
     211             : 
     212             : /************************************************************************/
     213             : /*                          WriteFloat32()                               */
     214             : /************************************************************************/
     215             : 
     216          54 : inline void WriteFloat32(std::vector<GByte> &abyBuffer, float fVal)
     217             : {
     218          54 :     CPL_LSBPTR32(&fVal);
     219          54 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&fVal);
     220          54 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(fVal));
     221          54 : }
     222             : 
     223             : /************************************************************************/
     224             : /*                          WriteFloat64()                               */
     225             : /************************************************************************/
     226             : 
     227       12878 : inline void WriteFloat64(std::vector<GByte> &abyBuffer, double dfVal)
     228             : {
     229       12878 :     CPL_LSBPTR64(&dfVal);
     230       12878 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&dfVal);
     231       12878 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(dfVal));
     232       12878 : }
     233             : 
     234             : /************************************************************************/
     235             : /*                          WriteInt32()                                */
     236             : /************************************************************************/
     237             : 
     238        3797 : inline void WriteInt32(std::vector<GByte> &abyBuffer, int32_t nVal)
     239             : {
     240        3797 :     CPL_LSBPTR32(&nVal);
     241        3797 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     242        3797 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     243        3797 : }
     244             : 
     245             : /************************************************************************/
     246             : /*                          WriteInt64()                                */
     247             : /************************************************************************/
     248             : 
     249           3 : inline void WriteInt64(std::vector<GByte> &abyBuffer, int64_t nVal)
     250             : {
     251           3 :     CPL_LSBPTR64(&nVal);
     252           3 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     253           3 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     254           3 : }
     255             : 
     256             : /************************************************************************/
     257             : /*                          WriteUInt16()                               */
     258             : /************************************************************************/
     259             : 
     260        4460 : inline void WriteUInt16(std::vector<GByte> &abyBuffer, uint16_t nVal)
     261             : {
     262        4460 :     CPL_LSBPTR16(&nVal);
     263        4460 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     264        4460 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     265        4460 : }
     266             : 
     267             : /************************************************************************/
     268             : /*                          WriteInt16()                                */
     269             : /************************************************************************/
     270             : 
     271        3692 : inline void WriteInt16(std::vector<GByte> &abyBuffer, int16_t nVal)
     272             : {
     273        3692 :     CPL_LSBPTR16(&nVal);
     274        3692 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     275        3692 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     276        3692 : }
     277             : 
     278             : /************************************************************************/
     279             : /*                          WriteUInt8()                                */
     280             : /************************************************************************/
     281             : 
     282      201186 : inline void WriteUInt8(std::vector<GByte> &abyBuffer, uint8_t nVal)
     283             : {
     284      201186 :     abyBuffer.push_back(nVal);
     285      201186 : }
     286             : 
     287             : /************************************************************************/
     288             : /*                          WriteUInt64()                               */
     289             : /************************************************************************/
     290             : 
     291        4058 : inline void WriteUInt64(std::vector<GByte> &abyBuffer, uint64_t nVal)
     292             : {
     293        4058 :     CPL_LSBPTR64(&nVal);
     294        4058 :     const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal);
     295        4058 :     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal));
     296        4058 : }
     297             : 
     298             : /************************************************************************/
     299             : /*                             WriteVarUInt()                           */
     300             : /************************************************************************/
     301             : 
     302      120728 : inline void WriteVarUInt(std::vector<GByte> &abyBuffer, uint64_t nVal)
     303             : {
     304             :     while (true)
     305             :     {
     306      120728 :         if (nVal >= 0x80)
     307             :         {
     308       54148 :             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nVal & 0x7F)));
     309       54148 :             nVal >>= 7;
     310             :         }
     311             :         else
     312             :         {
     313       66580 :             WriteUInt8(abyBuffer, static_cast<uint8_t>(nVal));
     314       66580 :             break;
     315             :         }
     316             :     }
     317       66580 : }
     318             : 
     319             : /************************************************************************/
     320             : /*                             WriteVarInt()                            */
     321             : /************************************************************************/
     322             : 
     323        3359 : inline void WriteVarInt(std::vector<GByte> &abyBuffer, int64_t nVal)
     324             : {
     325             :     uint64_t nUVal;
     326        3359 :     if (nVal < 0)
     327             :     {
     328         425 :         if (nVal == std::numeric_limits<int64_t>::min())
     329           0 :             nUVal = static_cast<uint64_t>(1) << 63;
     330             :         else
     331         425 :             nUVal = -nVal;
     332         425 :         if (nUVal >= 0x40)
     333             :         {
     334         425 :             WriteUInt8(abyBuffer,
     335         425 :                        static_cast<uint8_t>(0x80 | 0x40 | (nUVal & 0x3F)));
     336         425 :             nUVal >>= 6;
     337             :         }
     338             :         else
     339             :         {
     340           0 :             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x40 | (nUVal & 0x3F)));
     341           0 :             return;
     342             :         }
     343             :     }
     344             :     else
     345             :     {
     346        2934 :         nUVal = nVal;
     347        2934 :         if (nUVal >= 0x40)
     348             :         {
     349         699 :             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nUVal & 0x3F)));
     350         699 :             nUVal >>= 6;
     351             :         }
     352             :         else
     353             :         {
     354        2235 :             WriteUInt8(abyBuffer, static_cast<uint8_t>((nUVal & 0x3F)));
     355        2235 :             return;
     356             :         }
     357             :     }
     358             : 
     359        1124 :     WriteVarUInt(abyBuffer, nUVal);
     360             : }
     361             : 
     362             : /************************************************************************/
     363             : /*                            ReadUTF16String()                         */
     364             : /************************************************************************/
     365             : 
     366       92931 : inline std::string ReadUTF16String(const GByte *pabyIter, int nCarCount)
     367             : {
     368      185862 :     std::wstring osWideStr;
     369      732277 :     for (int j = 0; j < nCarCount; j++)
     370      639346 :         osWideStr += pabyIter[2 * j] | (pabyIter[2 * j + 1] << 8);
     371             :     char *pszStr =
     372       92931 :         CPLRecodeFromWChar(osWideStr.c_str(), CPL_ENC_UCS2, CPL_ENC_UTF8);
     373       92931 :     std::string osRet(pszStr);
     374       92931 :     CPLFree(pszStr);
     375      185862 :     return osRet;
     376             : }
     377             : 
     378             : /************************************************************************/
     379             : /*                           WriteUTF16String()                         */
     380             : /************************************************************************/
     381             : 
     382             : enum UTF16StringFormat
     383             : {
     384             :     NUMBER_OF_BYTES_ON_UINT16,
     385             :     NUMBER_OF_BYTES_ON_VARUINT,
     386             :     NUMBER_OF_CHARS_ON_UINT8,
     387             :     NUMBER_OF_CHARS_ON_UINT32,
     388             : };
     389             : 
     390       28707 : inline void WriteUTF16String(std::vector<GByte> &abyBuffer, const char *pszStr,
     391             :                              UTF16StringFormat eFormat)
     392             : {
     393       28707 :     wchar_t *pszWStr = CPLRecodeToWChar(pszStr, CPL_ENC_UTF8, CPL_ENC_UCS2);
     394       28707 :     size_t nWLen = wcslen(pszWStr);
     395       28707 :     switch (eFormat)
     396             :     {
     397         539 :         case NUMBER_OF_BYTES_ON_UINT16:
     398             :         {
     399             :             // Write length as bytes
     400             :             const auto nLenToWrite =
     401         539 :                 std::min(static_cast<size_t>(65534), sizeof(uint16_t) * nWLen);
     402         539 :             if (nLenToWrite < sizeof(uint16_t) * nWLen)
     403             :             {
     404           0 :                 CPLError(CE_Warning, CPLE_AppDefined,
     405             :                          "String %s truncated to %u bytes", pszStr,
     406             :                          static_cast<uint32_t>(nLenToWrite));
     407           0 :                 nWLen = nLenToWrite / sizeof(uint16_t);
     408             :             }
     409         539 :             WriteUInt16(abyBuffer, static_cast<uint16_t>(nLenToWrite));
     410         539 :             break;
     411             :         }
     412             : 
     413           2 :         case NUMBER_OF_BYTES_ON_VARUINT:
     414             :         {
     415             :             // Write length as bytes
     416           2 :             WriteVarUInt(abyBuffer, sizeof(uint16_t) * nWLen);
     417           2 :             break;
     418             :         }
     419             : 
     420       27194 :         case NUMBER_OF_CHARS_ON_UINT8:
     421             :         {
     422             :             // Write length as number of UTF16 characters
     423       27194 :             const auto nLenToWrite = std::min(static_cast<size_t>(255), nWLen);
     424       27194 :             if (nLenToWrite < nWLen)
     425             :             {
     426           0 :                 CPLError(CE_Warning, CPLE_AppDefined,
     427             :                          "String %s truncated to %u UTF16 characters", pszStr,
     428             :                          static_cast<uint32_t>(nLenToWrite));
     429           0 :                 nWLen = nLenToWrite;
     430             :             }
     431       27194 :             WriteUInt8(abyBuffer, static_cast<uint8_t>(nLenToWrite));
     432       27194 :             break;
     433             :         }
     434             : 
     435         972 :         case NUMBER_OF_CHARS_ON_UINT32:
     436             :         {
     437             :             // Write length as number of UTF16 characters
     438         972 :             WriteUInt32(abyBuffer, static_cast<uint32_t>(nWLen));
     439         972 :             break;
     440             :         }
     441             :     }
     442             : 
     443       28707 :     if (nWLen)
     444             :     {
     445       15114 :         std::vector<uint16_t> anChars(nWLen);
     446      178188 :         for (size_t i = 0; i < nWLen; ++i)
     447             :         {
     448      163074 :             anChars[i] = static_cast<uint16_t>(pszWStr[i]);
     449      163074 :             CPL_LSBPTR16(&anChars[i]);
     450             :         }
     451             :         const GByte *pabyInput =
     452       15114 :             reinterpret_cast<const GByte *>(anChars.data());
     453           0 :         abyBuffer.insert(abyBuffer.end(), pabyInput,
     454       15114 :                          pabyInput + nWLen * sizeof(uint16_t));
     455             :     }
     456       28707 :     CPLFree(pszWStr);
     457       28707 : }
     458             : 
     459             : /************************************************************************/
     460             : /*                      FileGDBOGRDateToDoubleDate()                    */
     461             : /************************************************************************/
     462             : 
     463         134 : inline double FileGDBOGRDateToDoubleDate(const OGRField *psField,
     464             :                                          bool bConvertToGMT,
     465             :                                          bool bHighPrecision)
     466             : {
     467             :     struct tm brokendowntime;
     468         134 :     brokendowntime.tm_year = psField->Date.Year - 1900;
     469         134 :     brokendowntime.tm_mon = psField->Date.Month - 1;
     470         134 :     brokendowntime.tm_mday = psField->Date.Day;
     471         134 :     brokendowntime.tm_hour = psField->Date.Hour;
     472         134 :     brokendowntime.tm_min = psField->Date.Minute;
     473         134 :     brokendowntime.tm_sec = bHighPrecision
     474         134 :                                 ? static_cast<int>(psField->Date.Second)
     475         118 :                                 : static_cast<int>(psField->Date.Second + 0.5);
     476         134 :     GIntBig nUnixTime = CPLYMDHMSToUnixTime(&brokendowntime);
     477         134 :     if (bConvertToGMT && psField->Date.TZFlag > 1 &&
     478          39 :         psField->Date.TZFlag != 100)
     479             :     {
     480             :         // Convert to GMT
     481          38 :         const int TZOffset = std::abs(psField->Date.TZFlag - 100) * 15;
     482          38 :         const int TZHour = TZOffset / 60;
     483          38 :         const int TZMinute = TZOffset - TZHour * 60;
     484          38 :         const int nOffset = TZHour * 3600 + TZMinute * 60;
     485          38 :         if (psField->Date.TZFlag >= 100)
     486          38 :             nUnixTime -= nOffset;
     487             :         else
     488           0 :             nUnixTime += nOffset;
     489             :     }
     490             :     // 25569: Number of days between 1899/12/30 00:00:00 and 1970/01/01 00:00:00
     491             :     return static_cast<double>(
     492         268 :                nUnixTime +
     493             :                (bHighPrecision
     494         134 :                     ? fmod(static_cast<double>(psField->Date.Second), 1.0)
     495         134 :                     : 0)) /
     496         134 :                3600.0 / 24.0 +
     497         134 :            25569.0;
     498             : }
     499             : 
     500             : /************************************************************************/
     501             : /*                      FileGDBOGRTimeToDoubleTime()                    */
     502             : /************************************************************************/
     503             : 
     504          12 : inline double FileGDBOGRTimeToDoubleTime(const OGRField *psField)
     505             : {
     506          12 :     return static_cast<double>(psField->Date.Hour * 3600 +
     507          12 :                                psField->Date.Minute * 60 +
     508          12 :                                psField->Date.Second) /
     509          12 :            3600.0 / 24.0;
     510             : }
     511             : 
     512             : void FileGDBTablePrintError(const char *pszFile, int nLineNumber);
     513             : 
     514             : #define PrintError() FileGDBTablePrintError(__FILE__, __LINE__)
     515             : 
     516             : /************************************************************************/
     517             : /*                          returnError()                               */
     518             : /************************************************************************/
     519             : 
     520             : #define returnError()                                                          \
     521             :     do                                                                         \
     522             :     {                                                                          \
     523             :         PrintError();                                                          \
     524             :         return (errorRetValue);                                                \
     525             :     } while (0)
     526             : 
     527             : /************************************************************************/
     528             : /*                         returnErrorIf()                              */
     529             : /************************************************************************/
     530             : 
     531             : #define returnErrorIf(expr)                                                    \
     532             :     do                                                                         \
     533             :     {                                                                          \
     534             :         if ((expr))                                                            \
     535             :             returnError();                                                     \
     536             :     } while (0)
     537             : 
     538             : /************************************************************************/
     539             : /*                       returnErrorAndCleanupIf()                      */
     540             : /************************************************************************/
     541             : 
     542             : #define returnErrorAndCleanupIf(expr, cleanup)                                 \
     543             :     do                                                                         \
     544             :     {                                                                          \
     545             :         if ((expr))                                                            \
     546             :         {                                                                      \
     547             :             cleanup;                                                           \
     548             :             returnError();                                                     \
     549             :         }                                                                      \
     550             :     } while (0)
     551             : 
     552             : } /* namespace OpenFileGDB */
     553             : 
     554             : #endif /* FILEGDBTABLE_PRIV_H_INCLUDED */

Generated by: LCOV version 1.14