Cleaned up indentation & comments
This commit is contained in:
parent
dcb98bede6
commit
8b94ed59e6
|
@ -6,7 +6,7 @@
|
|||
#include "phonenumbers/phonenumberutil.h"
|
||||
|
||||
extern "C" {
|
||||
#include "postgres.h"
|
||||
#include "postgres.h"
|
||||
}
|
||||
|
||||
#include "short_phone_number.h"
|
||||
|
@ -14,24 +14,24 @@ extern "C" {
|
|||
using namespace i18n::phonenumbers;
|
||||
|
||||
static const char* parseErrorMessage(PhoneNumberUtil::ErrorType error) {
|
||||
using PNU = i18n::phonenumbers::PhoneNumberUtil;
|
||||
switch(error) {
|
||||
case PNU::NO_PARSING_ERROR:
|
||||
return "Parsed successfully";
|
||||
case PNU::INVALID_COUNTRY_CODE_ERROR:
|
||||
return "Invalid country code";
|
||||
case PNU::NOT_A_NUMBER:
|
||||
return "String does not appear to contain a phone number";
|
||||
case PNU::TOO_SHORT_AFTER_IDD:
|
||||
return "Too short after IDD";
|
||||
case PNU::TOO_SHORT_NSN:
|
||||
return "National number is too short";
|
||||
case PNU::TOO_LONG_NSN:
|
||||
return "National number is too long";
|
||||
default:
|
||||
//We have some generic parsing error.
|
||||
return "Unable to parse number";
|
||||
}
|
||||
using PNU = i18n::phonenumbers::PhoneNumberUtil;
|
||||
switch(error) {
|
||||
case PNU::NO_PARSING_ERROR:
|
||||
return "Parsed successfully";
|
||||
case PNU::INVALID_COUNTRY_CODE_ERROR:
|
||||
return "Invalid country code";
|
||||
case PNU::NOT_A_NUMBER:
|
||||
return "String does not appear to contain a phone number";
|
||||
case PNU::TOO_SHORT_AFTER_IDD:
|
||||
return "Too short after IDD";
|
||||
case PNU::TOO_SHORT_NSN:
|
||||
return "National number is too short";
|
||||
case PNU::TOO_LONG_NSN:
|
||||
return "National number is too long";
|
||||
default:
|
||||
//We have some generic parsing error.
|
||||
return "Unable to parse number";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -39,9 +39,9 @@ static const char* parseErrorMessage(PhoneNumberUtil::ErrorType error) {
|
|||
*/
|
||||
|
||||
void reportOutOfMemory() {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of memory")));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of memory")));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,42 +51,42 @@ void reportOutOfMemory() {
|
|||
* depending on the type of the exception
|
||||
*/
|
||||
void reportException(const std::exception& exception) {
|
||||
{
|
||||
const std::bad_alloc* bad_alloc = dynamic_cast<const std::bad_alloc*>(&exception);
|
||||
if(bad_alloc != nullptr) {
|
||||
reportOutOfMemory();
|
||||
return;
|
||||
}
|
||||
const PhoneNumberTooLongException* too_long =
|
||||
dynamic_cast<const PhoneNumberTooLongException*>(&exception);
|
||||
if(too_long != nullptr) {
|
||||
std::string phone_number = too_long->number_string();
|
||||
phone_number += '\0';
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("phone number '%s' is too long", phone_number.data()),
|
||||
errdetail("%s", exception.what())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
const std::bad_alloc* bad_alloc = dynamic_cast<const std::bad_alloc*>(&exception);
|
||||
if(bad_alloc != nullptr) {
|
||||
reportOutOfMemory();
|
||||
return;
|
||||
}
|
||||
const PhoneNumberTooLongException* too_long =
|
||||
dynamic_cast<const PhoneNumberTooLongException*>(&exception);
|
||||
if(too_long != nullptr) {
|
||||
std::string phone_number = too_long->number_string();
|
||||
phone_number += '\0';
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("phone number '%s' is too long", phone_number.data()),
|
||||
errdetail("%s", exception.what())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If we don't have a special way to handle this exception, report
|
||||
//a generic error.
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("C++ exception: %s", typeid(exception).name()),
|
||||
errdetail("%s", exception.what())));
|
||||
//If we don't have a special way to handle this exception, report
|
||||
//a generic error.
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("C++ exception: %s", typeid(exception).name()),
|
||||
errdetail("%s", exception.what())));
|
||||
}
|
||||
|
||||
void reportParseError(const char* phone_number, PhoneNumberUtil::ErrorType err) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("unable to parse '%s' as a phone number", phone_number),
|
||||
errdetail("%s", parseErrorMessage(err))));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("unable to parse '%s' as a phone number", phone_number),
|
||||
errdetail("%s", parseErrorMessage(err))));
|
||||
}
|
||||
|
||||
void logInfo(const char* msg) {
|
||||
ereport(INFO,
|
||||
(errcode(ERRCODE_SUCCESSFUL_COMPLETION),
|
||||
errmsg("%s", msg)));
|
||||
ereport(INFO,
|
||||
(errcode(ERRCODE_SUCCESSFUL_COMPLETION),
|
||||
errmsg("%s", msg)));
|
||||
}
|
||||
|
|
6
mask.h
6
mask.h
|
@ -1,14 +1,14 @@
|
|||
#include <algorithm>
|
||||
|
||||
template<typename T> constexpr T mask(size_t bits, size_t offset = 0) {
|
||||
return (((T)1 << bits) - 1) << offset;
|
||||
return (((T)1 << bits) - 1) << offset;
|
||||
}
|
||||
|
||||
template<typename T> constexpr T getMasked(T data, size_t bits, size_t offset) {
|
||||
return (data >> offset) & mask<T>(bits);
|
||||
return (data >> offset) & mask<T>(bits);
|
||||
}
|
||||
|
||||
//TODO: support typeof(data) != typeof(value)?
|
||||
template<typename T> constexpr T setMasked(T data, T value, size_t bits, size_t offset) {
|
||||
return (data & ~mask<T>(bits, offset)) | ((value & mask<T>(bits)) << offset);
|
||||
return (data & ~mask<T>(bits, offset)) | ((value & mask<T>(bits)) << offset);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include "phonenumbers/phonenumberutil.h"
|
||||
|
||||
extern "C" {
|
||||
#include "postgres.h"
|
||||
#include "libpq/pqformat.h"
|
||||
#include "fmgr.h"
|
||||
#include "postgres.h"
|
||||
#include "libpq/pqformat.h"
|
||||
#include "fmgr.h"
|
||||
}
|
||||
|
||||
#include "error_handling.h"
|
||||
|
@ -16,6 +16,9 @@ using namespace i18n::phonenumbers;
|
|||
|
||||
static const PhoneNumberUtil* const phoneUtil = PhoneNumberUtil::GetInstance();
|
||||
|
||||
/**
|
||||
* Clips a value to the given (inclusive) range
|
||||
*/
|
||||
template <typename T>
|
||||
T clip(const T& n, const T& lower, const T& upper) {
|
||||
return std::max(lower, std::min(n, upper));
|
||||
|
@ -25,36 +28,39 @@ T clip(const T& n, const T& lower, const T& upper) {
|
|||
* Utility functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts a text object to a C-style string
|
||||
*/
|
||||
static char* textToCString(const text* text) {
|
||||
size_t len = VARSIZE(text) - VARHDRSZ;
|
||||
char* str = (char*)palloc(len + 1);
|
||||
memcpy(str, VARDATA(text), len);
|
||||
str[len] = '\0';
|
||||
return str;
|
||||
size_t len = VARSIZE(text) - VARHDRSZ;
|
||||
char* str = (char*)palloc(len + 1);
|
||||
memcpy(str, VARDATA(text), len);
|
||||
str[len] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
//Internal function used by phone_number_in and parse_phone_number
|
||||
//TODO: take a std::string to minimize copying?
|
||||
ShortPhoneNumber* parsePhoneNumber(const char* number_str, const char* country) {
|
||||
PhoneNumber number;
|
||||
ShortPhoneNumber* short_number;
|
||||
PhoneNumber number;
|
||||
ShortPhoneNumber* short_number;
|
||||
|
||||
short_number = (ShortPhoneNumber*)palloc0(sizeof(ShortPhoneNumber));
|
||||
if(short_number == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
short_number = (ShortPhoneNumber*)palloc0(sizeof(ShortPhoneNumber));
|
||||
if(short_number == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
PhoneNumberUtil::ErrorType error;
|
||||
error = phoneUtil->Parse(number_str, country, &number);
|
||||
if(error == PhoneNumberUtil::NO_PARSING_ERROR) {
|
||||
//Initialize short_number using placement new.
|
||||
new(short_number) ShortPhoneNumber(number);
|
||||
return short_number;
|
||||
} else {
|
||||
reportParseError(number_str, error);
|
||||
return nullptr;
|
||||
}
|
||||
//TODO: check number validity.
|
||||
PhoneNumberUtil::ErrorType error;
|
||||
error = phoneUtil->Parse(number_str, country, &number);
|
||||
if(error == PhoneNumberUtil::NO_PARSING_ERROR) {
|
||||
//Initialize short_number using placement new.
|
||||
new(short_number) ShortPhoneNumber(number);
|
||||
return short_number;
|
||||
} else {
|
||||
reportParseError(number_str, error);
|
||||
return nullptr;
|
||||
}
|
||||
//TODO: check number validity.
|
||||
}
|
||||
|
||||
//TODO: check null args (PG_ARGISNULL) and make non-strict?
|
||||
|
@ -64,232 +70,232 @@ ShortPhoneNumber* parsePhoneNumber(const char* number_str, const char* country)
|
|||
*/
|
||||
|
||||
extern "C" {
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_in);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_in);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_in(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const char *number_str = PG_GETARG_CSTRING(0);
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_in(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const char *number_str = PG_GETARG_CSTRING(0);
|
||||
|
||||
//TODO: use international format instead.
|
||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, "US");
|
||||
if(number) {
|
||||
PG_RETURN_POINTER(number);
|
||||
} else {
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(parse_phone_number);
|
||||
//TODO: use international format instead.
|
||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, "US");
|
||||
if(number) {
|
||||
PG_RETURN_POINTER(number);
|
||||
} else {
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
parse_phone_number(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const text* number_text = PG_GETARG_TEXT_P(0);
|
||||
const text* country_text = PG_GETARG_TEXT_P(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(parse_phone_number);
|
||||
|
||||
char* number_str = textToCString(number_text);
|
||||
char* country = textToCString(country_text);
|
||||
PGDLLEXPORT Datum
|
||||
parse_phone_number(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const text* number_text = PG_GETARG_TEXT_P(0);
|
||||
const text* country_text = PG_GETARG_TEXT_P(1);
|
||||
|
||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, country);
|
||||
//TODO: prevent leaks.
|
||||
pfree(number_str);
|
||||
pfree(country);
|
||||
if(number) {
|
||||
PG_RETURN_POINTER(number);
|
||||
} else {
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
}
|
||||
char* number_str = textToCString(number_text);
|
||||
char* country = textToCString(country_text);
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_out);
|
||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, country);
|
||||
//TODO: prevent leaks.
|
||||
pfree(number_str);
|
||||
pfree(country);
|
||||
if(number) {
|
||||
PG_RETURN_POINTER(number);
|
||||
} else {
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_out(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* short_number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
PhoneNumber number = *short_number;
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_out);
|
||||
|
||||
std::string formatted;
|
||||
phoneUtil->Format(number, PhoneNumberUtil::INTERNATIONAL, &formatted);
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_out(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* short_number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
PhoneNumber number = *short_number;
|
||||
|
||||
//Copy the formatted number to a C-style string.
|
||||
//We must use the PostgreSQL allocator, not new/malloc.
|
||||
size_t len = formatted.length();
|
||||
char* result = (char*)palloc(len + 1);
|
||||
if(result == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
memcpy(result, formatted.data(), len);
|
||||
result[len] = '\0';
|
||||
std::string formatted;
|
||||
phoneUtil->Format(number, PhoneNumberUtil::INTERNATIONAL, &formatted);
|
||||
|
||||
PG_RETURN_CSTRING(result);
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
//Copy the formatted number to a C-style string.
|
||||
//We must use the PostgreSQL allocator, not new/malloc.
|
||||
size_t len = formatted.length();
|
||||
char* result = (char*)palloc(len + 1);
|
||||
if(result == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
memcpy(result, formatted.data(), len);
|
||||
result[len] = '\0';
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_CSTRING(result);
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_recv);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_recv(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
|
||||
ShortPhoneNumber* number;
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_recv);
|
||||
|
||||
number = (ShortPhoneNumber*)palloc(sizeof(ShortPhoneNumber));
|
||||
//TODO: make portable (fix endianness issues, etc.).
|
||||
pq_copymsgbytes(buf, (char*)number, sizeof(ShortPhoneNumber));
|
||||
PG_RETURN_POINTER(number);
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_recv(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
|
||||
ShortPhoneNumber* number;
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
number = (ShortPhoneNumber*)palloc(sizeof(ShortPhoneNumber));
|
||||
//TODO: make portable (fix endianness issues, etc.).
|
||||
pq_copymsgbytes(buf, (char*)number, sizeof(ShortPhoneNumber));
|
||||
PG_RETURN_POINTER(number);
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_send);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_send(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber *number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
StringInfoData buf;
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_send);
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
pq_sendbytes(&buf, (const char*)number, sizeof(ShortPhoneNumber));
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_send(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber *number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
StringInfoData buf;
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
pq_begintypsend(&buf);
|
||||
pq_sendbytes(&buf, (const char*)number, sizeof(ShortPhoneNumber));
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
} catch (const std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_equal);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_equal);
|
||||
|
||||
PG_RETURN_BOOL(*number1 == *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(*number1 == *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_not_equal);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_not_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_not_equal);
|
||||
|
||||
PG_RETURN_BOOL(*number1 != *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_not_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(*number1 != *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) < 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) < 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less_or_equal);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less_or_equal);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) <= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) <= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) > 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) > 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater_or_equal);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater_or_equal);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) >= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) >= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_cmp);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_cmp(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_cmp);
|
||||
|
||||
int64 compared = number1->compare_fast(*number2);
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_cmp(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_INT32(clip<int64>(compared, -1, 1));
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
int64 compared = number1->compare_fast(*number2);
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
PG_RETURN_INT32(clip<int64>(compared, -1, 1));
|
||||
} catch(std::exception& e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ CREATE TYPE phone_number (
|
|||
--Cast definitions
|
||||
|
||||
CREATE CAST (phone_number AS text)
|
||||
WITH INOUT;
|
||||
WITH INOUT;
|
||||
|
||||
--Operator definitions
|
||||
|
||||
|
@ -42,16 +42,18 @@ CREATE FUNCTION phone_number_equal(phone_number, phone_number) RETURNS bool
|
|||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_equal';
|
||||
|
||||
-- TODO: make these operators strict.
|
||||
|
||||
CREATE OPERATOR = (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_equal,
|
||||
commutator = =,
|
||||
negator = <>,
|
||||
restrict = eqsel,
|
||||
join = eqjoinsel,
|
||||
hashes = true,
|
||||
merges = true
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_equal,
|
||||
commutator = =,
|
||||
negator = <>,
|
||||
restrict = eqsel,
|
||||
join = eqjoinsel,
|
||||
hashes = true,
|
||||
merges = true
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_not_equal(phone_number, phone_number) RETURNS bool
|
||||
|
@ -59,13 +61,13 @@ CREATE FUNCTION phone_number_not_equal(phone_number, phone_number) RETURNS bool
|
|||
AS 'pg_libphonenumber', 'phone_number_not_equal';
|
||||
|
||||
CREATE OPERATOR <> (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_not_equal,
|
||||
commutator = <>,
|
||||
negator = =,
|
||||
restrict = neqsel,
|
||||
join = neqjoinsel
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_not_equal,
|
||||
commutator = <>,
|
||||
negator = =,
|
||||
restrict = neqsel,
|
||||
join = neqjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_less(phone_number, phone_number) RETURNS bool
|
||||
|
@ -73,13 +75,13 @@ CREATE FUNCTION phone_number_less(phone_number, phone_number) RETURNS bool
|
|||
AS 'pg_libphonenumber', 'phone_number_less';
|
||||
|
||||
CREATE OPERATOR < (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less,
|
||||
commutator = >,
|
||||
negator = >=,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less,
|
||||
commutator = >,
|
||||
negator = >=,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_less_or_equal(phone_number, phone_number) RETURNS bool
|
||||
|
@ -87,13 +89,13 @@ CREATE FUNCTION phone_number_less_or_equal(phone_number, phone_number) RETURNS b
|
|||
AS 'pg_libphonenumber', 'phone_number_less_or_equal';
|
||||
|
||||
CREATE OPERATOR <= (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less_or_equal,
|
||||
commutator = >=,
|
||||
negator = >,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less_or_equal,
|
||||
commutator = >=,
|
||||
negator = >,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_greater(phone_number, phone_number) RETURNS bool
|
||||
|
@ -101,13 +103,13 @@ CREATE FUNCTION phone_number_greater(phone_number, phone_number) RETURNS bool
|
|||
AS 'pg_libphonenumber', 'phone_number_greater';
|
||||
|
||||
CREATE OPERATOR > (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater,
|
||||
commutator = >,
|
||||
negator = <=,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater,
|
||||
commutator = >,
|
||||
negator = <=,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_greater_or_equal(phone_number, phone_number) RETURNS bool
|
||||
|
@ -115,13 +117,13 @@ CREATE FUNCTION phone_number_greater_or_equal(phone_number, phone_number) RETURN
|
|||
AS 'pg_libphonenumber', 'phone_number_greater_or_equal';
|
||||
|
||||
CREATE OPERATOR >= (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater_or_equal,
|
||||
commutator = >=,
|
||||
negator = <,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater_or_equal,
|
||||
commutator = >=,
|
||||
negator = <,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_cmp(phone_number, phone_number) RETURNS integer
|
||||
|
@ -129,13 +131,13 @@ CREATE FUNCTION phone_number_cmp(phone_number, phone_number) RETURNS integer
|
|||
AS 'pg_libphonenumber', 'phone_number_cmp';
|
||||
|
||||
CREATE OPERATOR CLASS phone_number_ops
|
||||
DEFAULT FOR TYPE phone_number USING btree AS
|
||||
OPERATOR 1 <,
|
||||
OPERATOR 2 <=,
|
||||
OPERATOR 3 =,
|
||||
OPERATOR 4 >=,
|
||||
OPERATOR 5 >,
|
||||
FUNCTION 1 phone_number_cmp(phone_number, phone_number);
|
||||
DEFAULT FOR TYPE phone_number USING btree AS
|
||||
OPERATOR 1 <,
|
||||
OPERATOR 2 <=,
|
||||
OPERATOR 3 =,
|
||||
OPERATOR 4 >=,
|
||||
OPERATOR 5 >,
|
||||
FUNCTION 1 phone_number_cmp(phone_number, phone_number);
|
||||
|
||||
--General functions
|
||||
|
||||
|
|
|
@ -6,45 +6,44 @@ using namespace i18n::phonenumbers;
|
|||
const PhoneNumberUtil* const PhoneNumberTooLongException::phoneUtil = PhoneNumberUtil::GetInstance();
|
||||
|
||||
PhoneNumberTooLongException::PhoneNumberTooLongException(const PhoneNumber& number, const char* msg) :
|
||||
_number(number), std::runtime_error(msg) {};
|
||||
_number(number), std::runtime_error(msg) {};
|
||||
|
||||
std::string PhoneNumberTooLongException::number_string() const {
|
||||
std::string formatted;
|
||||
phoneUtil->Format(number(), PhoneNumberUtil::INTERNATIONAL, &formatted);
|
||||
return formatted;
|
||||
std::string formatted;
|
||||
phoneUtil->Format(number(), PhoneNumberUtil::INTERNATIONAL, &formatted);
|
||||
return formatted;
|
||||
}
|
||||
|
||||
ShortPhoneNumber::ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number) {
|
||||
uint32 country_code = number.country_code();
|
||||
if(country_code > MAX_COUNTRY_CODE) {
|
||||
throw PhoneNumberTooLongException(number, "Country code is too long");
|
||||
}
|
||||
this->country_code(country_code);
|
||||
uint32 country_code = number.country_code();
|
||||
if(country_code > MAX_COUNTRY_CODE) {
|
||||
throw PhoneNumberTooLongException(number, "Country code is too long");
|
||||
}
|
||||
this->country_code(country_code);
|
||||
|
||||
uint64 national_number = number.national_number();
|
||||
if(national_number > MAX_NATIONAL_NUMBER) {
|
||||
throw PhoneNumberTooLongException(number, "National number is too long");
|
||||
}
|
||||
this->national_number(national_number);
|
||||
uint64 national_number = number.national_number();
|
||||
if(national_number > MAX_NATIONAL_NUMBER) {
|
||||
throw PhoneNumberTooLongException(number, "National number is too long");
|
||||
}
|
||||
this->national_number(national_number);
|
||||
|
||||
if(number.has_number_of_leading_zeros()) {
|
||||
uint32 leading_zeros = number.number_of_leading_zeros();
|
||||
if(leading_zeros > MAX_LEADING_ZEROS) {
|
||||
throw PhoneNumberTooLongException(number, "Too many leading zeros");
|
||||
}
|
||||
this->leading_zeros(leading_zeros);
|
||||
} else {
|
||||
this->leading_zeros(0);
|
||||
}
|
||||
if(number.has_number_of_leading_zeros()) {
|
||||
uint32 leading_zeros = number.number_of_leading_zeros();
|
||||
if(leading_zeros > MAX_LEADING_ZEROS) {
|
||||
throw PhoneNumberTooLongException(number, "Too many leading zeros");
|
||||
}
|
||||
this->leading_zeros(leading_zeros);
|
||||
} else {
|
||||
this->leading_zeros(0);
|
||||
}
|
||||
}
|
||||
|
||||
ShortPhoneNumber::operator PhoneNumber() const {
|
||||
PhoneNumber number;
|
||||
number.set_country_code(country_code());
|
||||
number.set_national_number(national_number());
|
||||
int32 leading_zeros = this->leading_zeros();
|
||||
number.set_italian_leading_zero(leading_zeros > 0);
|
||||
number.set_number_of_leading_zeros(leading_zeros);
|
||||
return number;
|
||||
PhoneNumber number;
|
||||
number.set_country_code(country_code());
|
||||
number.set_national_number(national_number());
|
||||
int32 leading_zeros = this->leading_zeros();
|
||||
number.set_italian_leading_zero(leading_zeros > 0);
|
||||
number.set_number_of_leading_zeros(leading_zeros);
|
||||
return number;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,94 +6,96 @@
|
|||
#include "mask.h"
|
||||
|
||||
class PhoneNumberTooLongException : public std::runtime_error {
|
||||
public:
|
||||
PhoneNumberTooLongException(const i18n::phonenumbers::PhoneNumber& number, const char* msg);
|
||||
public:
|
||||
PhoneNumberTooLongException(const i18n::phonenumbers::PhoneNumber& number, const char* msg);
|
||||
|
||||
i18n::phonenumbers::PhoneNumber number() const {
|
||||
return _number;
|
||||
}
|
||||
i18n::phonenumbers::PhoneNumber number() const {
|
||||
return _number;
|
||||
}
|
||||
|
||||
//TODO: just get the number string from which the PhoneNumber was parsed? (if it exists...)
|
||||
std::string number_string() const;
|
||||
private:
|
||||
i18n::phonenumbers::PhoneNumber _number;
|
||||
//TODO: just get the number string from which the PhoneNumber was parsed? (if it exists...)
|
||||
std::string number_string() const;
|
||||
private:
|
||||
i18n::phonenumbers::PhoneNumber _number;
|
||||
|
||||
static const i18n::phonenumbers::PhoneNumberUtil* const phoneUtil;
|
||||
static const i18n::phonenumbers::PhoneNumberUtil* const phoneUtil;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores a phone number (packed into a 64-bit integer)
|
||||
*/
|
||||
class ShortPhoneNumber {
|
||||
public:
|
||||
enum : size_t {
|
||||
MAX_COUNTRY_CODE = 999,
|
||||
MAX_LEADING_ZEROS = 15,
|
||||
//15 digits
|
||||
MAX_NATIONAL_NUMBER = 999999999999999,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_BITS = 10,
|
||||
LEADING_ZEROS_BITS = 4,
|
||||
NATIONAL_NUMBER_BITS = 50,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_OFFSET = 0,
|
||||
LEADING_ZEROS_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
||||
NATIONAL_NUMBER_OFFSET = LEADING_ZEROS_OFFSET + LEADING_ZEROS_BITS,
|
||||
};
|
||||
public:
|
||||
enum : size_t {
|
||||
MAX_COUNTRY_CODE = 999,
|
||||
MAX_LEADING_ZEROS = 15,
|
||||
//15 digits
|
||||
MAX_NATIONAL_NUMBER = 999999999999999,
|
||||
};
|
||||
|
||||
ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number);
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_BITS = 10,
|
||||
LEADING_ZEROS_BITS = 4,
|
||||
NATIONAL_NUMBER_BITS = 50,
|
||||
};
|
||||
|
||||
bool operator == (const ShortPhoneNumber other) const {
|
||||
return this->_data == other._data;
|
||||
}
|
||||
|
||||
bool operator != (const ShortPhoneNumber other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_OFFSET = 0,
|
||||
LEADING_ZEROS_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
||||
NATIONAL_NUMBER_OFFSET = LEADING_ZEROS_OFFSET + LEADING_ZEROS_BITS,
|
||||
};
|
||||
|
||||
operator i18n::phonenumbers::PhoneNumber() const;
|
||||
ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number);
|
||||
|
||||
/*
|
||||
* Compares to another PhoneNumber using a fast collation heuristic
|
||||
*
|
||||
* May not produce intuitive results for numbers with the same
|
||||
* country code but different lengths
|
||||
*
|
||||
* Returns:
|
||||
* - <0 (if a < b)
|
||||
* - 0 (if a == b)
|
||||
* - >0 (if a > b)
|
||||
*/
|
||||
google::protobuf::int64 compare_fast(ShortPhoneNumber other) const {
|
||||
return other._data - this->_data;
|
||||
}
|
||||
bool operator == (const ShortPhoneNumber other) const {
|
||||
return this->_data == other._data;
|
||||
}
|
||||
|
||||
google::protobuf::uint32 country_code() const {
|
||||
return getMasked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||
}
|
||||
bool operator != (const ShortPhoneNumber other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void country_code(google::protobuf::uint32 value) {
|
||||
_data = setMasked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||
}
|
||||
operator i18n::phonenumbers::PhoneNumber() const;
|
||||
|
||||
google::protobuf::uint64 national_number() const {
|
||||
return getMasked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||
}
|
||||
/*
|
||||
* Compares to another PhoneNumber using a fast collation heuristic
|
||||
*
|
||||
* May not produce intuitive results for numbers with the same
|
||||
* country code but different lengths
|
||||
*
|
||||
* Returns:
|
||||
* - <0 (if a < b)
|
||||
* - 0 (if a == b)
|
||||
* - >0 (if a > b)
|
||||
*/
|
||||
google::protobuf::int64 compare_fast(ShortPhoneNumber other) const {
|
||||
return other._data - this->_data;
|
||||
}
|
||||
|
||||
void national_number(google::protobuf::uint64 value) {
|
||||
_data = setMasked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||
}
|
||||
google::protobuf::uint32 country_code() const {
|
||||
return getMasked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||
}
|
||||
|
||||
google::protobuf::uint64 leading_zeros() const {
|
||||
return getMasked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||
}
|
||||
void country_code(google::protobuf::uint32 value) {
|
||||
_data = setMasked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||
}
|
||||
|
||||
void leading_zeros(google::protobuf::uint64 value) {
|
||||
_data = setMasked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||
}
|
||||
google::protobuf::uint64 national_number() const {
|
||||
return getMasked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||
}
|
||||
|
||||
private:
|
||||
google::protobuf::uint64 _data;
|
||||
void national_number(google::protobuf::uint64 value) {
|
||||
_data = setMasked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||
}
|
||||
|
||||
google::protobuf::uint64 leading_zeros() const {
|
||||
return getMasked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||
}
|
||||
|
||||
void leading_zeros(google::protobuf::uint64 value) {
|
||||
_data = setMasked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||
}
|
||||
|
||||
private:
|
||||
google::protobuf::uint64 _data;
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
#include "../short_phone_number.h"
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
std::cout << sizeof(ShortPhoneNumber) << std::endl;
|
||||
return 0;
|
||||
std::cout << sizeof(ShortPhoneNumber) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue