From 5ea6cbe7435b90114042205e982059c7016d8b94 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Thu, 1 Feb 2024 22:50:33 +0100 Subject: [PATCH] Add wrapper functions for read/write of date attributes --- dbfopen.c | 65 +++++++++++++++++++++++++++++++++++++++++++--------- shapefil.h | 12 ++++++++++ shapelib.def | 2 ++ 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/dbfopen.c b/dbfopen.c index c90defc..fd4cd63 100644 --- a/dbfopen.c +++ b/dbfopen.c @@ -310,7 +310,6 @@ void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900, /************************************************************************/ DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess) - { SAHooks sHooks; @@ -1077,7 +1076,6 @@ double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord, const char SHPAPI_CALL1(*) DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField) - { return STATIC_CAST(const char *, DBFReadAttribute(psDBF, iRecord, iField, 'C')); @@ -1091,12 +1089,41 @@ const char SHPAPI_CALL1(*) const char SHPAPI_CALL1(*) DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField) - { return STATIC_CAST(const char *, DBFReadAttribute(psDBF, iRecord, iField, 'L')); } +/************************************************************************/ +/* DBFReadDateAttribute() */ +/* */ +/* Read a date attribute. */ +/************************************************************************/ + +SHPDate SHPAPI_CALL DBFReadDateAttribute(DBFHandle psDBF, int iRecord, + int iField) +{ + const char *pdateValue = DBFReadStringAttribute(psDBF, iRecord, iField); + + SHPDate date; + + if (pdateValue == SHPLIB_NULLPTR) + { + date.year = 0; + date.month = 0; + date.day = 0; + } + else if (3 != sscanf(pdateValue, "%4d%2d%2d", &date.year, &date.month, + &date.day)) + { + date.year = 0; + date.month = 0; + date.day = 0; + } + + return date; +} + /************************************************************************/ /* DBFIsValueNULL() */ /* */ @@ -1171,7 +1198,6 @@ int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField) /************************************************************************/ int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF) - { return (psDBF->nFields); } @@ -1183,7 +1209,6 @@ int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF) /************************************************************************/ int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF) - { return (psDBF->nRecords); } @@ -1199,7 +1224,6 @@ int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF) DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField, char *pszFieldName, int *pnWidth, int *pnDecimals) - { if (iField < 0 || iField >= psDBF->nFields) return (FTInvalid); @@ -1479,7 +1503,6 @@ int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord, int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord, int iField, const char *pszValue) - { return ( DBFWriteAttribute(psDBF, iRecord, iField, @@ -1493,7 +1516,6 @@ int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord, /************************************************************************/ int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField) - { return (DBFWriteAttribute(psDBF, iRecord, iField, SHPLIB_NULLPTR)); } @@ -1506,13 +1528,36 @@ int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField) int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord, int iField, const char lValue) - { return ( DBFWriteAttribute(psDBF, iRecord, iField, STATIC_CAST(void *, CONST_CAST(char *, &lValue)))); } +/************************************************************************/ +/* DBFWriteDateAttribute() */ +/* */ +/* Write a date attribute. */ +/************************************************************************/ + +int SHPAPI_CALL DBFWriteDateAttribute(DBFHandle psDBF, int iRecord, int iField, + const SHPDate *lValue) +{ + if (NULL == lValue) + return false; + /* check for supported digit range, but do not check for valid date */ + if (lValue->year < 0 || lValue->year > 9999) + return false; + if (lValue->month < 0 || lValue->month > 99) + return false; + if (lValue->day < 0 || lValue->day > 99) + return false; + char dateValue[9]; /* "yyyyMMdd\0" */ + snprintf(dateValue, sizeof(dateValue), "%04d%02d%02d", lValue->year, + lValue->month, lValue->day); + return (DBFWriteStringAttribute(psDBF, iRecord, iField, dateValue)); +} + /************************************************************************/ /* DBFWriteTuple() */ /* */ @@ -1572,7 +1617,6 @@ int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity, /************************************************************************/ const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity) - { if (hEntity < 0 || hEntity >= psDBF->nRecords) return SHPLIB_NULLPTR; @@ -1649,7 +1693,6 @@ DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename) /************************************************************************/ char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField) - { if (iField >= 0 && iField < psDBF->nFields) return psDBF->pachFieldType[iField]; diff --git a/shapefil.h b/shapefil.h index fcb8a5c..83a77b2 100644 --- a/shapefil.h +++ b/shapefil.h @@ -216,6 +216,13 @@ extern "C" typedef SHPInfo *SHPHandle; + typedef struct + { + int year; + int month; + int day; + } SHPDate; + /* -------------------------------------------------------------------- */ /* Shape types (nSHPType) */ /* -------------------------------------------------------------------- */ @@ -544,6 +551,8 @@ extern "C" DBFReadStringAttribute(DBFHandle hDBF, int iShape, int iField); const char SHPAPI_CALL1(*) DBFReadLogicalAttribute(DBFHandle hDBF, int iShape, int iField); + SHPDate SHPAPI_CALL DBFReadDateAttribute(DBFHandle hDBF, int iShape, + int iField); int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle hDBF, int iShape, int iField); int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle hDBF, int iShape, @@ -559,6 +568,9 @@ extern "C" int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle hDBF, int iShape, int iField, const char lFieldValue); + int SHPAPI_CALL DBFWriteDateAttribute(DBFHandle hDBF, int iShape, + int iField, + const SHPDate *dateFieldValue); int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, const void *pValue); const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity); diff --git a/shapelib.def b/shapelib.def index 90a912a..437d862 100644 --- a/shapelib.def +++ b/shapelib.def @@ -12,6 +12,7 @@ EXPORTS DBFIsRecordDeleted DBFMarkRecordDeleted DBFOpen + DBFReadDateAttribute DBFReadDoubleAttribute DBFReadIntegerAttribute DBFReadLogicalAttribute @@ -20,6 +21,7 @@ EXPORTS DBFSetLastModifiedDate DBFSetWriteEndOfFileChar DBFUpdateHeader + DBFWriteDateAttribute DBFWriteDoubleAttribute DBFWriteIntegerAttribute DBFWriteLogicalAttribute