--- /dev/null
+/* PSPP - a program for statistical analysis.
+ Copyright (C) 2010, 2012 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBPSPP_PXD_H
+#define LIBPSPP_PXD_H 1
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "data/case.h"
+#include "libpspp/hmap.h"
+
+struct pxd;
+struct pxd_object;
+struct pxd_id;
+union value;
+\f
+/* Databases. */
+
+struct pxd *pxd_open (const char *name, bool create);
+void pxd_close (struct pxd *);
+
+struct pxd_object *pxd_fetch (const struct pxd *, const struct pxd_id *);
+void pxd_store (struct pxd *, const struct pxd_object *);
+
+void pxd_get_root (const struct pxd *, struct pxd_id *);
+bool pxd_swap_root (struct pxd *, const struct pxd_id *old_root,
+ struct pxd_object *new_root);
+\f
+/* Object IDs. */
+
+struct pxd_id
+ {
+ uint32_t opaque[5];
+ };
+
+#define PXD_ID_FMT "%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32
+#define PXD_ID_ARGS(ID) \
+ (ID)->opaque[0], \
+ (ID)->opaque[1], \
+ (ID)->opaque[2], \
+ (ID)->opaque[3], \
+ (ID)->opaque[4]
+#define PXD_ID_SCAN_ARGS(ID) \
+ &(ID)->opaque[0], \
+ &(ID)->opaque[1], \
+ &(ID)->opaque[2], \
+ &(ID)->opaque[3], \
+ &(ID)->opaque[4]
+
+static inline bool
+pxd_id_equals (const struct pxd_id *a, const struct pxd_id *b)
+{
+ return (a->opaque[0] == b->opaque[0]
+ && a->opaque[1] == b->opaque[1]
+ && a->opaque[2] == b->opaque[2]
+ && a->opaque[3] == b->opaque[3]
+ && a->opaque[4] == b->opaque[4]);
+}
+
+static inline uint32_t
+pxd_id_hash (const struct pxd_id *id)
+{
+ return id->opaque[0];
+}
+\f
+/* Objects. */
+
+struct pxd_object
+ {
+ struct hmap_node hmap_node;
+ unsigned int n_refs;
+ struct pxd_id id;
+ unsigned int n_links;
+ unsigned int size;
+ struct pxd_id *links;
+ uint8_t *data;
+ };
+
+struct pxd_object *pxd_object_create (const struct pxd_id[], size_t,
+ const void *, size_t);
+
+struct pxd_object *pxd_object_ref (const struct pxd_object *);
+void pxd_object_unref (struct pxd_object *);
+
+static inline const struct pxd_id *
+pxd_object_id (const struct pxd_object *obj)
+{
+ return &obj->id;
+}
+
+static inline unsigned int
+pxd_object_get_n_links (const struct pxd_object *obj)
+{
+ return obj->n_links;
+}
+
+static inline const struct pxd_id *
+pxd_object_get_link_id (const struct pxd_object *obj, unsigned int idx)
+{
+ return &obj->links[idx];
+}
+
+static inline struct pxd_object *
+pxd_object_get_link (const struct pxd_object *obj, unsigned int idx,
+ const struct pxd *pxd)
+{
+ return pxd_fetch (pxd, pxd_object_get_link_id (obj, idx));
+}
+
+static inline unsigned int
+pxd_object_size (const struct pxd_object *obj)
+{
+ return obj->size;
+}
+
+static inline const uint8_t *
+pxd_object_data (const struct pxd_object *obj)
+{
+ return obj->data;
+}
+
+void *pxd_object_raw_data__ (const struct pxd_object *);
+size_t pxd_object_raw_size__ (const struct pxd_object *);
+\f
+/* Object builder. */
+
+struct pxd_builder
+ {
+ struct pxd *pxd;
+
+ struct pxd_id *links;
+ unsigned int n_links, links_allocated;
+
+ uint8_t *data;
+ unsigned int size, data_allocated;
+ };
+
+void pxd_builder_init (struct pxd_builder *, struct pxd *);
+void pxd_builder_destroy (struct pxd_builder *);
+
+struct pxd_object *pxd_builder_commit (struct pxd_builder *);
+
+void *pxd_builder_put_uninit (struct pxd_builder *, size_t);
+void pxd_builder_put (struct pxd_builder *, const void *, size_t);
+void pxd_builder_put_value (struct pxd_builder *,
+ const union value *, int width);
+void pxd_builder_put_string (struct pxd_builder *, const char *);
+void pxd_builder_put_interned_string (struct pxd_builder *, const char *);
+void pxd_builder_put_bool (struct pxd_builder *, bool);
+void pxd_builder_put_u8 (struct pxd_builder *, unsigned char);
+void pxd_builder_put_u16 (struct pxd_builder *, unsigned short int);
+void pxd_builder_put_u32 (struct pxd_builder *, unsigned int);
+void pxd_builder_put_u64 (struct pxd_builder *, unsigned long long int);
+void pxd_builder_put_s8 (struct pxd_builder *, signed char);
+void pxd_builder_put_s16 (struct pxd_builder *, short int);
+void pxd_builder_put_s32 (struct pxd_builder *, int);
+void pxd_builder_put_s64 (struct pxd_builder *, long long int);
+void pxd_builder_put_size_t (struct pxd_builder *, size_t);
+void pxd_builder_put_casenumber (struct pxd_builder *, casenumber);
+void pxd_builder_put_double (struct pxd_builder *, double);
+
+void pxd_builder_put_link (struct pxd_builder *, struct pxd_object *);
+\f
+/* Object parser. */
+
+struct pxd_parser
+ {
+ struct pxd_object *obj;
+ const struct pxd *pxd;
+ unsigned int offset;
+ unsigned int link;
+ };
+
+void pxd_parser_init (struct pxd_parser *,
+ struct pxd_object *, const struct pxd *);
+void pxd_parser_destroy (struct pxd_parser *);
+
+const void *pxd_parser_get (struct pxd_parser *, size_t);
+void pxd_parser_get_copy (struct pxd_parser *, void *, size_t);
+void pxd_parser_get_value (struct pxd_parser *, union value *, int width);
+char *pxd_parser_get_string (struct pxd_parser *);
+const char *pxd_parser_get_interned_string (struct pxd_parser *);
+bool pxd_parser_get_bool (struct pxd_parser *);
+unsigned char pxd_parser_get_u8 (struct pxd_parser *);
+unsigned short int pxd_parser_get_u16 (struct pxd_parser *);
+unsigned int pxd_parser_get_u32 (struct pxd_parser *);
+unsigned long long int pxd_parser_get_u64 (struct pxd_parser *);
+signed char pxd_parser_get_s8 (struct pxd_parser *);
+short int pxd_parser_get_s16 (struct pxd_parser *);
+int pxd_parser_get_s32 (struct pxd_parser *);
+long long int pxd_parser_get_s64 (struct pxd_parser *);
+size_t pxd_parser_get_size_t (struct pxd_parser *);
+casenumber pxd_parser_get_casenumber (struct pxd_parser *);
+double pxd_parser_get_double (struct pxd_parser *);
+struct pxd_object *pxd_parser_get_link (struct pxd_parser *);
+\f
+/* Array builder. */
+
+#define PXD_ARRAY_LEVELS 10
+#define PXD_ARRAY_BITS 5
+
+struct pxd_array_builder
+ {
+ struct pxd_builder b;
+ };
+
+void pxd_array_builder_init (struct pxd_array_builder *, struct pxd *);
+void pxd_array_builder_destroy (struct pxd_array_builder *);
+
+struct pxd_object *pxd_array_builder_commit (struct pxd_array_builder *);
+
+void pxd_array_builder_add (struct pxd_array_builder *, struct pxd_object *);
+\f
+/* Array reader. */
+
+struct pxd_array
+ {
+ const struct pxd *pxd;
+ struct pxd_object *obj;
+ };
+
+void pxd_array_init (struct pxd_array *, struct pxd_object *,
+ const struct pxd *);
+void pxd_array_destroy (struct pxd_array *);
+
+static inline unsigned long long int
+pxd_array_size (const struct pxd_array *array)
+{
+ return array->obj->n_links;
+}
+
+static inline struct pxd_object *
+pxd_array_get (const struct pxd_array *array, unsigned long long int index)
+{
+ return pxd_object_get_link (array->obj, index, array->pxd);
+}
+
+#endif /* libpspp/pxd.h */