diff --git a/Makefile b/Makefile index 85a5d8a..062d74f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ extension_script := $(EXTENSION)--$(version).sql DATA_built := $(extension_script) MODULE_big := pg_libphonenumber -OBJS := pg_libphonenumber.o +OBJS := pg_libphonenumber.o short_phone_number.o PG_CPPFLAGS := -fPIC -std=c++11 -g SHLIB_LINK := -lphonenumber -lstdc++ diff --git a/pg_libphonenumber.cpp b/pg_libphonenumber.cpp index 457f168..4d810eb 100755 --- a/pg_libphonenumber.cpp +++ b/pg_libphonenumber.cpp @@ -9,9 +9,11 @@ extern "C" { #include "fmgr.h" } +#include "short_phone_number.h" + using namespace i18n::phonenumbers; -static thread_local PhoneNumberUtil *phoneUtil = PhoneNumberUtil::GetInstance(); +static const PhoneNumberUtil* const phoneUtil = PhoneNumberUtil::GetInstance(); static const char* parseErrorMessage(PhoneNumberUtil::ErrorType error) { using PNU = i18n::phonenumbers::PhoneNumberUtil; diff --git a/short_phone_number.cpp b/short_phone_number.cpp new file mode 100644 index 0000000..c132d5d --- /dev/null +++ b/short_phone_number.cpp @@ -0,0 +1,32 @@ +#include "short_phone_number.h" + +using namespace google::protobuf; +using namespace i18n::phonenumbers; + +PhoneNumberTooLongException::PhoneNumberTooLongException(const PhoneNumber& number, const char* msg) : _number(number), std::runtime_error(msg) {}; + +const PhoneNumberUtil* const PhoneNumberTooLongException::phoneUtil = PhoneNumberUtil::GetInstance(); + +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"); + } + _country_code = country_code; + + uint64 national_number = number.national_number(); + if(national_number > MAX_NATIONAL_NUMBER) { + throw PhoneNumberTooLongException(number, "National number is too long"); + } + _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"); + } + _leading_zeros = leading_zeros; + } else { + _leading_zeros = 0; + } +} diff --git a/short_phone_number.h b/short_phone_number.h new file mode 100644 index 0000000..8e30176 --- /dev/null +++ b/short_phone_number.h @@ -0,0 +1,31 @@ +#include + +#include "phonenumbers/phonenumberutil.h" + +class PhoneNumberTooLongException : std::runtime_error { + public: + PhoneNumberTooLongException(const i18n::phonenumbers::PhoneNumber& number, const char* msg); + + private: + i18n::phonenumbers::PhoneNumber _number; + + static const i18n::phonenumbers::PhoneNumberUtil* const phoneUtil; +}; + +struct ShortPhoneNumber { + public: + enum : size_t { + MAX_COUNTRY_CODE = 999, + //15 digits + MAX_NATIONAL_NUMBER = 999999999999999, + MAX_LEADING_ZEROS = 15, + }; + + ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number); + + private: + google::protobuf::uint32 _country_code : 10; + google::protobuf::uint64 _national_number : 50; + google::protobuf::uint32 _leading_zeros : 4; +}; +