changeset 11710:4f5471a9bce6 octave-forge

Added converters for bit string types.
author i7tiol
date Sat, 18 May 2013 13:22:09 +0000
parents 4f95e5c4a57a
children c53226c6cd5c
files main/database/NEWS main/database/doc/README-postgresql main/database/doc/dev-postgresql/conversions.tex main/database/inst/pq_exec_params.m main/database/src/converters.cc main/database/src/converters.h
diffstat 6 files changed, 140 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/main/database/NEWS	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/NEWS	Sat May 18 13:22:09 2013 +0000
@@ -1,6 +1,8 @@
  ** pq_exec_params: For queries, information on postgresql data types
     of columns is also returned.
 
+ ** New converters for bit string types (bit, varbit).
+
  ** New converters for network types (cidr, inet, macaddr).
 
  ** New converters for geometric types (point, lseg, (line,) box,
--- a/main/database/doc/README-postgresql	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/doc/README-postgresql	Sat May 18 13:22:09 2013 +0000
@@ -44,19 +44,14 @@
 State:
 
 
-Not all base types implemented yet. All commands should work with
-pq_exec_params, copy from stdin and copy to stdout are implemented
-from/to files at client side, copy from stdin is also possible from an
-Octave cell-array. There are no plans to implement copy to stdout into
-an Octave cell-array (does not safely fit into the framework, and
-select should be equivalent). The whole framework including conversion
-of composite and array types with the resulting possible recursion,
-enum types, and a number of base types are implemented. Large object
-import, export, and unlink works, also import/export from/to pipes.
+All commands should work with pq_exec_params, copy from stdin and copy
+to stdout are implemented from/to files at client side, copy from
+stdin is also possible from an Octave cell-array. There are no plans
+to implement copy to stdout into an Octave cell-array (does not safely
+fit into the framework, and select should be equivalent). The whole
+framework including conversion of composite and array types with the
+resulting possible recursion, enum types, and all base types except
+uuid, xml, and textsearch types are implemented. Large object import,
+export, and unlink works, also import/export from/to pipes.
 
-Please report bugs. If you want to implement a new type-converter for
-a base type yourself, you can do it in converters.cc and tell me
-(package maintainer) about it. See converters.h for the meaning of
-fields in the oct_pq_conv_t structure. Presently only the binary
-converters are needed, the string converters can be stubs returning an
-error value (1).
+Please report bugs.
--- a/main/database/doc/dev-postgresql/conversions.tex	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/doc/dev-postgresql/conversions.tex	Sat May 18 13:22:09 2013 +0000
@@ -201,8 +201,9 @@
 path &
 602 &
 1019 &
-(2n-element float vector, and somehow code if it is closed (?)) &
-yes ((path? closed?) obsolete) &
+structure with fields ``closed'' (boolean, is path closed?) and ``path''
+(2n-element float vector) &
+yes  &
 NBO, 1 byte (closed ? 1 : 0), int32 (npts), 2n double \\
 
 polygon &
@@ -222,12 +223,12 @@
 inet &
 869 &
 1041 &
-4,5,16, or 17-element uint8 vector &
-yes (is an addresstype? cidr? (code this in Octave representation of value) &
-uint8: \nolinkurl{AF_INET}, any other constant means \nolinkurl{AF_INET6}; uint8: number of
-set maskbits (in element 5 or 17 of octave vector, default 32 and
-128); uint8: \nolinkurl{is_cidr}?; uint8: addrsize (4 or 16); 4x or 16x uint8:
-address (left to right) \\
+4 or 5-element uint8 vector or 8 or 9-element uint16 vector &
+yes &
+uint8: \nolinkurl{AF_INET}, \nolinkurl{AF_INET} + 1 means
+\nolinkurl{AF_INET6}; uint8: number of set maskbits (in element 5 or
+9 of octave vector, default 32 and 128); uint8: \nolinkurl{is_cidr}?;
+uint8: addrsize (4 or 16(?)); 4x or 16x uint8: address (left to right) \\
 
 cidr &
 650 &
@@ -246,9 +247,9 @@
 bit &
 1560 &
 1561 &
-string of 1 and 0 &
+structure, fields ``bitlen'' (int32) and ``bits'' (uint8 array) &
 yes &
-int32 (NBO): nbits; n times uint8 (left to right, first byte full) \\
+int32 (NBO): nbits; nbytes times uint8 (left to right, first byte full) \\
 
 varbit &
 1562 &
--- a/main/database/inst/pq_exec_params.m	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/inst/pq_exec_params.m	Sat May 18 13:22:09 2013 +0000
@@ -188,6 +188,14 @@
 ## @item macaddr
 ## @tab uint8 array of 6 elements
 ## @tab yes
+## @item bit
+## @tab structure with fields @code{bitlen} (int32, number of valid
+## bits) and @code{bits} (uint8 array, 8 bits per entry, first entry
+## contains the leftmost bits, last entry may contain less than 8 bits)
+## @tab yes
+## @item varbit
+## @tab as bit
+## 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),
--- a/main/database/src/converters.cc	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/src/converters.cc	Sat May 18 13:22:09 2013 +0000
@@ -1889,6 +1889,111 @@
 
 /* end type macaddr */
 
+/* type bit */
+
+int to_octave_str_bit (const octave_pq_connection &conn,
+                       const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_bit (const octave_pq_connection &conn,
+                       const char *c, octave_value &ov, int nb)
+{
+  int32_t nbits = int32_t (be32toh (*((int32_t *) c)));
+
+  c += 4;
+
+  int32_t nbytes = (nbits + 7) / 8;
+
+  uint8NDArray a (dim_vector (nbytes, 1));
+
+  for (int i = 0; i < nbytes; i++, c++)
+    a(i) = uint8_t (*c);
+
+  octave_scalar_map tp;
+  tp.assign ("bitlen", octave_value (octave_int32 (nbits)));
+  tp.assign ("bits", octave_value (a));
+
+  ov = octave_value (tp);
+
+  return 0;
+}
+
+int from_octave_str_bit (const octave_pq_connection &conn,
+                         const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_bit (const octave_pq_connection &conn,
+                         const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  octave_scalar_map tp = ov.scalar_map_value ();
+  if (error_state || ! tp.isfield ("bitlen") || ! tp.isfield ("bits"))
+    {
+      error ("can not convert octave_value to bitstring representation");
+      return 1;
+    }
+
+  int32_t nbits = tp.contents ("bitlen").int_value ();
+
+  uint8NDArray a = tp.contents ("bits").uint8_array_value ();
+
+  if (error_state || nbits < 0)
+    {
+      error ("can not convert octave_value to bitstring representation");
+      return 1;
+    }
+
+  int32_t nbytes = (nbits + 7) / 8;
+
+  if (a.numel () != nbytes)
+    {
+      error ("wrong number of elements in bitstring representation");
+      return 1;
+    }
+
+  OCT_PQ_PUT(val, int32_t, htobe32 (nbits))
+
+  for (int i = 0; i < nbytes; i++)
+    val.push_back (a(i).value ());
+
+  return 0;
+}
+
+oct_pq_conv_t conv_bit = {0,
+                          0,
+                          oct_pq_el_oids_t (),
+                          oct_pq_conv_cache_t (),
+                          false,
+                          false,
+                          false,
+                          "bit",
+                          &to_octave_str_bit,
+                          &to_octave_bin_bit,
+                          &from_octave_str_bit,
+                          &from_octave_bin_bit};
+
+/* end type bit */
+
+/* type varbit */
+
+oct_pq_conv_t conv_varbit = {0,
+                             0,
+                             oct_pq_el_oids_t (),
+                             oct_pq_conv_cache_t (),
+                             false,
+                             false,
+                             false,
+                             "varbit",
+                             &to_octave_str_bit,
+                             &to_octave_bin_bit,
+                             &from_octave_str_bit,
+                             &from_octave_bin_bit};
+
+/* end type varbit */
+
 oct_pq_conv_t *t_conv_ptrs[OCT_PQ_NUM_CONVERTERS] = {&conv_bool,
                                                      &conv_oid,
                                                      &conv_float8,
@@ -1918,6 +2023,8 @@
                                                      &conv_unknown,
                                                      &conv_cidr,
                                                      &conv_inet,
-                                                     &conv_macaddr};
+                                                     &conv_macaddr,
+                                                     &conv_bit,
+                                                     &conv_varbit};
 
 oct_pq_conv_ptrs_t conv_ptrs (OCT_PQ_NUM_CONVERTERS, t_conv_ptrs);
--- a/main/database/src/converters.h	Sat May 18 10:30:40 2013 +0000
+++ b/main/database/src/converters.h	Sat May 18 13:22:09 2013 +0000
@@ -32,7 +32,7 @@
 
 #include "wrap_endian.h"
 
-#define OCT_PQ_NUM_CONVERTERS 30
+#define OCT_PQ_NUM_CONVERTERS 32
 
 typedef std::vector<char> oct_pq_dynvec_t;