@@ -202,6 +202,43 @@ static inline bool IsLargeBinary(const char *format)
202
202
return format[0 ] == ARROW_LETTER_LARGE_BINARY && format[1 ] == 0 ;
203
203
}
204
204
205
+ static inline bool IsTimestampInternal (const char *format, char chType)
206
+ {
207
+ return format[0 ] == ' t' && format[1 ] == ' s' && format[2 ] == chType &&
208
+ format[3 ] == ' :' ;
209
+ }
210
+
211
+ static inline bool IsTimestampSeconds (const char *format)
212
+ {
213
+ return IsTimestampInternal (format, ' s' );
214
+ }
215
+
216
+ static inline bool IsTimestampMilliseconds (const char *format)
217
+ {
218
+ return IsTimestampInternal (format, ' m' );
219
+ }
220
+
221
+ static inline bool IsTimestampMicroseconds (const char *format)
222
+ {
223
+ return IsTimestampInternal (format, ' u' );
224
+ }
225
+
226
+ static inline bool IsTimestampNanoseconds (const char *format)
227
+ {
228
+ return IsTimestampInternal (format, ' n' );
229
+ }
230
+
231
+ static inline bool IsTimestamp (const char *format)
232
+ {
233
+ return IsTimestampSeconds (format) || IsTimestampMilliseconds (format) ||
234
+ IsTimestampMicroseconds (format) || IsTimestampNanoseconds (format);
235
+ }
236
+
237
+ static inline const char *GetTimestampTimezone (const char *format)
238
+ {
239
+ return IsTimestamp (format) ? format + strlen (" tm?:" ) : " " ;
240
+ }
241
+
205
242
/* ***********************************************************************/
206
243
/* TestBit() */
207
244
/* ***********************************************************************/
@@ -2820,20 +2857,9 @@ static bool IsHandledSchema(bool bTopLevel, const struct ArrowSchema *schema,
2820
2857
return true ;
2821
2858
}
2822
2859
2823
- const char *const apszHandledFormatsPrefix[] = {
2824
- " w:" , // fixed width binary
2825
- " tss:" , // timestamp [seconds] with timezone
2826
- " tsm:" , // timestamp [milliseconds] with timezone
2827
- " tsu:" , // timestamp [microseconds] with timezone
2828
- " tsn:" , // timestamp [nanoseconds] with timezone
2829
- };
2830
-
2831
- for (const char *pszHandledFormat : apszHandledFormatsPrefix)
2860
+ if (IsFixedWidthBinary (format) || IsTimestamp (format))
2832
2861
{
2833
- if (strncmp (format, pszHandledFormat, strlen (pszHandledFormat)) == 0 )
2834
- {
2835
- return true ;
2836
- }
2862
+ return true ;
2837
2863
}
2838
2864
2839
2865
CPLDebug (" OGR" , " Field %s has unhandled format '%s'" ,
@@ -4303,37 +4329,30 @@ static bool SetFieldForOtherFormats(OGRFeature &oFeature,
4303
4329
static_cast <GIntBig>(static_cast <const int64_t *>(
4304
4330
array->buffers [1 ])[nOffsettedIndex]));
4305
4331
}
4306
- else if (format[0 ] == ' t' && format[1 ] == ' s' && format[2 ] == ' s' &&
4307
- format[3 ] == ' :' ) // STARTS_WITH(format, "tss:")
4332
+ else if (IsTimestampSeconds (format))
4308
4333
{
4309
- // timestamp [seconds] with timezone
4310
4334
ArrowTimestampToOGRDateTime (
4311
4335
static_cast <const int64_t *>(array->buffers [1 ])[nOffsettedIndex], 1 ,
4312
- format + strlen ( " tss: " ), oFeature, iOGRFieldIndex);
4336
+ GetTimestampTimezone (format ), oFeature, iOGRFieldIndex);
4313
4337
}
4314
- else if (format[0 ] == ' t' && format[1 ] == ' s' && format[2 ] == ' m' &&
4315
- format[3 ] == ' :' ) // STARTS_WITH(format, "tsm:"))
4338
+ else if (IsTimestampMilliseconds (format))
4316
4339
{
4317
- // timestamp [milliseconds] with timezone
4318
4340
ArrowTimestampToOGRDateTime (
4319
4341
static_cast <const int64_t *>(array->buffers [1 ])[nOffsettedIndex],
4320
- 1000 , format + strlen ( " tsm: " ), oFeature, iOGRFieldIndex);
4342
+ 1000 , GetTimestampTimezone (format ), oFeature, iOGRFieldIndex);
4321
4343
}
4322
- else if (format[0 ] == ' t' && format[1 ] == ' s' && format[2 ] == ' u' &&
4323
- format[3 ] == ' :' ) // STARTS_WITH(format, "tsu:"))
4344
+ else if (IsTimestampMicroseconds (format))
4324
4345
{
4325
- // timestamp [microseconds] with timezone
4326
4346
ArrowTimestampToOGRDateTime (
4327
4347
static_cast <const int64_t *>(array->buffers [1 ])[nOffsettedIndex],
4328
- 1000 * 1000 , format + strlen (" tsu:" ), oFeature, iOGRFieldIndex);
4348
+ 1000 * 1000 , GetTimestampTimezone (format), oFeature,
4349
+ iOGRFieldIndex);
4329
4350
}
4330
- else if (format[0 ] == ' t' && format[1 ] == ' s' && format[2 ] == ' n' &&
4331
- format[3 ] == ' :' ) // STARTS_WITH(format, "tsn:"))
4351
+ else if (IsTimestampNanoseconds (format))
4332
4352
{
4333
- // timestamp [nanoseconds] with timezone
4334
4353
ArrowTimestampToOGRDateTime (
4335
4354
static_cast <const int64_t *>(array->buffers [1 ])[nOffsettedIndex],
4336
- 1000 * 1000 * 1000 , format + strlen ( " tsn: " ), oFeature,
4355
+ 1000 * 1000 * 1000 , GetTimestampTimezone (format ), oFeature,
4337
4356
iOGRFieldIndex);
4338
4357
}
4339
4358
else if (IsFixedSizeList (format))
@@ -5227,9 +5246,7 @@ static bool OGRCloneArrowArray(const struct ArrowSchema *schema,
5227
5246
}
5228
5247
else if (IsUInt64 (format) || IsInt64 (format) || IsFloat64 (format) ||
5229
5248
strcmp (format, " tdm" ) == 0 || strcmp (format, " ttu" ) == 0 ||
5230
- strcmp (format, " ttn" ) == 0 || strcmp (format, " tss" ) == 0 ||
5231
- STARTS_WITH (format, " tsm:" ) ||
5232
- STARTS_WITH (format, " tsu:" ) || STARTS_WITH (format, " tsn:" ))
5249
+ strcmp (format, " ttn" ) == 0 || IsTimestamp (format))
5233
5250
{
5234
5251
nEltSize = sizeof (uint64_t );
5235
5252
}
@@ -5692,21 +5709,9 @@ static bool IsArrowSchemaSupportedInternal(const struct ArrowSchema *schema,
5692
5709
}
5693
5710
}
5694
5711
5695
- if (IsFixedWidthBinary (format))
5712
+ if (IsFixedWidthBinary (format) || IsTimestamp (format) )
5696
5713
return true ;
5697
5714
5698
- const char *const apszTimestamps[] = {
5699
- " tss:" , // timestamp[s]
5700
- " tsm:" , // timestamp[ms]
5701
- " tsu:" , // timestamp[us]
5702
- " tsn:" // timestamp[ns]
5703
- };
5704
- for (const char *pszSupported : apszTimestamps)
5705
- {
5706
- if (STARTS_WITH (format, pszSupported))
5707
- return true ;
5708
- }
5709
-
5710
5715
AppendError (" Type '" + std::string (format) + " ' for field " +
5711
5716
osFieldPrefix + fieldName + " is not supported." );
5712
5717
return false ;
@@ -5991,10 +5996,7 @@ bool OGRLayer::CreateFieldFromArrowSchemaInternal(
5991
5996
return AddField (OFTString, OFSTJSON, 0 , 0 );
5992
5997
}
5993
5998
5994
- if (STARTS_WITH (format, " tss:" ) || // timestamp[s]
5995
- STARTS_WITH (format, " tsm:" ) || // timestamp[ms]
5996
- STARTS_WITH (format, " tsu:" ) || // timestamp[us]
5997
- STARTS_WITH (format, " tsn:" )) // timestamp[ns]
5999
+ if (IsTimestamp (format))
5998
6000
{
5999
6001
return AddField (OFTDateTime, OFSTNone, 0 , 0 );
6000
6002
}
@@ -6401,9 +6403,7 @@ static bool BuildOGRFieldInfo(
6401
6403
}
6402
6404
}
6403
6405
6404
- if (!bTypeOK &&
6405
- (STARTS_WITH (format, " tss:" ) || STARTS_WITH (format, " tsm:" ) ||
6406
- STARTS_WITH (format, " tsu:" ) || STARTS_WITH (format, " tsn:" )))
6406
+ if (!bTypeOK && IsTimestamp (format))
6407
6407
{
6408
6408
sInfo .eNominalFieldType = OFTDateTime;
6409
6409
if (eOGRType == sInfo .eNominalFieldType )
0 commit comments