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 Variant Data Type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
@ -25,6 +26,7 @@ static const char *variantTypeName[] =
"bool", // varTypeBool "bool", // varTypeBool
"double", // varTypeDouble, "double", // varTypeDouble,
"int", // varTypeInt "int", // varTypeInt
"int64", // varTypeInt64
"KeyValue", // varTypeKeyValue "KeyValue", // varTypeKeyValue
"String", // varTypeString "String", // varTypeString
"VariantList", // varTypeVariantList "VariantList", // varTypeVariantList
@ -87,6 +89,12 @@ varDup(const Variant *this)
break; break;
} }
case varTypeInt64:
{
result = varNewInt64(varInt64(this));
break;
}
case varTypeKeyValue: case varTypeKeyValue:
{ {
KeyValue *data = kvDup(varKv(this)); KeyValue *data = kvDup(varKv(this));
@ -145,6 +153,12 @@ varEq(const Variant *this1, const Variant *this2)
break; break;
} }
case varTypeInt64:
{
result = varInt64(this1) == varInt64(this2);
break;
}
case varTypeString: case varTypeString:
{ {
result = strEq(varStr(this1), varStr(this2)); result = strEq(varStr(this1), varStr(this2));
@ -213,6 +227,10 @@ varBoolForce(const Variant *this)
result = varInt(this) != 0; result = varInt(this) != 0;
break; break;
case varTypeInt64:
result = varInt64(this) != 0;
break;
case varTypeString: case varTypeString:
{ {
// List of false/true boolean string values. Note that false/true values must be equal. // List of false/true boolean string values. Note that false/true values must be equal.
@ -298,6 +316,12 @@ varDblForce(const Variant *this)
break; break;
} }
case varTypeInt64:
{
result = (double)varInt64(this);
break;
}
case varTypeString: case varTypeString:
{ {
sscanf(strPtr(varStr(this)), "%lf", &result); sscanf(strPtr(varStr(this)), "%lf", &result);
@ -342,6 +366,131 @@ varInt(const Variant *this)
return *((int *)varData(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 New key/value variant
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -374,45 +523,6 @@ varKv(const Variant *this)
return result; 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 New string variant
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -512,6 +622,12 @@ varStrForce(const Variant *this)
break; break;
} }
case varTypeInt64:
{
result = strNewFmt("%" PRId64, varInt64(this));
break;
}
case varTypeString: case varTypeString:
{ {
result = strDup(varStr(this)); result = strDup(varStr(this));
@ -602,6 +718,7 @@ varFree(Variant *this)
case varTypeBool: case varTypeBool:
case varTypeDouble: case varTypeDouble:
case varTypeInt: case varTypeInt:
case varTypeInt64:
break; break;
} }

View File

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

View File

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

View File

@ -4,6 +4,8 @@ C Test Harness
#ifndef TEST_COMMON_HARNESS_H #ifndef TEST_COMMON_HARNESS_H
#define TEST_COMMON_HARNESS_H #define TEST_COMMON_HARNESS_H
#include <inttypes.h>
#include "common/error.h" #include "common/error.h"
#include "common/type.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__); TEST_RESULT_DOUBLE_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_INT_PARAM(statement, resultExpected, typeOp, ...) \ #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, ...) \ #define TEST_RESULT_INT(statement, resultExpected, ...) \
TEST_RESULT_INT_PARAM(statement, resultExpected, ==, __VA_ARGS__); TEST_RESULT_INT_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_INT_NE(statement, resultExpected, ...) \ #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(varNewBool(false)), false, "force bool to bool");
TEST_RESULT_BOOL(varBoolForce(varNewInt(1)), true, "force int 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"); 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(varNewDbl(4.567)), 4.567, "force double to double");
TEST_RESULT_DOUBLE(varDblForce(varNewBool(false)), 0, "force bool 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(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_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"); 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_RESULT_INT(varIntForce(varNewBool(true)), 1, "force bool to int");
TEST_ERROR(varIntForce(varNewVarLstEmpty()), FormatError, "unable to force VariantList 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); integer = varNewInt(-1);
@ -107,6 +112,44 @@ testRun()
TEST_RESULT_BOOL(varEq(varNewInt(444), varNewInt(123)), false, "int, int not eq"); 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")) 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(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(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(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((double)999999999.123456))), "999999999.123456", "force double to string");
TEST_RESULT_STR(strPtr(varStrForce(varNewDbl(999.0))), "999", "force double to string"); TEST_RESULT_STR(strPtr(varStrForce(varNewDbl(999.0))), "999", "force double to string");