1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Add int64 variant type.

This commit is contained in:
David Steele 2018-02-09 13:52:02 -05:00
parent 1659598cfe
commit 305a3e1761
5 changed files with 209 additions and 41 deletions

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Variant Data Type
***********************************************************************************************************************************/
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
@ -25,6 +26,7 @@ static const char *variantTypeName[] =
"bool", // varTypeBool
"double", // varTypeDouble,
"int", // varTypeInt
"int64", // varTypeInt64
"KeyValue", // varTypeKeyValue
"String", // varTypeString
"VariantList", // varTypeVariantList
@ -87,6 +89,12 @@ varDup(const Variant *this)
break;
}
case varTypeInt64:
{
result = varNewInt64(varInt64(this));
break;
}
case varTypeKeyValue:
{
KeyValue *data = kvDup(varKv(this));
@ -145,6 +153,12 @@ varEq(const Variant *this1, const Variant *this2)
break;
}
case varTypeInt64:
{
result = varInt64(this1) == varInt64(this2);
break;
}
case varTypeString:
{
result = strEq(varStr(this1), varStr(this2));
@ -213,6 +227,10 @@ varBoolForce(const Variant *this)
result = varInt(this) != 0;
break;
case varTypeInt64:
result = varInt64(this) != 0;
break;
case varTypeString:
{
// List of false/true boolean string values. Note that false/true values must be equal.
@ -298,6 +316,12 @@ varDblForce(const Variant *this)
break;
}
case varTypeInt64:
{
result = (double)varInt64(this);
break;
}
case varTypeString:
{
sscanf(strPtr(varStr(this)), "%lf", &result);
@ -342,6 +366,131 @@ varInt(const Variant *this)
return *((int *)varData(this));
}
/***********************************************************************************************************************************
Return int regardless of variant type
***********************************************************************************************************************************/
int
varIntForce(const Variant *this)
{
int result = 0;
switch (this->type)
{
case varTypeBool:
{
result = varBool(this);
break;
}
case varTypeInt:
{
result = varInt(this);
break;
}
case varTypeInt64:
{
int64 resultTest = varInt64(this);
if (resultTest > 2147483647 || resultTest < -2147483648)
THROW(
AssertError, "unable to convert %s %" PRId64 " to %s", variantTypeName[this->type], resultTest,
variantTypeName[varTypeInt]);
result = (int)resultTest;
break;
}
case varTypeString:
{
result = atoi(strPtr(varStr(this)));
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
THROW(FormatError, "unable to convert str '%s' to int", strPtr(varStr(this)));
break;
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
}
return result;
}
/***********************************************************************************************************************************
New int64 variant
***********************************************************************************************************************************/
Variant *
varNewInt64(int64 data)
{
return varNewInternal(varTypeInt64, (void *)&data, sizeof(data));
}
/***********************************************************************************************************************************
Return int64
***********************************************************************************************************************************/
int64
varInt64(const Variant *this)
{
// Only valid for int
if (this->type != varTypeInt64)
THROW(AssertError, "variant type is not %s", variantTypeName[varTypeInt64]);
// Get the int
return *((int64 *)varData(this));
}
/***********************************************************************************************************************************
Return int64 regardless of variant type
***********************************************************************************************************************************/
int64
varInt64Force(const Variant *this)
{
int64 result = 0;
switch (this->type)
{
case varTypeBool:
{
result = varBool(this);
break;
}
case varTypeInt:
{
result = (int64)varInt(this);
break;
}
case varTypeInt64:
{
result = varInt64(this);
break;
}
case varTypeString:
{
result = atoll(strPtr(varStr(this)));
char buffer[32];
snprintf(buffer, sizeof(buffer), "%" PRId64, result);
if (strcmp(strPtr(varStr(this)), buffer) != 0)
THROW(
FormatError, "unable to convert %s '%s' to %s", variantTypeName[varTypeString], strPtr(varStr(this)),
variantTypeName[varTypeInt64]);
break;
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]);
}
return result;
}
/***********************************************************************************************************************************
New key/value variant
***********************************************************************************************************************************/
@ -374,45 +523,6 @@ varKv(const Variant *this)
return result;
}
/***********************************************************************************************************************************
Return int regardless of variant type
***********************************************************************************************************************************/
int
varIntForce(const Variant *this)
{
int result = 0;
switch (this->type)
{
case varTypeBool:
{
result = varBool(this);
break;
}
case varTypeInt:
{
result = varInt(this);
break;
}
case varTypeString:
{
result = atoi(strPtr(varStr(this)));
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
THROW(FormatError, "unable to convert str '%s' to int", strPtr(varStr(this)));
break;
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
}
return result;
}
/***********************************************************************************************************************************
New string variant
***********************************************************************************************************************************/
@ -512,6 +622,12 @@ varStrForce(const Variant *this)
break;
}
case varTypeInt64:
{
result = strNewFmt("%" PRId64, varInt64(this));
break;
}
case varTypeString:
{
result = strDup(varStr(this));
@ -602,6 +718,7 @@ varFree(Variant *this)
case varTypeBool:
case varTypeDouble:
case varTypeInt:
case varTypeInt64:
break;
}

View File

@ -14,6 +14,7 @@ typedef enum
varTypeBool,
varTypeDouble,
varTypeInt,
varTypeInt64,
varTypeKeyValue,
varTypeString,
varTypeVariantList,
@ -43,6 +44,10 @@ Variant *varNewInt(int data);
int varInt(const Variant *this);
int varIntForce(const Variant *this);
Variant *varNewInt64(int64 data);
int64 varInt64(const Variant *this);
int64 varInt64Force(const Variant *this);
Variant *varNewKv();
KeyValue *varKv(const Variant *this);

View File

@ -214,7 +214,7 @@ my $oTestDef =
},
{
&TESTDEF_NAME => 'type-variant',
&TESTDEF_TOTAL => 6,
&TESTDEF_TOTAL => 7,
&TESTDEF_C => true,
&TESTDEF_COVERAGE =>

View File

@ -4,6 +4,8 @@ C Test Harness
#ifndef TEST_COMMON_HARNESS_H
#define TEST_COMMON_HARNESS_H
#include <inttypes.h>
#include "common/error.h"
#include "common/type.h"
@ -216,7 +218,7 @@ Macros to ease the use of common data types
TEST_RESULT_DOUBLE_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_INT_PARAM(statement, resultExpected, typeOp, ...) \
TEST_RESULT(statement, resultExpected, int, "%d", TEST_TYPE_FORMAT, typeOp, TEST_TYPE_COMPARE, __VA_ARGS__);
TEST_RESULT(statement, resultExpected, int64, "%" PRId64, TEST_TYPE_FORMAT, typeOp, TEST_TYPE_COMPARE, __VA_ARGS__);
#define TEST_RESULT_INT(statement, resultExpected, ...) \
TEST_RESULT_INT_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_INT_NE(statement, resultExpected, ...) \

View File

@ -26,6 +26,7 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_BOOL(varBoolForce(varNewBool(false)), false, "force bool to bool");
TEST_RESULT_BOOL(varBoolForce(varNewInt(1)), true, "force int to bool");
TEST_RESULT_BOOL(varBoolForce(varNewInt64(false)), false, "force int64 to bool");
TEST_ERROR(varBoolForce(varNewVarLstEmpty()), FormatError, "unable to force VariantList to bool");
@ -62,6 +63,7 @@ testRun()
TEST_RESULT_DOUBLE(varDblForce(varNewDbl(4.567)), 4.567, "force double to double");
TEST_RESULT_DOUBLE(varDblForce(varNewBool(false)), 0, "force bool to double");
TEST_RESULT_DOUBLE(varDblForce(varNewInt(123)), 123, "force int to double");
TEST_RESULT_DOUBLE(varDblForce(varNewInt64(999999999999)), 999999999999, "force int64 to double");
TEST_RESULT_DOUBLE(varDblForce(varNewStr(strNew("879.01"))), 879.01, "force String to double");
TEST_ERROR(varDblForce(varNewStr(strNew("AAA"))), FormatError, "unable to force String 'AAA' to double");
@ -86,6 +88,9 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_INT(varIntForce(varNewBool(true)), 1, "force bool to int");
TEST_ERROR(varIntForce(varNewVarLstEmpty()), FormatError, "unable to force VariantList to int");
TEST_RESULT_INT(varIntForce(varNewInt64(999)), 999, "force int64 to int");
TEST_ERROR(varIntForce(varNewInt64(2147483648)), AssertError, "unable to convert int64 2147483648 to int");
TEST_ERROR(varIntForce(varNewInt64(-2147483649)), AssertError, "unable to convert int64 -2147483649 to int");
// -------------------------------------------------------------------------------------------------------------------------
integer = varNewInt(-1);
@ -107,6 +112,44 @@ testRun()
TEST_RESULT_BOOL(varEq(varNewInt(444), varNewInt(123)), false, "int, int not eq");
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("int64"))
{
Variant *integer = varNewInt64(44);
TEST_RESULT_INT(varInt64(integer), 44, "int64 variant");
TEST_RESULT_INT(varInt64Force(integer), 44, "force int64 to int64");
varFree(integer);
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_INT(varInt64Force(varNewBool(true)), 1, "force bool to int64");
TEST_RESULT_INT(varInt64Force(varNewInt(2147483647)), 2147483647, "force int to int64");
TEST_RESULT_INT(varInt64Force(varNewStrZ("9223372036854775807")), 9223372036854775807L, "force str to int64");
TEST_ERROR(
varInt64Force(varNewStrZ("9923372036854775807")), FormatError,
"unable to convert String '9923372036854775807' to int64");
TEST_ERROR(varInt64Force(varNewVarLstEmpty()), FormatError, "unable to force VariantList to int64");
// -------------------------------------------------------------------------------------------------------------------------
integer = varNewInt64(-1);
integer->type = varTypeString;
TEST_ERROR(varInt64(integer), AssertError, "variant type is not int64");
integer->type = varTypeInt;
varFree(integer);
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_INT(varInt64(varDup(varNewInt64(88976))), 88976, "dup int64");
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_BOOL(varEq(NULL, NULL), true, "null, null eq");
TEST_RESULT_BOOL(varEq(NULL, varNewInt64(123)), false, "null, int64 not eq");
TEST_RESULT_BOOL(varEq(varNewInt64(9223372036854775807L), varNewInt64(9223372036854775807L)), true, "int64, int64 eq");
TEST_RESULT_BOOL(varEq(varNewInt64(444), varNewInt64(123)), false, "int64, int64 not eq");
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("keyValue"))
{
@ -167,6 +210,7 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_STR(strPtr(varStrForce(varNewStr(strNew("teststring")))), "teststring", "force string to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewInt(999))), "999", "force int to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewInt64(9223372036854775807L))), "9223372036854775807", "force int64 to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewDbl(999.1234))), "999.1234", "force double to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewDbl((double)999999999.123456))), "999999999.123456", "force double to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewDbl(999.0))), "999", "force double to string");