You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-15 01:04:37 +02:00
Add cvtZSubNTo*() functions.
These functions allow conversion from substrings without needing to create a String or a temporary buffer. httpDateToTime() no longer requires a temp mem context. Also improve handling of month search to avoid an allocation. httpUriDecode() no longer requires a temp mem context. jsonReadStr() no longer requires a temp mem context. pgLsnFromWalSegment() no longer requires a temp mem context. pgVersionFromStr() no longer requires a temp mem context. Also do a bit of refactoring. storageGcsCvtTime() no longer leaks six Strings per call. storageS3CvtTime() no longer leaks six Strings per call.
This commit is contained in:
@ -492,8 +492,7 @@ removeExpiredArchive(InfoBackup *infoBackup, bool timeBasedFullRetention, unsign
|
||||
if (strCmp(archiveId, strLstGet(listArchiveDisk, archiveIdx)) != 0)
|
||||
continue;
|
||||
|
||||
StringList *archiveSplit = strLstNewSplitZ(archiveId, "-");
|
||||
unsigned int archivePgId = cvtZToUInt(strZ(strLstGet(archiveSplit, 1)));
|
||||
const unsigned int archivePgId = cvtZToUInt(strrchr(strZ(archiveId), '-') + 1);
|
||||
|
||||
// From the global list of backups to retain, create a list of backups, oldest to newest, associated with
|
||||
// this archiveId (e.g. 9.4-1), e.g. If globalBackupRetention has 4F, 3F, 2F, 1F then
|
||||
|
@ -120,12 +120,12 @@ getEpoch(const String *targetTime)
|
||||
// Strip off the date and time and put the remainder into another string
|
||||
String *datetime = strSubN(targetTime, 0, 19);
|
||||
|
||||
int dtYear = cvtZToInt(strZ(strSubN(datetime, 0, 4)));
|
||||
int dtMonth = cvtZToInt(strZ(strSubN(datetime, 5, 2)));
|
||||
int dtDay = cvtZToInt(strZ(strSubN(datetime, 8, 2)));
|
||||
int dtHour = cvtZToInt(strZ(strSubN(datetime, 11, 2)));
|
||||
int dtMinute = cvtZToInt(strZ(strSubN(datetime, 14, 2)));
|
||||
int dtSecond = cvtZToInt(strZ(strSubN(datetime, 17, 2)));
|
||||
int dtYear = cvtZSubNToInt(strZ(datetime), 0, 4);
|
||||
int dtMonth = cvtZSubNToInt(strZ(datetime), 5, 2);
|
||||
int dtDay = cvtZSubNToInt(strZ(datetime), 8, 2);
|
||||
int dtHour = cvtZSubNToInt(strZ(datetime), 11, 2);
|
||||
int dtMinute = cvtZSubNToInt(strZ(datetime), 14, 2);
|
||||
int dtSecond = cvtZSubNToInt(strZ(datetime), 17, 2);
|
||||
|
||||
// Confirm date and time parts are valid
|
||||
datePartsValid(dtYear, dtMonth, dtDay);
|
||||
@ -145,13 +145,13 @@ getEpoch(const String *targetTime)
|
||||
String *timezoneOffset = strSub(timeTargetZone, (size_t)idxSign);
|
||||
|
||||
// Include the sign with the hour
|
||||
int tzHour = cvtZToInt(strZ(strSubN(timezoneOffset, 0, 3)));
|
||||
int tzHour = cvtZSubNToInt(strZ(timezoneOffset), 0, 3);
|
||||
int tzMinute = 0;
|
||||
|
||||
// If minutes are included in timezone offset then extract the minutes based on whether a colon separates them from
|
||||
// the hour
|
||||
if (strSize(timezoneOffset) > 3)
|
||||
tzMinute = cvtZToInt(strZ(strSubN(timezoneOffset, 3 + (strChr(timezoneOffset, ':') == -1 ? 0 : 1), 2)));
|
||||
tzMinute = cvtZSubNToInt(strZ(timezoneOffset), 3 + (strChr(timezoneOffset, ':') == -1 ? 0 : 1), 2);
|
||||
|
||||
result = epochFromParts(dtYear, dtMonth, dtDay, dtHour, dtMinute, dtSecond, tzOffsetSeconds(tzHour, tzMinute));
|
||||
}
|
||||
|
@ -18,38 +18,32 @@ static const char *const httpCommonMonthList[] =
|
||||
static const char *const httpCommonDayList[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
|
||||
time_t
|
||||
httpDateToTime(const String *lastModified)
|
||||
httpDateToTime(const String *const lastModified)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, lastModified);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
time_t result = 0;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Find the month
|
||||
const char *month = strZ(strSubN(lastModified, 8, 3));
|
||||
const char *const month = strZ(lastModified) + 8;
|
||||
unsigned int monthIdx = 0;
|
||||
|
||||
for (; monthIdx < LENGTH_OF(httpCommonMonthList); monthIdx++)
|
||||
{
|
||||
if (strcmp(month, httpCommonMonthList[monthIdx]) == 0)
|
||||
if (strncmp(month, httpCommonMonthList[monthIdx], 3) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (monthIdx == LENGTH_OF(httpCommonMonthList))
|
||||
THROW_FMT(FormatError, "invalid month '%s'", month);
|
||||
THROW_FMT(FormatError, "invalid month '%.3s'", month);
|
||||
|
||||
// Convert to time_t
|
||||
result = epochFromParts(
|
||||
cvtZToInt(strZ(strSubN(lastModified, 12, 4))), (int)monthIdx + 1, cvtZToInt(strZ(strSubN(lastModified, 5, 2))),
|
||||
cvtZToInt(strZ(strSubN(lastModified, 17, 2))), cvtZToInt(strZ(strSubN(lastModified, 20, 2))),
|
||||
cvtZToInt(strZ(strSubN(lastModified, 23, 2))), 0);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(TIME, result);
|
||||
FUNCTION_TEST_RETURN(
|
||||
TIME,
|
||||
epochFromParts(
|
||||
cvtZSubNToInt(strZ(lastModified), 12, 4), (int)monthIdx + 1, cvtZSubNToInt(strZ(lastModified), 5, 2),
|
||||
cvtZSubNToInt(strZ(lastModified), 17, 2), cvtZSubNToInt(strZ(lastModified), 20, 2),
|
||||
cvtZSubNToInt(strZ(lastModified), 23, 2), 0));
|
||||
}
|
||||
|
||||
String *
|
||||
@ -72,7 +66,7 @@ httpDateFromTime(const time_t time)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
httpUriDecode(const String *uri)
|
||||
httpUriDecode(const String *const uri)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, uri);
|
||||
@ -85,8 +79,6 @@ httpUriDecode(const String *uri)
|
||||
{
|
||||
result = strNew();
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Iterate all characters in the string
|
||||
for (unsigned uriIdx = 0; uriIdx < strSize(uri); uriIdx++)
|
||||
{
|
||||
@ -100,7 +92,7 @@ httpUriDecode(const String *uri)
|
||||
THROW_FMT(FormatError, "invalid escape sequence length in '%s'", strZ(uri));
|
||||
|
||||
// Convert hex digits
|
||||
uriChar = (char)cvtZToUIntBase(strZ(strSubN(uri, uriIdx + 1, 2)), 16);
|
||||
uriChar = (char)cvtZSubNToUIntBase(strZ(uri), uriIdx + 1, 2, 16);
|
||||
|
||||
// Skip to next character or escape
|
||||
uriIdx += 2;
|
||||
@ -109,8 +101,6 @@ httpUriDecode(const String *uri)
|
||||
strCatChr(result, uriChar);
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(STRING, result);
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
||||
if (spacePos != 3)
|
||||
THROW_FMT(FormatError, "response status '%s' must have a space after the status code", strZ(status));
|
||||
|
||||
this->pub.code = cvtZToUInt(strZ(strSubN(status, 0, (size_t)spacePos)));
|
||||
this->pub.code = cvtZSubNToUInt(strZ(status), 0, (size_t)spacePos);
|
||||
|
||||
// Read reason phrase. A missing reason phrase will be represented as an empty string.
|
||||
MEM_CONTEXT_OBJ_BEGIN(this)
|
||||
|
@ -248,6 +248,26 @@ cvtZToInt(const char *value)
|
||||
FUNCTION_TEST_RETURN(INT, cvtZToIntBase(value, 10));
|
||||
}
|
||||
|
||||
int
|
||||
cvtZSubNToIntBase(const char *const value, const size_t offset, const size_t size, const int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, value);
|
||||
FUNCTION_TEST_PARAM(SIZE, offset);
|
||||
FUNCTION_TEST_PARAM(SIZE, size);
|
||||
FUNCTION_TEST_PARAM(INT, base);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(value != NULL);
|
||||
|
||||
char buffer[CVT_BASE10_BUFFER_SIZE + 1];
|
||||
ASSERT(size <= CVT_BASE10_BUFFER_SIZE);
|
||||
strncpy(buffer, value + offset, size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(INT, cvtZToIntBase(buffer, base));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize)
|
||||
@ -292,6 +312,26 @@ cvtZToInt64(const char *value)
|
||||
FUNCTION_TEST_RETURN(INT64, cvtZToInt64Base(value, 10));
|
||||
}
|
||||
|
||||
int64_t
|
||||
cvtZSubNToInt64Base(const char *const value, const size_t offset, const size_t size, const int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, value);
|
||||
FUNCTION_TEST_PARAM(SIZE, offset);
|
||||
FUNCTION_TEST_PARAM(SIZE, size);
|
||||
FUNCTION_TEST_PARAM(INT, base);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(value != NULL);
|
||||
|
||||
char buffer[CVT_BASE10_BUFFER_SIZE + 1];
|
||||
ASSERT(size <= CVT_BASE10_BUFFER_SIZE);
|
||||
strncpy(buffer, value + offset, size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(INT64, cvtZToInt64Base(buffer, base));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
cvtModeToZ(mode_t value, char *buffer, size_t bufferSize)
|
||||
@ -434,6 +474,26 @@ cvtZToUInt(const char *value)
|
||||
FUNCTION_TEST_RETURN(UINT, cvtZToUIntBase(value, 10));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
cvtZSubNToUIntBase(const char *const value, const size_t offset, const size_t size, const int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, value);
|
||||
FUNCTION_TEST_PARAM(SIZE, offset);
|
||||
FUNCTION_TEST_PARAM(SIZE, size);
|
||||
FUNCTION_TEST_PARAM(INT, base);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(value != NULL);
|
||||
|
||||
char buffer[CVT_BASE10_BUFFER_SIZE + 1];
|
||||
ASSERT(size <= CVT_BASE10_BUFFER_SIZE);
|
||||
strncpy(buffer, value + offset, size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(UINT, cvtZToUIntBase(buffer, base));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize)
|
||||
@ -484,6 +544,26 @@ cvtZToUInt64(const char *value)
|
||||
FUNCTION_TEST_RETURN(UINT64, cvtZToUInt64Base(value, 10));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
cvtZSubNToUInt64Base(const char *const value, const size_t offset, const size_t size, const int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, value);
|
||||
FUNCTION_TEST_PARAM(SIZE, offset);
|
||||
FUNCTION_TEST_PARAM(SIZE, size);
|
||||
FUNCTION_TEST_PARAM(INT, base);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(value != NULL);
|
||||
|
||||
char buffer[CVT_BASE10_BUFFER_SIZE + 1];
|
||||
ASSERT(size <= CVT_BASE10_BUFFER_SIZE);
|
||||
strncpy(buffer, value + offset, size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(UINT64, cvtZToUInt64Base(buffer, base));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
cvtUInt64ToVarInt128(uint64_t value, uint8_t *const buffer, size_t *const bufferPos, const size_t bufferSize)
|
||||
|
@ -31,11 +31,26 @@ double cvtZToDouble(const char *value);
|
||||
size_t cvtIntToZ(int value, char *buffer, size_t bufferSize);
|
||||
int cvtZToInt(const char *value);
|
||||
int cvtZToIntBase(const char *value, int base);
|
||||
int cvtZSubNToIntBase(const char *value, size_t offset, size_t size, int base);
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
cvtZSubNToInt(const char *const value, const size_t offset, const size_t size)
|
||||
{
|
||||
return cvtZSubNToIntBase(value, offset, size, 10);
|
||||
}
|
||||
|
||||
// Convert int64 to zero-terminated string and vice versa
|
||||
size_t cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize);
|
||||
int64_t cvtZToInt64(const char *value);
|
||||
int64_t cvtZToInt64Base(const char *value, int base);
|
||||
int64_t cvtZSubNToInt64Base(const char *value, size_t offset, size_t size, int base);
|
||||
|
||||
__attribute__((always_inline)) static inline int64_t
|
||||
cvtZSubNToInt64(const char *const value, const size_t offset, const size_t size)
|
||||
{
|
||||
return cvtZSubNToInt64Base(value, offset, size, 10);
|
||||
}
|
||||
|
||||
|
||||
// Convert int32/64 to uint32/64 using zigzag encoding and vice versa. Zigzag encoding places the sign in the least significant bit
|
||||
// so that signed and unsigned values alternate, e.g. 0 = 0, -1 = 1, 1 = 2, -2 = 3, 2 = 4, -3 = 5, 3 = 6, etc. This moves as many
|
||||
@ -80,11 +95,25 @@ size_t cvtTimeToZ(time_t value, char *buffer, size_t bufferSize);
|
||||
size_t cvtUIntToZ(unsigned int value, char *buffer, size_t bufferSize);
|
||||
unsigned int cvtZToUInt(const char *value);
|
||||
unsigned int cvtZToUIntBase(const char *value, int base);
|
||||
unsigned int cvtZSubNToUIntBase(const char *value, size_t offset, size_t size, int base);
|
||||
|
||||
__attribute__((always_inline)) static inline unsigned int
|
||||
cvtZSubNToUInt(const char *const value, const size_t offset, const size_t size)
|
||||
{
|
||||
return cvtZSubNToUIntBase(value, offset, size, 10);
|
||||
}
|
||||
|
||||
// Convert uint64 to zero-terminated string and vice versa
|
||||
size_t cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize);
|
||||
uint64_t cvtZToUInt64(const char *value);
|
||||
uint64_t cvtZToUInt64Base(const char *value, int base);
|
||||
uint64_t cvtZSubNToUInt64Base(const char* value, size_t offset, size_t size, int base);
|
||||
|
||||
__attribute__((always_inline)) static inline uint64_t
|
||||
cvtZSubNToUInt64(const char *const value, const size_t offset, const size_t size)
|
||||
{
|
||||
return cvtZSubNToUInt64Base(value, offset, size, 10);
|
||||
}
|
||||
|
||||
// Convert uint64 to base-128 varint and vice versa
|
||||
void cvtUInt64ToVarInt128(uint64_t value, uint8_t *buffer, size_t *bufferPos, size_t bufferSize);
|
||||
|
@ -415,22 +415,19 @@ jsonReadNumber(JsonRead *const this)
|
||||
THROW_FMT(JsonFormatError, "invalid number at: %s", this->json);
|
||||
|
||||
const size_t size = digits + intSigned;
|
||||
|
||||
char working[CVT_BASE10_BUFFER_SIZE];
|
||||
strncpy(working, this->json, size);
|
||||
working[size] = '\0';
|
||||
|
||||
this->json += size;
|
||||
|
||||
// Return result
|
||||
if (intSigned)
|
||||
{
|
||||
FUNCTION_TEST_RETURN_TYPE(
|
||||
JsonReadNumberResult, (JsonReadNumberResult){.type = jsonNumberTypeI64, .value = {.i64 = cvtZToInt64(working)}});
|
||||
JsonReadNumberResult,
|
||||
(JsonReadNumberResult){.type = jsonNumberTypeI64, .value = {.i64 = cvtZSubNToInt64(this->json - size, 0, size)}});
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_TYPE(
|
||||
JsonReadNumberResult, (JsonReadNumberResult){.type = jsonNumberTypeU64, .value = {.u64 = cvtZToUInt64(working)}});
|
||||
JsonReadNumberResult,
|
||||
(JsonReadNumberResult){.type = jsonNumberTypeU64, .value = {.u64 = cvtZSubNToUInt64(this->json - size, 0, size)}});
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -962,8 +959,6 @@ jsonReadStr(JsonRead *const this)
|
||||
|
||||
String *const result = strNew();
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Skip the beginning "
|
||||
ASSERT(*this->json == '"');
|
||||
this->json++;
|
||||
@ -1029,7 +1024,7 @@ jsonReadStr(JsonRead *const this)
|
||||
|
||||
// Decode char
|
||||
this->json += 2;
|
||||
strCatChr(result, (char)cvtZToUIntBase(strZ(strNewZN(this->json, 2)), 16));
|
||||
strCatChr(result, (char)cvtZSubNToUIntBase(this->json, 0, 2, 16));
|
||||
this->json++;
|
||||
|
||||
break;
|
||||
@ -1060,8 +1055,6 @@ jsonReadStr(JsonRead *const this)
|
||||
|
||||
// Advance the character array pointer to the next element after the string
|
||||
this->json++;
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(STRING, result);
|
||||
}
|
||||
|
@ -509,17 +509,10 @@ pgLsnFromWalSegment(const String *const walSegment, const unsigned int walSegmen
|
||||
ASSERT(strSize(walSegment) == 24);
|
||||
ASSERT(walSegmentSize > 0);
|
||||
|
||||
uint64_t result;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
result =
|
||||
(cvtZToUInt64Base(strZ(strSubN(walSegment, 8, 8)), 16) << 32) +
|
||||
(cvtZToUInt64Base(strZ(strSubN(walSegment, 16, 8)), 16) * walSegmentSize);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(UINT64, result);
|
||||
FUNCTION_TEST_RETURN(
|
||||
UINT64,
|
||||
(cvtZSubNToUInt64Base(strZ(walSegment), 8, 8, 16) << 32) +
|
||||
(cvtZSubNToUInt64Base(strZ(walSegment), 16, 8, 16) * walSegmentSize));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -533,12 +526,7 @@ pgTimelineFromWalSegment(const String *const walSegment)
|
||||
ASSERT(walSegment != NULL);
|
||||
ASSERT(strSize(walSegment) == 24);
|
||||
|
||||
char buffer[9];
|
||||
|
||||
strncpy(buffer, strZ(walSegment), sizeof(buffer) - 1);
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(UINT32, cvtZToUIntBase(buffer, 16));
|
||||
FUNCTION_TEST_RETURN(UINT32, cvtZSubNToUIntBase(strZ(walSegment), 0, 8, 16));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -646,7 +634,7 @@ pgXactPath(unsigned int pgVersion)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
unsigned int
|
||||
pgVersionFromStr(const String *version)
|
||||
pgVersionFromStr(const String *const version)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, version);
|
||||
@ -654,33 +642,19 @@ pgVersionFromStr(const String *version)
|
||||
|
||||
ASSERT(version != NULL);
|
||||
|
||||
unsigned int result = 0;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// If format is not number.number (9.4) or number only (10) then error
|
||||
// If format not number.number (9.4) or number only (10) then error. No check for valid/supported PG version is on purpose.
|
||||
if (!regExpMatchOne(STRDEF("^[0-9]+[.]*[0-9]+$"), version))
|
||||
THROW_FMT(AssertError, "version %s format is invalid", strZ(version));
|
||||
|
||||
// If there is a dot set the major and minor versions, else just the major
|
||||
int idxStart = strChr(version, '.');
|
||||
unsigned int major;
|
||||
unsigned int minor = 0;
|
||||
// If there is no dot then only the major version is needed
|
||||
const int idxStart = strChr(version, '.');
|
||||
|
||||
if (idxStart != -1)
|
||||
{
|
||||
major = cvtZToUInt(strZ(strSubN(version, 0, (size_t)idxStart)));
|
||||
minor = cvtZToUInt(strZ(strSub(version, (size_t)idxStart + 1)));
|
||||
}
|
||||
else
|
||||
major = cvtZToUInt(strZ(version));
|
||||
if (idxStart == -1)
|
||||
FUNCTION_LOG_RETURN(UINT, cvtZToUInt(strZ(version)) * 10000);
|
||||
|
||||
// No check to see if valid/supported PG version is on purpose
|
||||
result = major * 10000 + minor * 100;
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(UINT, result);
|
||||
// Major and minor version are needed
|
||||
FUNCTION_LOG_RETURN(
|
||||
UINT, cvtZSubNToUInt(strZ(version), 0, (size_t)idxStart) * 10000 + cvtZToUInt(strZ(version) + (size_t)idxStart + 1) * 100);
|
||||
}
|
||||
|
||||
String *
|
||||
|
@ -488,7 +488,7 @@ General function for listing files to be used by other list routines
|
||||
// Helper to convert YYYY-MM-DDTHH:MM:SS.MSECZ format to time_t. This format is very nearly ISO-8601 except for the inclusion of
|
||||
// milliseconds, which are discarded here.
|
||||
static time_t
|
||||
storageGcsCvtTime(const String *time)
|
||||
storageGcsCvtTime(const String *const time)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, time);
|
||||
@ -497,9 +497,8 @@ storageGcsCvtTime(const String *time)
|
||||
FUNCTION_TEST_RETURN(
|
||||
TIME,
|
||||
epochFromParts(
|
||||
cvtZToInt(strZ(strSubN(time, 0, 4))), cvtZToInt(strZ(strSubN(time, 5, 2))),
|
||||
cvtZToInt(strZ(strSubN(time, 8, 2))), cvtZToInt(strZ(strSubN(time, 11, 2))),
|
||||
cvtZToInt(strZ(strSubN(time, 14, 2))), cvtZToInt(strZ(strSubN(time, 17, 2))), 0));
|
||||
cvtZSubNToInt(strZ(time), 0, 4), cvtZSubNToInt(strZ(time), 5, 2), cvtZSubNToInt(strZ(time), 8, 2),
|
||||
cvtZSubNToInt(strZ(time), 11, 2), cvtZSubNToInt(strZ(time), 14, 2), cvtZSubNToInt(strZ(time), 17, 2), 0));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -241,7 +241,7 @@ Convert YYYY-MM-DDTHH:MM:SS.MSECZ format to time_t. This format is very nearly I
|
||||
which are discarded here.
|
||||
***********************************************************************************************************************************/
|
||||
static time_t
|
||||
storageS3CvtTime(const String *time)
|
||||
storageS3CvtTime(const String *const time)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, time);
|
||||
@ -250,9 +250,8 @@ storageS3CvtTime(const String *time)
|
||||
FUNCTION_TEST_RETURN(
|
||||
TIME,
|
||||
epochFromParts(
|
||||
cvtZToInt(strZ(strSubN(time, 0, 4))), cvtZToInt(strZ(strSubN(time, 5, 2))),
|
||||
cvtZToInt(strZ(strSubN(time, 8, 2))), cvtZToInt(strZ(strSubN(time, 11, 2))),
|
||||
cvtZToInt(strZ(strSubN(time, 14, 2))), cvtZToInt(strZ(strSubN(time, 17, 2))), 0));
|
||||
cvtZSubNToInt(strZ(time), 0, 4), cvtZSubNToInt(strZ(time), 5, 2), cvtZSubNToInt(strZ(time), 8, 2),
|
||||
cvtZSubNToInt(strZ(time), 11, 2), cvtZSubNToInt(strZ(time), 14, 2), cvtZSubNToInt(strZ(time), 17, 2), 0));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -65,7 +65,7 @@ testBackupValidateCallback(void *callbackData, const StorageInfo *info)
|
||||
|
||||
if (bundle)
|
||||
{
|
||||
const uint64_t bundleId = cvtZToUInt64(strZ(strSub(info->name, sizeof("bundle"))));
|
||||
const uint64_t bundleId = cvtZToUInt64(strZ(info->name) + sizeof("bundle"));
|
||||
|
||||
for (unsigned int fileIdx = 0; fileIdx < manifestFileTotal(data->manifest); fileIdx++)
|
||||
{
|
||||
|
@ -73,8 +73,10 @@ testRun(void)
|
||||
cvtZToInt("-9223372036854775807"), FormatError, "unable to convert base 10 string '-9223372036854775807' to int");
|
||||
|
||||
TEST_RESULT_INT(cvtZToIntBase("-FF", 16), -255, "convert string to int");
|
||||
TEST_RESULT_INT(cvtZSubNToIntBase("XFFX", 1, 2, 16), 255, "convert string to int");
|
||||
TEST_RESULT_INT(cvtZToInt("0"), 0, "convert string to int");
|
||||
TEST_RESULT_INT(cvtZToInt("1234567890"), 1234567890, "convert string to int");
|
||||
TEST_RESULT_INT(cvtZSubNToInt("X1234567890X", 1, 10), 1234567890, "convert string to int");
|
||||
TEST_RESULT_INT(cvtZToInt("-1234567890"), -1234567890, "convert string to int");
|
||||
}
|
||||
|
||||
@ -155,7 +157,9 @@ testRun(void)
|
||||
TEST_ERROR(cvtZToUInt("5000000000"), FormatError, "unable to convert base 10 string '5000000000' to unsigned int");
|
||||
|
||||
TEST_RESULT_UINT(cvtZToUIntBase("FF", 16), 255, "convert string to unsigned int");
|
||||
TEST_RESULT_UINT(cvtZSubNToUIntBase("XFFX", 1, 2, 16), 255, "convert string to unsigned int");
|
||||
TEST_RESULT_UINT(cvtZToUInt("3333333333"), 3333333333U, "convert string to unsigned int");
|
||||
TEST_RESULT_UINT(cvtZSubNToUInt("X3333333333X", 1, 10), 3333333333U, "convert string to unsigned int");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -178,9 +182,11 @@ testRun(void)
|
||||
cvtZToInt64("9223372036854775808"), FormatError, "unable to convert base 10 string '9223372036854775808' to int64");
|
||||
|
||||
TEST_RESULT_INT(cvtZToInt64Base("-FF", 16), -255, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZSubNToInt64Base("X-FFX", 1, 3, 16), -255, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("0"), 0, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("9223372036854775807"), 9223372036854775807, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("-9223372036854775807"), -9223372036854775807, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZSubNToInt64("X-9223372036854775807X", 1, 20), -9223372036854775807, "convert string to int64");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -199,7 +205,9 @@ testRun(void)
|
||||
TEST_ERROR(cvtZToUInt64("-1"), FormatError, "unable to convert base 10 string '-1' to uint64");
|
||||
|
||||
TEST_RESULT_UINT(cvtZToUInt64Base("FF", 16), 255, "convert string to uint64");
|
||||
TEST_RESULT_UINT(cvtZSubNToUInt64Base("XFFX", 1, 2, 16), 255, "convert string to uint64");
|
||||
TEST_RESULT_UINT(cvtZToUInt64("18446744073709551615"), 18446744073709551615U, "convert string to uint64");
|
||||
TEST_RESULT_UINT(cvtZSubNToUInt64("X18446744073709551615X", 1, 20), 18446744073709551615U, "convert string to uint64");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
Reference in New Issue
Block a user