annotate main/database/src/converters.h @ 11460:9ef769abf53d octave-forge

Fix segfault reported by Richard <richard@mail.sheugh.com>, due to undefined order of initialization.
author i7tiol
date Mon, 18 Feb 2013 20:48:19 +0000
parents 61ea672a060a
children 4fd39d36eff5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
1 /*
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
2
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
3 Copyright (C) 2012, 2013 Olaf Till <i7tiol@t-online.de>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
4
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
8 (at your option) any later version.
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
9
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
13 GNU General Public License for more details.
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
14
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
16 along with this program; If not, see <http://www.gnu.org/licenses/>.
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
17
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
18 */
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
19
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
20 #ifndef __OCT_PQ_CONVERTERS__
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
21
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
22 #define __OCT_PQ_CONVERTERS__
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
23
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
24 #include <octave/oct.h>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
25
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
26 #include <stdint.h>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
27 #include <endian.h>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
28
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
29 #include <vector>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
30 #include <string>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
31
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
32 #include <postgresql/libpq-fe.h>
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
33
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
34 #define OCT_PQ_NUM_CONVERTERS 13
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
35
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
36 typedef std::vector<char> oct_pq_dynvec_t;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
37
11409
21794ea37065 Make char* in to_octave_ converters const.
i7tiol
parents: 11407
diff changeset
38 typedef int (*oct_pq_to_octave_fp_t) (const char *, octave_value &, int);
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
39
11407
f4098c7d5b35 Wrong implementation of copy-in from argument.
i7tiol
parents: 11394
diff changeset
40 typedef int (*oct_pq_from_octave_fp_t) (const octave_value &, oct_pq_dynvec_t &);
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
41
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
42 // some objects will be constants, some will be allocated
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
43 typedef struct
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
44 {
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
45 Oid oid; // read from server
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
46 Oid aoid; // array oid // read from server
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
47 Oid relid; // pg_attribute.attrelid, zero for non-composite types
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
48 bool is_composite; // false for constant objects
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
49 bool is_enum; // false for constant objects
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
50 bool is_not_constant; // false for constant objects
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
51 // const char *name; not all constants, use std::string
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
52 std::string name;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
53 oct_pq_to_octave_fp_t to_octave_str;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
54 oct_pq_to_octave_fp_t to_octave_bin;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
55 oct_pq_from_octave_fp_t from_octave_str;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
56 oct_pq_from_octave_fp_t from_octave_bin;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
57 }
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
58 oct_pq_conv_t;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
59
11460
9ef769abf53d Fix segfault reported by Richard <richard@mail.sheugh.com>, due to undefined order of initialization.
i7tiol
parents: 11429
diff changeset
60 std::string &pq_basetype_prefix (void);
11429
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
61
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
62 // a wrapper class for array of pointers to converters which qualifies
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
63 // base type names in initialization
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
64 class oct_pq_conv_ptrs_t
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
65 {
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
66 public:
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
67
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
68 oct_pq_conv_ptrs_t (int n, oct_pq_conv_t **ptrs) : converters (ptrs)
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
69 {
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
70 for (int i = 0; i < n; i++)
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
71 {
11460
9ef769abf53d Fix segfault reported by Richard <richard@mail.sheugh.com>, due to undefined order of initialization.
i7tiol
parents: 11429
diff changeset
72 std::string prefix = pq_basetype_prefix ();
11429
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
73
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
74 converters[i]->name = prefix.append (converters[i]->name);
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
75 }
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
76 }
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
77
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
78 oct_pq_conv_t *operator[] (int i) { return converters[i]; }
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
79
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
80 private:
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
81
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
82 oct_pq_conv_t **converters;
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
83 };
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
84
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
85 // a wrapper class around oct_pq_conv_t* to provide a default
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
86 // constructor which nullifies it, for efficient use of maps, where
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
87 // checking for the presence of a key while inserting it can rely on a
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
88 // newly generated key mapping to a value of NULL
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
89 class oct_pq_conv_wrapper_t
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
90 {
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
91 public:
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
92
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
93 oct_pq_conv_wrapper_t (void) : conv (NULL) {}
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
94
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
95 oct_pq_conv_wrapper_t (oct_pq_conv_t *c) : conv (c) {}
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
96
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
97 operator oct_pq_conv_t *&(void) { return conv; }
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
98
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
99 oct_pq_conv_t *&operator->(void) { return conv; }
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
100
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
101 private:
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
102
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
103 oct_pq_conv_t *conv;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
104 };
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
105
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
106 // helper function for debugging
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
107 void print_conv (oct_pq_conv_t *);
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
108
11429
61ea672a060a Consider schemas in type specifications by name.
i7tiol
parents: 11410
diff changeset
109 extern oct_pq_conv_ptrs_t conv_ptrs;
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
110
11410
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
111 // these prototypes are needed because pointers to these functions are
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
112 // stored in the converter structures of each found enum type
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
113 int to_octave_str_text (const char *c, octave_value &ov, int nb);
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
114 int to_octave_bin_text (const char *c, octave_value &ov, int nb);
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
115 int from_octave_str_text (const octave_value &ov, oct_pq_dynvec_t &val);
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
116 int from_octave_bin_text (const octave_value &ov, oct_pq_dynvec_t &val);
c20550232685 Conversion of enum types implemented.
i7tiol
parents: 11409
diff changeset
117
11394
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
118 // append bytes of value 'val' of type 'type' to dynamic char vector 'dv'
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
119 #define OCT_PQ_PUT(dv, type, val) \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
120 dv.resize (dv.size () + sizeof (type)); \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
121 *((type *) &(dv.end ()[-sizeof (type)])) = val;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
122
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
123 // increase size of dynamic char vector 'dv' by size of uint32 and
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
124 // store the new size in a variable named 'var' of octave_idx_type;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
125 // after further increasing 'dv', OCT_PQ_FILL_UINT32_PLACEHOLDER
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
126 // should be used with equal arguments
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
127 #define OCT_PQ_SET_UINT32_PLACEHOLDER(dv, var) \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
128 octave_idx_type var = dv.size () + sizeof (uint32_t); \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
129 dv.resize (var);
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
130 // to be used after OCT_PQ_SET_UINT32_PLACEHOLDER with equal
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
131 // arguments; calculate difference between current size of dynamic
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
132 // char vector 'dv' and a previous size stored in a variable named
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
133 // 'var', and write this difference, converted to uint32_t in network
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
134 // byte order, to the placeholder within 'dv' just before the position
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
135 // stored in 'var'
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
136 #define OCT_PQ_FILL_UINT32_PLACEHOLDER(dv, var) \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
137 *((uint32_t *) &(dv[var - sizeof (uint32_t)])) = htobe32 (dv.size () - var);
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
138
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
139 #define OCT_PQ_DECL_GET_INT32(retvar, pointer, type) \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
140 type retvar = be32toh (*((type *) pointer)); \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
141 pointer += 4;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
142
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
143 #define OCT_PQ_GET_INT32(retvar, pointer, type) \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
144 retvar = be32toh (*((type *) pointer)); \
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
145 pointer += 4;
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
146
9aee227e296c Populated new database package with initial postgresql interface.
i7tiol
parents:
diff changeset
147 #endif // __OCT_PQ_CONVERTERS__