# HG changeset patch # User i7tiol # Date 1368872526 0 # Node ID efca9c2a8a7ec409941160f2e1acae15e5272e31 # Parent b8949643063c108f2cdff44d297a54c7b23cdcdf Added converters for network types. diff -r b8949643063c -r efca9c2a8a7e main/database/NEWS --- a/main/database/NEWS Fri May 17 19:36:12 2013 +0000 +++ b/main/database/NEWS Sat May 18 10:22:06 2013 +0000 @@ -1,6 +1,8 @@ ** pq_exec_params: For queries, information on postgresql data types of columns is also returned. + ** New converters for network types (cidr, inet, macaddr). + ** New converters for geometric types (point, lseg, (line,) box, circle, polygon, path). diff -r b8949643063c -r efca9c2a8a7e main/database/inst/pq_exec_params.m --- a/main/database/inst/pq_exec_params.m Fri May 17 19:36:12 2013 +0000 +++ b/main/database/inst/pq_exec_params.m Sat May 18 10:22:06 2013 +0000 @@ -176,6 +176,18 @@ ## @tab structure with fields @code{closed} (boolean, is path closed?) ## and @code{path} (geometric point data, see below). ## @tab yes +## @item inet +## @tab uint8 array of 4 or 5 elements for IPv4 or uint16 array of 8 or +## 9 elements for IPv6. 5th or 9th element, respectively, contain number +## of set bits in network mask, the default (if there are only 4 or 8 +## elements, respectively) is all bits set. +## @tab yes +## @item cidr +## @tab as inet +## @tab yes +## @item macaddr +## @tab uint8 array of 6 elements +## @tab yes ## @item any array ## @tab Structure with fields @code{data} (holding a cell-array with ## entries of a type corresponding to the Postgresql element type), diff -r b8949643063c -r efca9c2a8a7e main/database/src/converters.cc --- a/main/database/src/converters.cc Fri May 17 19:36:12 2013 +0000 +++ b/main/database/src/converters.cc Sat May 18 10:22:06 2013 +0000 @@ -25,11 +25,16 @@ #include +#include // for AF_INET, needed in network address types + #include "converters.h" #include "pq_connection.h" // remember to adjust OCT_PQ_NUM_CONVERTERS in converters.h +#define PGSQL_AF_INET6 (AF_INET + 1) // defined so in postgresql, no + // public header file available + // helper function for debugging void print_conv (oct_pq_conv_t *c) { @@ -1584,6 +1589,313 @@ /* end type unknown */ +// helpers for network types + +static inline +int to_octave_bin_cidr_inet (const char *c, octave_value &ov, bool &cidr) +{ + int8_t nb; + + if (*(c++) == AF_INET) + { + uint8NDArray a (dim_vector (5, 1), 0); + + a(4) = uint8_t (*(c++)); // number of set mask bits + + cidr = *(c++); + + nb = *(c++); + + if (nb < 0) + nb = 0; + + if (nb > 4) + { + error ("internal error: received too many bytes for AF_INET type"); + + return 1; + } + + for (int8_t i = 0; i < nb; i++, c++) + a(i) = uint8_t (*c); + + ov = octave_value (a); + } + else + { + uint16NDArray a (dim_vector (9, 1), 0); + + a(8) = uint16_t (uint8_t (*(c++))); // number of set mask bits + + cidr = *(c++); + + nb = *(c++); + + if (nb < 0) + nb = 0; + + if (nb > 16) + { + error ("internal error: received too many bytes for AF_INET6 type"); + + return 1; + } + + int8_t n = nb / 2; + bool odd = nb % 2; + + for (int8_t i = 0; i < n; i++, c += 2) + a(i) = uint16_t (be16toh (*((uint16_t *) c))); + + if (odd) + { + uint16_t tp = *c; + + a(n) = uint16_t (be16toh (tp)); + } + + ov = octave_value (a); + } + + return 0; +} + +static inline +int from_octave_bin_cidr_inet (const octave_value &ov, oct_pq_dynvec_t &val, + bool cidr) +{ + int nl = ov.numel (); + + uint8_t n_mbits; + + if (nl == 4 || nl == 5) + { + uint8NDArray a = ov.uint8_array_value (); + + if (error_state) + { + error ("can not convert octave_value to network type representation"); + return 1; + } + + if (nl == 5) + n_mbits = a(4).value (); + else + n_mbits = 32; + + val.push_back (AF_INET); + val.push_back (n_mbits); + val.push_back (cidr); + val.push_back (4); + for (int i = 0; i < 4; i++) + val.push_back (a(i).value ()); + } + else if (nl == 8 || nl == 9) + { + uint16NDArray a = ov.uint16_array_value (); + + if (error_state) + { + error ("can not convert octave_value to network type representation"); + return 1; + } + + if (nl == 9) + n_mbits = a(8).value (); + else + n_mbits = 128; + + val.push_back (PGSQL_AF_INET6); + val.push_back (n_mbits); + val.push_back (cidr); + val.push_back (16); + for (int i = 0; i < 8; i++) + { + OCT_PQ_PUT(val, uint16_t, htobe16(a(i).value ())) + } + } + else + { + error ("invalid network type representation"); + return 1; + } + + return 0; +} + +// end helpers for network types + +/* type cidr */ + +int to_octave_str_cidr (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + return 1; +} + +int to_octave_bin_cidr (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + bool cidr = false; + + if (to_octave_bin_cidr_inet (c, ov, cidr)) + return 1; + + if (! cidr) + { + error ("internal error: unexpected flag in cidr type"); + + return 1; + } + + return 0; +} + +int from_octave_str_cidr (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return 1; +} + +int from_octave_bin_cidr (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return from_octave_bin_cidr_inet (ov, val, true); +} + +oct_pq_conv_t conv_cidr = {0, + 0, + oct_pq_el_oids_t (), + oct_pq_conv_cache_t (), + false, + false, + false, + "cidr", + &to_octave_str_cidr, + &to_octave_bin_cidr, + &from_octave_str_cidr, + &from_octave_bin_cidr}; + +/* end type cidr */ + +/* type inet */ + +int to_octave_str_inet (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + return 1; +} + +int to_octave_bin_inet (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + bool cidr = false; + + if (to_octave_bin_cidr_inet (c, ov, cidr)) + return 1; + + if (cidr) + { + error ("internal error: unexpected flag in inet type"); + + return 1; + } + + return 0; +} + +int from_octave_str_inet (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return 1; +} + +int from_octave_bin_inet (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return from_octave_bin_cidr_inet (ov, val, false); +} + +oct_pq_conv_t conv_inet = {0, + 0, + oct_pq_el_oids_t (), + oct_pq_conv_cache_t (), + false, + false, + false, + "inet", + &to_octave_str_inet, + &to_octave_bin_inet, + &from_octave_str_inet, + &from_octave_bin_inet}; + +/* end type inet */ + +/* type macaddr */ + +int to_octave_str_macaddr (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + return 1; +} + +int to_octave_bin_macaddr (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + uint8NDArray a (dim_vector (6, 1)); + + for (int i = 0; i < 6; i++, c++) + a(i) = uint8_t (*c); + + ov = octave_value (a); + + return 0; +} + +int from_octave_str_macaddr (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return 1; +} + +int from_octave_bin_macaddr (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + uint8NDArray a = ov.uint8_array_value (); + + if (error_state) + { + error ("can not convert octave_value to macaddr representation"); + return 1; + } + + if (a.numel () != 6) + { + error ("macaddr representation must have 6 elements"); + return 1; + } + + for (int i = 0; i < 6; i++) + val.push_back (a(i).value ()); + + return 0; +} + +oct_pq_conv_t conv_macaddr = {0, + 0, + oct_pq_el_oids_t (), + oct_pq_conv_cache_t (), + false, + false, + false, + "macaddr", + &to_octave_str_macaddr, + &to_octave_bin_macaddr, + &from_octave_str_macaddr, + &from_octave_bin_macaddr}; + +/* end type macaddr */ + oct_pq_conv_t *t_conv_ptrs[OCT_PQ_NUM_CONVERTERS] = {&conv_bool, &conv_oid, &conv_float8, @@ -1610,6 +1922,9 @@ &conv_circle, &conv_polygon, &conv_path, - &conv_unknown}; + &conv_unknown, + &conv_cidr, + &conv_inet, + &conv_macaddr}; oct_pq_conv_ptrs_t conv_ptrs (OCT_PQ_NUM_CONVERTERS, t_conv_ptrs); diff -r b8949643063c -r efca9c2a8a7e main/database/src/converters.h --- a/main/database/src/converters.h Fri May 17 19:36:12 2013 +0000 +++ b/main/database/src/converters.h Sat May 18 10:22:06 2013 +0000 @@ -32,7 +32,7 @@ #include "wrap_endian.h" -#define OCT_PQ_NUM_CONVERTERS 27 +#define OCT_PQ_NUM_CONVERTERS 30 typedef std::vector oct_pq_dynvec_t;