/src/gdal/ogr/ogrsf_frmts/openfilegdb/filegdbtable_priv.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: OpenGIS Simple Features Reference Implementation |
4 | | * Purpose: Implements reading of FileGDB tables |
5 | | * Author: Even Rouault, <even dot rouault at spatialys.com> |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef FILEGDBTABLE_PRIV_H_INCLUDED |
14 | | #define FILEGDBTABLE_PRIV_H_INCLUDED |
15 | | |
16 | | #include "filegdbtable.h" |
17 | | |
18 | | #include "cpl_conv.h" |
19 | | #include "cpl_error.h" |
20 | | #include "cpl_time.h" |
21 | | |
22 | | #include <algorithm> |
23 | | #include <cwchar> |
24 | | #include <vector> |
25 | | #include <limits> |
26 | | |
27 | 584k | #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1)) |
28 | | |
29 | 16.5M | #define TEST_BIT(ar, bit) (ar[(bit) / 8] & (1 << ((bit) % 8))) |
30 | 57.2k | #define BIT_ARRAY_SIZE_IN_BYTES(bitsize) (((bitsize) + 7) / 8) |
31 | | |
32 | | namespace OpenFileGDB |
33 | | { |
34 | | |
35 | | /************************************************************************/ |
36 | | /* GetInt16() */ |
37 | | /************************************************************************/ |
38 | | |
39 | | inline GInt16 GetInt16(const GByte *pBaseAddr, int iOffset) |
40 | 36.4k | { |
41 | 36.4k | GInt16 nVal; |
42 | 36.4k | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
43 | 36.4k | CPL_LSBPTR16(&nVal); |
44 | 36.4k | return nVal; |
45 | 36.4k | } |
46 | | |
47 | | /************************************************************************/ |
48 | | /* GetUInt16() */ |
49 | | /************************************************************************/ |
50 | | |
51 | | inline GUInt16 GetUInt16(const GByte *pBaseAddr, int iOffset) |
52 | 73.9k | { |
53 | 73.9k | GUInt16 nVal; |
54 | 73.9k | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
55 | 73.9k | CPL_LSBPTR16(&nVal); |
56 | 73.9k | return nVal; |
57 | 73.9k | } |
58 | | |
59 | | /************************************************************************/ |
60 | | /* GetInt32() */ |
61 | | /************************************************************************/ |
62 | | |
63 | | inline GInt32 GetInt32(const GByte *pBaseAddr, int iOffset) |
64 | 417k | { |
65 | 417k | GInt32 nVal; |
66 | 417k | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
67 | 417k | CPL_LSBPTR32(&nVal); |
68 | 417k | return nVal; |
69 | 417k | } |
70 | | |
71 | | /************************************************************************/ |
72 | | /* GetUInt32() */ |
73 | | /************************************************************************/ |
74 | | |
75 | | inline GUInt32 GetUInt32(const GByte *pBaseAddr, int iOffset) |
76 | 81.9M | { |
77 | 81.9M | GUInt32 nVal; |
78 | 81.9M | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
79 | 81.9M | CPL_LSBPTR32(&nVal); |
80 | 81.9M | return nVal; |
81 | 81.9M | } |
82 | | |
83 | | /************************************************************************/ |
84 | | /* GetInt64() */ |
85 | | /************************************************************************/ |
86 | | |
87 | | inline int64_t GetInt64(const GByte *pBaseAddr, int iOffset) |
88 | 1.91k | { |
89 | 1.91k | int64_t nVal; |
90 | 1.91k | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
91 | 1.91k | CPL_LSBPTR64(&nVal); |
92 | 1.91k | return nVal; |
93 | 1.91k | } |
94 | | |
95 | | /************************************************************************/ |
96 | | /* GetUInt64() */ |
97 | | /************************************************************************/ |
98 | | |
99 | | inline uint64_t GetUInt64(const GByte *pBaseAddr, int iOffset) |
100 | 47.6k | { |
101 | 47.6k | uint64_t nVal; |
102 | 47.6k | memcpy(&nVal, pBaseAddr + sizeof(nVal) * iOffset, sizeof(nVal)); |
103 | 47.6k | CPL_LSBPTR64(&nVal); |
104 | 47.6k | return nVal; |
105 | 47.6k | } |
106 | | |
107 | | /************************************************************************/ |
108 | | /* GetFloat32() */ |
109 | | /************************************************************************/ |
110 | | |
111 | | inline float GetFloat32(const GByte *pBaseAddr, int iOffset) |
112 | 22.8k | { |
113 | 22.8k | float fVal; |
114 | 22.8k | memcpy(&fVal, pBaseAddr + sizeof(fVal) * iOffset, sizeof(fVal)); |
115 | 22.8k | CPL_LSBPTR32(&fVal); |
116 | 22.8k | return fVal; |
117 | 22.8k | } |
118 | | |
119 | | /************************************************************************/ |
120 | | /* GetFloat64() */ |
121 | | /************************************************************************/ |
122 | | |
123 | | inline double GetFloat64(const GByte *pBaseAddr, int iOffset) |
124 | 707k | { |
125 | 707k | double dfVal; |
126 | 707k | memcpy(&dfVal, pBaseAddr + sizeof(dfVal) * iOffset, sizeof(dfVal)); |
127 | 707k | CPL_LSBPTR64(&dfVal); |
128 | 707k | return dfVal; |
129 | 707k | } |
130 | | |
131 | | /************************************************************************/ |
132 | | /* ReadUInt32() */ |
133 | | /************************************************************************/ |
134 | | |
135 | | inline bool ReadUInt32(VSILFILE *fp, uint32_t &nVal) |
136 | 115k | { |
137 | 115k | const bool bRet = VSIFReadL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal); |
138 | 115k | CPL_LSBPTR32(&nVal); |
139 | 115k | return bRet; |
140 | 115k | } |
141 | | |
142 | | /************************************************************************/ |
143 | | /* WriteUInt32() */ |
144 | | /************************************************************************/ |
145 | | |
146 | | inline bool WriteUInt32(VSILFILE *fp, uint32_t nVal) |
147 | 748k | { |
148 | 748k | CPL_LSBPTR32(&nVal); |
149 | 748k | return VSIFWriteL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal); |
150 | 748k | } |
151 | | |
152 | | /************************************************************************/ |
153 | | /* WriteUInt64() */ |
154 | | /************************************************************************/ |
155 | | |
156 | | inline bool WriteUInt64(VSILFILE *fp, uint64_t nVal) |
157 | 16.6k | { |
158 | 16.6k | CPL_LSBPTR64(&nVal); |
159 | 16.6k | return VSIFWriteL(&nVal, 1, sizeof(nVal), fp) == sizeof(nVal); |
160 | 16.6k | } |
161 | | |
162 | | /************************************************************************/ |
163 | | /* WriteFloat64() */ |
164 | | /************************************************************************/ |
165 | | |
166 | | inline bool WriteFloat64(VSILFILE *fp, double dfVal) |
167 | 0 | { |
168 | 0 | CPL_LSBPTR64(&dfVal); |
169 | 0 | return VSIFWriteL(&dfVal, 1, sizeof(dfVal), fp) == sizeof(dfVal); |
170 | 0 | } |
171 | | |
172 | | /************************************************************************/ |
173 | | /* WriteUInt32() */ |
174 | | /************************************************************************/ |
175 | | |
176 | | inline void WriteUInt32(std::vector<GByte> &abyBuffer, uint32_t nVal) |
177 | 36.8k | { |
178 | 36.8k | CPL_LSBPTR32(&nVal); |
179 | 36.8k | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
180 | 36.8k | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
181 | 36.8k | } |
182 | | |
183 | | /************************************************************************/ |
184 | | /* WriteUInt32() */ |
185 | | /************************************************************************/ |
186 | | |
187 | | inline void WriteUInt32(std::vector<GByte> &abyBuffer, uint32_t nVal, |
188 | | size_t nPos) |
189 | 2.05k | { |
190 | 2.05k | CPL_LSBPTR32(&nVal); |
191 | 2.05k | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
192 | 2.05k | memcpy(&abyBuffer[nPos], pabyInput, sizeof(nVal)); |
193 | 2.05k | } |
194 | | |
195 | | /************************************************************************/ |
196 | | /* WriteFloat32() */ |
197 | | /************************************************************************/ |
198 | | |
199 | | inline void WriteFloat32(std::vector<GByte> &abyBuffer, float fVal) |
200 | 0 | { |
201 | 0 | CPL_LSBPTR32(&fVal); |
202 | 0 | const GByte *pabyInput = reinterpret_cast<const GByte *>(&fVal); |
203 | 0 | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(fVal)); |
204 | 0 | } |
205 | | |
206 | | /************************************************************************/ |
207 | | /* WriteFloat64() */ |
208 | | /************************************************************************/ |
209 | | |
210 | | inline void WriteFloat64(std::vector<GByte> &abyBuffer, double dfVal) |
211 | 15.0k | { |
212 | 15.0k | CPL_LSBPTR64(&dfVal); |
213 | 15.0k | const GByte *pabyInput = reinterpret_cast<const GByte *>(&dfVal); |
214 | 15.0k | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(dfVal)); |
215 | 15.0k | } |
216 | | |
217 | | /************************************************************************/ |
218 | | /* WriteInt32() */ |
219 | | /************************************************************************/ |
220 | | |
221 | | inline void WriteInt32(std::vector<GByte> &abyBuffer, int32_t nVal) |
222 | 6.49k | { |
223 | 6.49k | CPL_LSBPTR32(&nVal); |
224 | 6.49k | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
225 | 6.49k | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
226 | 6.49k | } |
227 | | |
228 | | /************************************************************************/ |
229 | | /* WriteInt64() */ |
230 | | /************************************************************************/ |
231 | | |
232 | | inline void WriteInt64(std::vector<GByte> &abyBuffer, int64_t nVal) |
233 | 0 | { |
234 | 0 | CPL_LSBPTR64(&nVal); |
235 | 0 | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
236 | 0 | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
237 | 0 | } |
238 | | |
239 | | /************************************************************************/ |
240 | | /* WriteUInt16() */ |
241 | | /************************************************************************/ |
242 | | |
243 | | inline void WriteUInt16(std::vector<GByte> &abyBuffer, uint16_t nVal) |
244 | 9.14k | { |
245 | 9.14k | CPL_LSBPTR16(&nVal); |
246 | 9.14k | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
247 | 9.14k | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
248 | 9.14k | } |
249 | | |
250 | | /************************************************************************/ |
251 | | /* WriteInt16() */ |
252 | | /************************************************************************/ |
253 | | |
254 | | inline void WriteInt16(std::vector<GByte> &abyBuffer, int16_t nVal) |
255 | 672 | { |
256 | 672 | CPL_LSBPTR16(&nVal); |
257 | 672 | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
258 | 672 | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
259 | 672 | } |
260 | | |
261 | | /************************************************************************/ |
262 | | /* WriteUInt8() */ |
263 | | /************************************************************************/ |
264 | | |
265 | | inline void WriteUInt8(std::vector<GByte> &abyBuffer, uint8_t nVal) |
266 | 751k | { |
267 | 751k | abyBuffer.push_back(nVal); |
268 | 751k | } |
269 | | |
270 | | /************************************************************************/ |
271 | | /* WriteUInt64() */ |
272 | | /************************************************************************/ |
273 | | |
274 | | inline void WriteUInt64(std::vector<GByte> &abyBuffer, uint64_t nVal) |
275 | 0 | { |
276 | 0 | CPL_LSBPTR64(&nVal); |
277 | 0 | const GByte *pabyInput = reinterpret_cast<const GByte *>(&nVal); |
278 | 0 | abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(nVal)); |
279 | 0 | } |
280 | | |
281 | | /************************************************************************/ |
282 | | /* WriteVarUInt() */ |
283 | | /************************************************************************/ |
284 | | |
285 | | inline void WriteVarUInt(std::vector<GByte> &abyBuffer, uint64_t nVal) |
286 | 610k | { |
287 | 624k | while (true) |
288 | 624k | { |
289 | 624k | if (nVal >= 0x80) |
290 | 14.2k | { |
291 | 14.2k | WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nVal & 0x7F))); |
292 | 14.2k | nVal >>= 7; |
293 | 14.2k | } |
294 | 610k | else |
295 | 610k | { |
296 | 610k | WriteUInt8(abyBuffer, static_cast<uint8_t>(nVal)); |
297 | 610k | break; |
298 | 610k | } |
299 | 624k | } |
300 | 610k | } |
301 | | |
302 | | /************************************************************************/ |
303 | | /* WriteVarInt() */ |
304 | | /************************************************************************/ |
305 | | |
306 | | inline void WriteVarInt(std::vector<GByte> &abyBuffer, int64_t nVal) |
307 | 0 | { |
308 | 0 | uint64_t nUVal; |
309 | 0 | if (nVal < 0) |
310 | 0 | { |
311 | 0 | if (nVal == std::numeric_limits<int64_t>::min()) |
312 | 0 | nUVal = static_cast<uint64_t>(1) << 63; |
313 | 0 | else |
314 | 0 | nUVal = -nVal; |
315 | 0 | if (nUVal >= 0x40) |
316 | 0 | { |
317 | 0 | WriteUInt8(abyBuffer, |
318 | 0 | static_cast<uint8_t>(0x80 | 0x40 | (nUVal & 0x3F))); |
319 | 0 | nUVal >>= 6; |
320 | 0 | } |
321 | 0 | else |
322 | 0 | { |
323 | 0 | WriteUInt8(abyBuffer, static_cast<uint8_t>(0x40 | (nUVal & 0x3F))); |
324 | 0 | return; |
325 | 0 | } |
326 | 0 | } |
327 | 0 | else |
328 | 0 | { |
329 | 0 | nUVal = nVal; |
330 | 0 | if (nUVal >= 0x40) |
331 | 0 | { |
332 | 0 | WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nUVal & 0x3F))); |
333 | 0 | nUVal >>= 6; |
334 | 0 | } |
335 | 0 | else |
336 | 0 | { |
337 | 0 | WriteUInt8(abyBuffer, static_cast<uint8_t>((nUVal & 0x3F))); |
338 | 0 | return; |
339 | 0 | } |
340 | 0 | } |
341 | | |
342 | 0 | WriteVarUInt(abyBuffer, nUVal); |
343 | 0 | } |
344 | | |
345 | | /************************************************************************/ |
346 | | /* ReadUTF16String() */ |
347 | | /************************************************************************/ |
348 | | |
349 | | inline std::string ReadUTF16String(const GByte *pabyIter, int nCarCount) |
350 | 1.02M | { |
351 | 1.02M | std::wstring osWideStr; |
352 | 9.21M | for (int j = 0; j < nCarCount; j++) |
353 | 8.18M | osWideStr += pabyIter[2 * j] | (pabyIter[2 * j + 1] << 8); |
354 | 1.02M | char *pszStr = |
355 | 1.02M | CPLRecodeFromWChar(osWideStr.c_str(), CPL_ENC_UCS2, CPL_ENC_UTF8); |
356 | 1.02M | std::string osRet(pszStr); |
357 | 1.02M | CPLFree(pszStr); |
358 | 1.02M | return osRet; |
359 | 1.02M | } |
360 | | |
361 | | /************************************************************************/ |
362 | | /* WriteUTF16String() */ |
363 | | /************************************************************************/ |
364 | | |
365 | | enum UTF16StringFormat |
366 | | { |
367 | | NUMBER_OF_BYTES_ON_UINT16, |
368 | | NUMBER_OF_BYTES_ON_VARUINT, |
369 | | NUMBER_OF_CHARS_ON_UINT8, |
370 | | NUMBER_OF_CHARS_ON_UINT32, |
371 | | }; |
372 | | |
373 | | inline void WriteUTF16String(std::vector<GByte> &abyBuffer, const char *pszStr, |
374 | | UTF16StringFormat eFormat) |
375 | 54.6k | { |
376 | 54.6k | wchar_t *pszWStr = CPLRecodeToWChar(pszStr, CPL_ENC_UTF8, CPL_ENC_UCS2); |
377 | 54.6k | size_t nWLen = wcslen(pszWStr); |
378 | 54.6k | switch (eFormat) |
379 | 54.6k | { |
380 | 885 | case NUMBER_OF_BYTES_ON_UINT16: |
381 | 885 | { |
382 | | // Write length as bytes |
383 | 885 | const auto nLenToWrite = |
384 | 885 | std::min(static_cast<size_t>(65534), sizeof(uint16_t) * nWLen); |
385 | 885 | if (nLenToWrite < sizeof(uint16_t) * nWLen) |
386 | 0 | { |
387 | 0 | CPLError(CE_Warning, CPLE_AppDefined, |
388 | 0 | "String %s truncated to %u bytes", pszStr, |
389 | 0 | static_cast<uint32_t>(nLenToWrite)); |
390 | 0 | nWLen = nLenToWrite / sizeof(uint16_t); |
391 | 0 | } |
392 | 885 | WriteUInt16(abyBuffer, static_cast<uint16_t>(nLenToWrite)); |
393 | 885 | break; |
394 | 0 | } |
395 | | |
396 | 0 | case NUMBER_OF_BYTES_ON_VARUINT: |
397 | 0 | { |
398 | | // Write length as bytes |
399 | 0 | WriteVarUInt(abyBuffer, sizeof(uint16_t) * nWLen); |
400 | 0 | break; |
401 | 0 | } |
402 | | |
403 | 49.5k | case NUMBER_OF_CHARS_ON_UINT8: |
404 | 49.5k | { |
405 | | // Write length as number of UTF16 characters |
406 | 49.5k | const auto nLenToWrite = std::min(static_cast<size_t>(255), nWLen); |
407 | 49.5k | if (nLenToWrite < nWLen) |
408 | 1 | { |
409 | 1 | CPLError(CE_Warning, CPLE_AppDefined, |
410 | 1 | "String %s truncated to %u UTF16 characters", pszStr, |
411 | 1 | static_cast<uint32_t>(nLenToWrite)); |
412 | 1 | nWLen = nLenToWrite; |
413 | 1 | } |
414 | 49.5k | WriteUInt8(abyBuffer, static_cast<uint8_t>(nLenToWrite)); |
415 | 49.5k | break; |
416 | 0 | } |
417 | | |
418 | 4.13k | case NUMBER_OF_CHARS_ON_UINT32: |
419 | 4.13k | { |
420 | | // Write length as number of UTF16 characters |
421 | 4.13k | WriteUInt32(abyBuffer, static_cast<uint32_t>(nWLen)); |
422 | 4.13k | break; |
423 | 0 | } |
424 | 54.6k | } |
425 | | |
426 | 54.6k | if (nWLen) |
427 | 29.8k | { |
428 | 29.8k | std::vector<uint16_t> anChars(nWLen); |
429 | 367k | for (size_t i = 0; i < nWLen; ++i) |
430 | 337k | { |
431 | 337k | anChars[i] = static_cast<uint16_t>(pszWStr[i]); |
432 | 337k | CPL_LSBPTR16(&anChars[i]); |
433 | 337k | } |
434 | 29.8k | const GByte *pabyInput = |
435 | 29.8k | reinterpret_cast<const GByte *>(anChars.data()); |
436 | 29.8k | abyBuffer.insert(abyBuffer.end(), pabyInput, |
437 | 29.8k | pabyInput + nWLen * sizeof(uint16_t)); |
438 | 29.8k | } |
439 | 54.6k | CPLFree(pszWStr); |
440 | 54.6k | } |
441 | | |
442 | | /************************************************************************/ |
443 | | /* FileGDBOGRDateToDoubleDate() */ |
444 | | /************************************************************************/ |
445 | | |
446 | | inline double FileGDBOGRDateToDoubleDate(const OGRField *psField, |
447 | | bool bConvertToGMT, |
448 | | bool bHighPrecision) |
449 | 0 | { |
450 | 0 | struct tm brokendowntime; |
451 | 0 | brokendowntime.tm_year = psField->Date.Year - 1900; |
452 | 0 | brokendowntime.tm_mon = psField->Date.Month - 1; |
453 | 0 | brokendowntime.tm_mday = psField->Date.Day; |
454 | 0 | brokendowntime.tm_hour = psField->Date.Hour; |
455 | 0 | brokendowntime.tm_min = psField->Date.Minute; |
456 | 0 | brokendowntime.tm_sec = bHighPrecision |
457 | 0 | ? static_cast<int>(psField->Date.Second) |
458 | 0 | : static_cast<int>(psField->Date.Second + 0.5); |
459 | 0 | GIntBig nUnixTime = CPLYMDHMSToUnixTime(&brokendowntime); |
460 | 0 | if (bConvertToGMT && psField->Date.TZFlag > 1 && |
461 | 0 | psField->Date.TZFlag != 100) |
462 | 0 | { |
463 | | // Convert to GMT |
464 | 0 | const int TZOffset = std::abs(psField->Date.TZFlag - 100) * 15; |
465 | 0 | const int TZHour = TZOffset / 60; |
466 | 0 | const int TZMinute = TZOffset - TZHour * 60; |
467 | 0 | const int nOffset = TZHour * 3600 + TZMinute * 60; |
468 | 0 | if (psField->Date.TZFlag >= 100) |
469 | 0 | nUnixTime -= nOffset; |
470 | 0 | else |
471 | 0 | nUnixTime += nOffset; |
472 | 0 | } |
473 | | // 25569: Number of days between 1899/12/30 00:00:00 and 1970/01/01 00:00:00 |
474 | 0 | return static_cast<double>( |
475 | 0 | nUnixTime + |
476 | 0 | (bHighPrecision |
477 | 0 | ? fmod(static_cast<double>(psField->Date.Second), 1.0) |
478 | 0 | : 0)) / |
479 | 0 | 3600.0 / 24.0 + |
480 | 0 | 25569.0; |
481 | 0 | } |
482 | | |
483 | | /************************************************************************/ |
484 | | /* FileGDBOGRTimeToDoubleTime() */ |
485 | | /************************************************************************/ |
486 | | |
487 | | inline double FileGDBOGRTimeToDoubleTime(const OGRField *psField) |
488 | 0 | { |
489 | 0 | return static_cast<double>(psField->Date.Hour * 3600 + |
490 | 0 | psField->Date.Minute * 60 + |
491 | 0 | psField->Date.Second) / |
492 | 0 | 3600.0 / 24.0; |
493 | 0 | } |
494 | | |
495 | | void FileGDBTablePrintError(const char *pszFile, int nLineNumber); |
496 | | |
497 | 2.27M | #define PrintError() FileGDBTablePrintError(__FILE__, __LINE__) |
498 | | |
499 | | /************************************************************************/ |
500 | | /* returnError() */ |
501 | | /************************************************************************/ |
502 | | |
503 | | #define returnError() \ |
504 | 2.27M | do \ |
505 | 2.27M | { \ |
506 | 2.27M | PrintError(); \ |
507 | 2.27M | return (errorRetValue); \ |
508 | 2.27M | } while (0) |
509 | | |
510 | | /************************************************************************/ |
511 | | /* returnErrorIf() */ |
512 | | /************************************************************************/ |
513 | | |
514 | | #define returnErrorIf(expr) \ |
515 | 22.9M | do \ |
516 | 22.9M | { \ |
517 | 22.9M | if ((expr)) \ |
518 | 22.9M | returnError(); \ |
519 | 22.9M | } while (0) |
520 | | |
521 | | /************************************************************************/ |
522 | | /* returnErrorAndCleanupIf() */ |
523 | | /************************************************************************/ |
524 | | |
525 | | #define returnErrorAndCleanupIf(expr, cleanup) \ |
526 | 7.99M | do \ |
527 | 7.99M | { \ |
528 | 9.04M | if ((expr)) \ |
529 | 7.99M | { \ |
530 | 1.60M | cleanup; \ |
531 | 1.60M | returnError(); \ |
532 | 1.60M | } \ |
533 | 7.99M | } while (0) |
534 | | |
535 | | } /* namespace OpenFileGDB */ |
536 | | |
537 | | #endif /* FILEGDBTABLE_PRIV_H_INCLUDED */ |