case, caseproto: Implement save and load.
[pspp] / src / libpspp / pxd.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2010, 2012, 2013 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifndef LIBPSPP_PXD_H
18 #define LIBPSPP_PXD_H 1
19
20 #include <inttypes.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdint.h>
24
25 #include "data/casenumber.h"
26 #include "libpspp/hmap.h"
27
28 struct pxd;
29 struct pxd_object;
30 struct pxd_id;
31 union value;
32 \f
33 /* Databases. */
34
35 struct pxd *pxd_open (const char *name, bool create);
36 void pxd_close (struct pxd *);
37
38 struct pxd_object *pxd_fetch (const struct pxd *, const struct pxd_id *);
39 void pxd_store (struct pxd *, const struct pxd_object *);
40
41 void pxd_get_root (const struct pxd *, struct pxd_id *);
42 bool pxd_swap_root (struct pxd *, const struct pxd_id *old_root,
43                     struct pxd_object *new_root);
44 \f
45 /* Object IDs. */
46
47 struct pxd_id
48   {
49     uint32_t opaque[5];
50   };
51
52 #define PXD_ID_FMT "%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32
53 #define PXD_ID_ARGS(ID)                         \
54         (ID)->opaque[0],                        \
55         (ID)->opaque[1],                        \
56         (ID)->opaque[2],                        \
57         (ID)->opaque[3],                        \
58         (ID)->opaque[4]
59 #define PXD_ID_SCAN_ARGS(ID)                    \
60         &(ID)->opaque[0],                       \
61         &(ID)->opaque[1],                       \
62         &(ID)->opaque[2],                       \
63         &(ID)->opaque[3],                       \
64         &(ID)->opaque[4]
65
66 static inline bool
67 pxd_id_equals (const struct pxd_id *a, const struct pxd_id *b)
68 {
69   return (a->opaque[0] == b->opaque[0]
70           && a->opaque[1] == b->opaque[1]
71           && a->opaque[2] == b->opaque[2]
72           && a->opaque[3] == b->opaque[3]
73           && a->opaque[4] == b->opaque[4]);
74 }
75
76 static inline uint32_t
77 pxd_id_hash (const struct pxd_id *id)
78 {
79   return id->opaque[0];
80 }
81 \f
82 /* Objects. */
83
84 struct pxd_object
85   {
86     struct hmap_node hmap_node;
87     unsigned int n_refs;
88     struct pxd_id id;
89     unsigned int n_links;
90     unsigned int size;
91     struct pxd_id *links;
92     uint8_t *data;
93   };
94
95 struct pxd_object *pxd_object_create (const struct pxd_id[], size_t,
96                                       const void *, size_t);
97
98 struct pxd_object *pxd_object_ref (const struct pxd_object *);
99 void pxd_object_unref (struct pxd_object *);
100
101 static inline const struct pxd_id *
102 pxd_object_id (const struct pxd_object *obj)
103 {
104   return &obj->id;
105 }
106
107 static inline unsigned int
108 pxd_object_get_n_links (const struct pxd_object *obj)
109 {
110   return obj->n_links;
111 }
112
113 static inline const struct pxd_id *
114 pxd_object_get_link_id (const struct pxd_object *obj, unsigned int idx)
115 {
116   return &obj->links[idx];
117 }
118
119 static inline struct pxd_object *
120 pxd_object_get_link (const struct pxd_object *obj, unsigned int idx,
121                      const struct pxd *pxd)
122 {
123   return pxd_fetch (pxd, pxd_object_get_link_id (obj, idx));
124 }
125
126 static inline unsigned int
127 pxd_object_size (const struct pxd_object *obj)
128 {
129   return obj->size;
130 }
131
132 static inline const uint8_t *
133 pxd_object_data (const struct pxd_object *obj)
134 {
135   return obj->data;
136 }
137
138 void *pxd_object_raw_data__ (const struct pxd_object *);
139 size_t pxd_object_raw_size__ (const struct pxd_object *);
140 \f
141 /* Object builder. */
142
143 struct pxd_builder
144   {
145     struct pxd *pxd;
146
147     struct pxd_id *links;
148     unsigned int n_links, links_allocated;
149
150     uint8_t *data;
151     unsigned int size, data_allocated;
152   };
153
154 void pxd_builder_init (struct pxd_builder *, struct pxd *);
155 void pxd_builder_destroy (struct pxd_builder *);
156
157 struct pxd_object *pxd_builder_commit (struct pxd_builder *);
158
159 void *pxd_builder_put_uninit (struct pxd_builder *, size_t);
160 void pxd_builder_put (struct pxd_builder *, const void *, size_t);
161 void pxd_builder_put_value (struct pxd_builder *,
162                             const union value *, int width);
163 void pxd_builder_put_string (struct pxd_builder *, const char *);
164 void pxd_builder_put_interned_string (struct pxd_builder *, const char *);
165 void pxd_builder_put_bool (struct pxd_builder *, bool);
166 void pxd_builder_put_u8 (struct pxd_builder *, unsigned char);
167 void pxd_builder_put_u16 (struct pxd_builder *, unsigned short int);
168 void pxd_builder_put_u32 (struct pxd_builder *, unsigned int);
169 void pxd_builder_put_u64 (struct pxd_builder *, unsigned long long int);
170 void pxd_builder_put_s8 (struct pxd_builder *, signed char);
171 void pxd_builder_put_s16 (struct pxd_builder *, short int);
172 void pxd_builder_put_s32 (struct pxd_builder *, int);
173 void pxd_builder_put_s64 (struct pxd_builder *, long long int);
174 void pxd_builder_put_size_t (struct pxd_builder *, size_t);
175 void pxd_builder_put_casenumber (struct pxd_builder *, casenumber);
176 void pxd_builder_put_double (struct pxd_builder *, double);
177
178 void pxd_builder_put_link (struct pxd_builder *, struct pxd_object *);
179 \f
180 /* Object parser. */
181
182 struct pxd_parser
183   {
184     struct pxd_object *obj;
185     const struct pxd *pxd;
186     unsigned int offset;
187     unsigned int link;
188   };
189
190 void pxd_parser_init (struct pxd_parser *,
191                       struct pxd_object *, const struct pxd *);
192 void pxd_parser_destroy (struct pxd_parser *);
193
194 const void *pxd_parser_get (struct pxd_parser *, size_t);
195 void pxd_parser_get_copy (struct pxd_parser *, void *, size_t);
196 void pxd_parser_get_value (struct pxd_parser *, union value *, int width);
197 char *pxd_parser_get_string (struct pxd_parser *);
198 const char *pxd_parser_get_interned_string (struct pxd_parser *);
199 bool pxd_parser_get_bool (struct pxd_parser *);
200 unsigned char pxd_parser_get_u8 (struct pxd_parser *);
201 unsigned short int pxd_parser_get_u16 (struct pxd_parser *);
202 unsigned int pxd_parser_get_u32 (struct pxd_parser *);
203 unsigned long long int pxd_parser_get_u64 (struct pxd_parser *);
204 signed char pxd_parser_get_s8 (struct pxd_parser *);
205 short int pxd_parser_get_s16 (struct pxd_parser *);
206 int pxd_parser_get_s32 (struct pxd_parser *);
207 long long int pxd_parser_get_s64 (struct pxd_parser *);
208 size_t pxd_parser_get_size_t (struct pxd_parser *);
209 casenumber pxd_parser_get_casenumber (struct pxd_parser *);
210 double pxd_parser_get_double (struct pxd_parser *);
211 struct pxd_object *pxd_parser_get_link (struct pxd_parser *);
212 \f
213 /* Array builder. */
214
215 #define PXD_ARRAY_LEVELS 10
216 #define PXD_ARRAY_BITS 5
217
218 struct pxd_array_builder
219   {
220     struct pxd_builder b;
221   };
222
223 void pxd_array_builder_init (struct pxd_array_builder *, struct pxd *);
224 void pxd_array_builder_destroy (struct pxd_array_builder *);
225
226 struct pxd_object *pxd_array_builder_commit (struct pxd_array_builder *);
227
228 void pxd_array_builder_add (struct pxd_array_builder *, struct pxd_object *);
229 \f
230 /* Array reader. */
231
232 struct pxd_array
233   {
234     const struct pxd *pxd;
235     struct pxd_object *obj;
236   };
237
238 void pxd_array_init (struct pxd_array *, struct pxd_object *,
239                      const struct pxd *);
240 void pxd_array_destroy (struct pxd_array *);
241
242 static inline unsigned long long int
243 pxd_array_size (const struct pxd_array *array)
244 {
245   return array->obj->n_links;
246 }
247
248 static inline struct pxd_object *
249 pxd_array_get (const struct pxd_array *array, unsigned long long int index)
250 {
251   return pxd_object_get_link (array->obj, index, array->pxd);
252 }
253
254 #endif /* libpspp/pxd.h */