Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build system, and add input from hex. #3

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all: sql/$(EXTENSION)--$(EXTVERSION).sql
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
cp $< $@

DATA = $(wildcard sql/*--*.sql) sql/$(EXTENSION)--$(EXTVERSION).sql
DATA = $(wildcard sql/*--*.sql)
EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql
endif

Expand Down
18 changes: 16 additions & 2 deletions sql/bignum.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,30 @@
--
CREATE TYPE bignum;

CREATE OR REPLACE FUNCTION bn_in(cstring)
CREATE OR REPLACE FUNCTION bn_in_dec(cstring)
RETURNS bignum
AS 'bignum', 'pgx_bignum_in'
AS 'bignum', 'pgx_bignum_in_dec'
LANGUAGE C IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION bn_in_hex(cstring)
RETURNS bignum
AS 'bignum', 'pgx_bignum_in_hex'
LANGUAGE C IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION bn_out(bignum)
RETURNS CSTRING
AS 'bignum', 'pgx_bignum_out'
LANGUAGE C IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION bn_out_hex(bignum)
RETURNS CSTRING AS 'bignum', 'pgx_bignum_out_hex'
LANGUAGE C IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION bn_in(cstring)
RETURNS bignum
AS 'bignum', 'pgx_bignum_in_asc'
LANGUAGE C IMMUTABLE STRICT;

CREATE TYPE bignum (
INPUT = bn_in,
OUTPUT = bn_out
Expand Down
100 changes: 97 additions & 3 deletions src/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "bignum.h"

static char * bignum_to_string(BIGNUM *bn);
static char * bignum_to_string_hex(BIGNUM *bn);

static BIGNUM * int4_to_bignum(int i) {
BIGNUM *bn;
Expand Down Expand Up @@ -67,17 +68,44 @@ PG_MODULE_MAGIC;
/**
* Read from cstring
*/
PG_FUNCTION_INFO_V1(pgx_bignum_in);

Datum pgx_bignum_in(PG_FUNCTION_ARGS) {
PG_FUNCTION_INFO_V1(pgx_bignum_in_asc);

Datum pgx_bignum_in_asc(PG_FUNCTION_ARGS) {
char *txt;
bytea *results;
BIGNUM *bn;

// check for null input
txt = PG_GETARG_CSTRING(0);
if (strlen(txt) == 0) {
PG_RETURN_NULL();
}

// convert to bignum
bn = BN_new();
BN_asc2bn(&bn, txt);

// write to binary format
results = bignum_to_bytea(bn);
BN_free(bn);

// return bytea
PG_RETURN_BYTEA_P(results);
}


PG_FUNCTION_INFO_V1(pgx_bignum_in_dec);

Datum pgx_bignum_in_dec(PG_FUNCTION_ARGS) {
char *txt;
int len;
bytea *results;
BIGNUM *bn;

// check for null input
txt = PG_GETARG_CSTRING(0);
if (txt == NULL || strlen(txt) == 0) {
if (strlen(txt) == 0) {
PG_RETURN_NULL();
}

Expand All @@ -87,6 +115,7 @@ Datum pgx_bignum_in(PG_FUNCTION_ARGS) {

if (strlen(txt) != len) {
elog(ERROR, "length mismatch - non-numeric values?");
BN_free(bn);
PG_RETURN_NULL();
}

Expand All @@ -98,6 +127,31 @@ Datum pgx_bignum_in(PG_FUNCTION_ARGS) {
PG_RETURN_BYTEA_P(results);
}

PG_FUNCTION_INFO_V1(pgx_bignum_in_hex);

Datum pgx_bignum_in_hex(PG_FUNCTION_ARGS) {
char *txt;
bytea *results;
BIGNUM *bn;

// check for null input
txt = PG_GETARG_CSTRING(0);
if (strlen(txt) == 0) {
PG_RETURN_NULL();
}

// convert to bignum
bn = BN_new();
BN_hex2bn(&bn, txt);

// write to binary format
results = bignum_to_bytea(bn);
BN_free(bn);

// return bytea
PG_RETURN_BYTEA_P(results);
}

/**
* Write to cstring.
*/
Expand All @@ -121,6 +175,26 @@ Datum pgx_bignum_out(PG_FUNCTION_ARGS) {
PG_RETURN_CSTRING(results);
}

PG_FUNCTION_INFO_V1(pgx_bignum_out_hex);
Datum pgx_bignum_out_hex(PG_FUNCTION_ARGS) {
bytea *raw;
char *results;
BIGNUM *bn;

// check for null value.
raw = PG_GETARG_BYTEA_P(0);
if (raw == NULL) {
PG_RETURN_NULL();
}

bn = bytea_to_bignum(raw);
results = bignum_to_string_hex(bn);
BN_free(bn);

PG_RETURN_CSTRING(results);
}


/**
* Read from int4
*/
Expand Down Expand Up @@ -816,6 +890,26 @@ static char * bignum_to_string(BIGNUM *bn) {
return results;
}

static char * bignum_to_string_hex(BIGNUM *bn) {
char *ptr, *results;
int len;

// convert bignum to decimal
ptr = BN_bn2hex(bn);

// create bytea results.
len = strlen(ptr);
results = palloc (1 + len);
strncpy(results, ptr, len);
results[len] = '\0';

// release memory
OPENSSL_free(ptr);

return results;
}


/**
* Convert BIGNUM to Datum (for return in records).
*/
Expand Down
7 changes: 5 additions & 2 deletions src/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ BIGNUM * bytea_to_bignum(bytea *raw);
bytea * bignum_to_bytea(BIGNUM *bn);

// big numbers
Datum pgx_bignum_in(PG_FUNCTION_ARGS);
Datum pgx_bignum_in_asc(PG_FUNCTION_ARGS);
Datum pgx_bignum_in_hex(PG_FUNCTION_ARGS);
Datum pgx_bignum_in_dec(PG_FUNCTION_ARGS);
Datum pgx_bignum_out(PG_FUNCTION_ARGS);
Datum pgx_bignum_out_hex(PG_FUNCTION_ARGS);

Datum BnGetDatum(BIGNUM *bn);

#ifdef __cplusplus
}
#endif

#endif
#endif