Reorganized code
This commit is contained in:
parent
1bcea0d885
commit
9772c52322
|
@ -1,8 +1,6 @@
|
||||||
*.swp
|
*.swp
|
||||||
*.o
|
*.o
|
||||||
*.so
|
*.so
|
||||||
/tools/get_sizeof_phone_number
|
|
||||||
/pg_libphonenumber--*.sql
|
|
||||||
regression.diffs
|
regression.diffs
|
||||||
regression.out
|
regression.out
|
||||||
/results/
|
/results/
|
||||||
|
|
20
Makefile
20
Makefile
|
@ -4,8 +4,9 @@ CONFIG := release
|
||||||
# Extension packaging options
|
# Extension packaging options
|
||||||
EXTENSION := pg_libphonenumber
|
EXTENSION := pg_libphonenumber
|
||||||
version := 0.1.0
|
version := 0.1.0
|
||||||
extension_script := $(EXTENSION)--$(version).sql
|
# TODO: include scripts for all versions.
|
||||||
DATA_built := $(extension_script)
|
extension_script := sql/$(EXTENSION)--$(version).sql
|
||||||
|
DATA := $(extension_script)
|
||||||
REGRESS := regression
|
REGRESS := regression
|
||||||
|
|
||||||
# Build options
|
# Build options
|
||||||
|
@ -17,7 +18,7 @@ MODULE_big := pg_libphonenumber
|
||||||
OBJS := $(patsubst %.cpp,%.o,$(cpp_files))
|
OBJS := $(patsubst %.cpp,%.o,$(cpp_files))
|
||||||
|
|
||||||
# C flags
|
# C flags
|
||||||
PG_CPPFLAGS := -fPIC -std=c++11 -Isrc/
|
PG_CPPFLAGS := -fPIC -std=c++11 -Isrc/ -I/usr/include
|
||||||
ifeq ($(CONFIG),debug)
|
ifeq ($(CONFIG),debug)
|
||||||
PG_CPPFLAGS += -g -Og
|
PG_CPPFLAGS += -g -Og
|
||||||
else
|
else
|
||||||
|
@ -26,18 +27,13 @@ endif
|
||||||
# Extra libraries to link
|
# Extra libraries to link
|
||||||
SHLIB_LINK := -lphonenumber -lstdc++
|
SHLIB_LINK := -lphonenumber -lstdc++
|
||||||
|
|
||||||
# Clean options
|
|
||||||
EXTRA_CLEAN := $(extension_script) tools/get_sizeof_phone_number
|
|
||||||
|
|
||||||
# Load PGXS.
|
# Load PGXS.
|
||||||
PG_CONFIG := pg_config
|
PG_CONFIG := pg_config
|
||||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
include $(PGXS)
|
include $(PGXS)
|
||||||
|
|
||||||
# Build the extension script:
|
# Docker stuff
|
||||||
$(extension_script): $(EXTENSION).sql.template tools/get_sizeof_phone_number
|
.PHONY: docker-image
|
||||||
sed "s/SIZEOF_PHONE_NUMBER/$(shell tools/get_sizeof_phone_number)/" $< > $@
|
|
||||||
|
|
||||||
# Gets the size of a ShortPhoneNumber (which corresponds to the phone_number type in SQL)
|
docker-image: clean
|
||||||
tools/get_sizeof_phone_number: tools/get_sizeof_phone_number.cpp src/short_phone_number.h
|
docker build -t pg_libphonenumber .
|
||||||
$(CXX) $(PG_CPPFLAGS) $< -o $@
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ CREATE FUNCTION phone_number_send(phone_number) RETURNS bytea
|
||||||
AS 'pg_libphonenumber', 'phone_number_send';
|
AS 'pg_libphonenumber', 'phone_number_send';
|
||||||
|
|
||||||
CREATE TYPE phone_number (
|
CREATE TYPE phone_number (
|
||||||
INTERNALLENGTH = SIZEOF_PHONE_NUMBER,
|
INTERNALLENGTH = 8,
|
||||||
INPUT = phone_number_in,
|
INPUT = phone_number_in,
|
||||||
OUTPUT = phone_number_out,
|
OUTPUT = phone_number_out,
|
||||||
RECEIVE = phone_number_recv,
|
RECEIVE = phone_number_recv,
|
||||||
|
@ -42,8 +42,6 @@ CREATE FUNCTION phone_number_equal(phone_number, phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_equal';
|
AS 'pg_libphonenumber', 'phone_number_equal';
|
||||||
|
|
||||||
-- TODO: make these operators strict.
|
|
||||||
|
|
||||||
CREATE OPERATOR = (
|
CREATE OPERATOR = (
|
||||||
leftarg = phone_number,
|
leftarg = phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = phone_number,
|
||||||
|
@ -145,4 +143,3 @@ CREATE FUNCTION parse_phone_number(text, text) RETURNS phone_number
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'parse_phone_number';
|
AS 'pg_libphonenumber', 'parse_phone_number';
|
||||||
|
|
||||||
-- vim:syntax=sql
|
|
|
@ -4,11 +4,11 @@ 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) {
|
template<typename T> constexpr T get_masked(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)?
|
//TODO: support typeof(data) != typeof(value)?
|
||||||
template<typename T> constexpr T setMasked(T data, T value, size_t bits, size_t offset) {
|
template<typename T> constexpr T set_masked(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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ T clip(const T& n, const T& lower, const T& upper) {
|
||||||
/**
|
/**
|
||||||
* Converts a text object to a C-style string
|
* Converts a text object to a C-style string
|
||||||
*/
|
*/
|
||||||
static char* textToCString(const text* text) {
|
static char* text_to_c_string(const text* text) {
|
||||||
size_t len = VARSIZE(text) - VARHDRSZ;
|
size_t len = VARSIZE(text) - VARHDRSZ;
|
||||||
char* str = (char*)palloc(len + 1);
|
char* str = (char*)palloc(len + 1);
|
||||||
memcpy(str, VARDATA(text), len);
|
memcpy(str, VARDATA(text), len);
|
||||||
|
@ -41,7 +41,9 @@ static char* textToCString(const text* text) {
|
||||||
|
|
||||||
//Internal function used by phone_number_in and parse_phone_number
|
//Internal function used by phone_number_in and parse_phone_number
|
||||||
//TODO: take a std::string to minimize copying?
|
//TODO: take a std::string to minimize copying?
|
||||||
ShortPhoneNumber* parsePhoneNumber(const char* number_str, const char* country) {
|
//TODO: rename this so we're not relying on overloading to distinguish this from
|
||||||
|
// its extern "C" counterpart.
|
||||||
|
ShortPhoneNumber* parse_phone_number(const char* number_str, const char* country) {
|
||||||
PhoneNumber number;
|
PhoneNumber number;
|
||||||
ShortPhoneNumber* short_number;
|
ShortPhoneNumber* short_number;
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ extern "C" {
|
||||||
const char *number_str = PG_GETARG_CSTRING(0);
|
const char *number_str = PG_GETARG_CSTRING(0);
|
||||||
|
|
||||||
//TODO: use international format instead.
|
//TODO: use international format instead.
|
||||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, "US");
|
ShortPhoneNumber* number = parse_phone_number(number_str, "US");
|
||||||
if(number) {
|
if(number) {
|
||||||
PG_RETURN_POINTER(number);
|
PG_RETURN_POINTER(number);
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,10 +103,10 @@ extern "C" {
|
||||||
const text* number_text = PG_GETARG_TEXT_P(0);
|
const text* number_text = PG_GETARG_TEXT_P(0);
|
||||||
const text* country_text = PG_GETARG_TEXT_P(1);
|
const text* country_text = PG_GETARG_TEXT_P(1);
|
||||||
|
|
||||||
char* number_str = textToCString(number_text);
|
char* number_str = text_to_c_string(number_text);
|
||||||
char* country = textToCString(country_text);
|
char* country = text_to_c_string(country_text);
|
||||||
|
|
||||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, country);
|
ShortPhoneNumber* number = parse_phone_number(number_str, country);
|
||||||
//TODO: prevent leaks.
|
//TODO: prevent leaks.
|
||||||
pfree(number_str);
|
pfree(number_str);
|
||||||
pfree(country);
|
pfree(country);
|
||||||
|
|
|
@ -73,29 +73,32 @@ class ShortPhoneNumber {
|
||||||
}
|
}
|
||||||
|
|
||||||
google::protobuf::uint32 country_code() const {
|
google::protobuf::uint32 country_code() const {
|
||||||
return getMasked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
return get_masked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void country_code(google::protobuf::uint32 value) {
|
void country_code(google::protobuf::uint32 value) {
|
||||||
_data = setMasked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
_data = set_masked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
google::protobuf::uint64 national_number() const {
|
google::protobuf::uint64 national_number() const {
|
||||||
return getMasked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
return get_masked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void national_number(google::protobuf::uint64 value) {
|
void national_number(google::protobuf::uint64 value) {
|
||||||
_data = setMasked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
_data = set_masked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
google::protobuf::uint64 leading_zeros() const {
|
google::protobuf::uint64 leading_zeros() const {
|
||||||
return getMasked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
return get_masked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void leading_zeros(google::protobuf::uint64 value) {
|
void leading_zeros(google::protobuf::uint64 value) {
|
||||||
_data = setMasked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
_data = set_masked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
google::protobuf::uint64 _data;
|
google::protobuf::uint64 _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If the size changes, we'll need to update the extension script too.
|
||||||
|
static_assert(sizeof(ShortPhoneNumber) == 8);
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "short_phone_number.h"
|
|
||||||
|
|
||||||
int main(int argc, const char** argv) {
|
|
||||||
std::cout << sizeof(ShortPhoneNumber) << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue