/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 2009-2015 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
#include "libpspp/message.h"
#include "libpspp/misc.h"
#include "libpspp/pool.h"
+#include "libpspp/pxd.h"
#include "libpspp/str.h"
#include "libpspp/string-array.h"
static void dict_unset_split_var (struct dictionary *, struct variable *);
static void dict_unset_mrset_var (struct dictionary *, struct variable *);
+static void dict_uncache (struct dictionary *);
+
/* Returns the encoding for data in dictionary D. The return value is a
nonnull string that contains an IANA character set name. */
const char *
void
dict_clear (struct dictionary *d)
{
+ dict_uncache (d);
+
/* FIXME? Should we really clear case_limit, label, documents?
Others are necessarily cleared by deleting all the variables.*/
while (d->var_cnt > 0 )
{
return vardict - vardict->dict->var;
}
+\f
+static struct pxd_object *
+vardict_info_save (const struct vardict_info *vardict, struct pxd *pxd)
+{
+ struct pxd_builder b;
+
+ pxd_builder_init (&b, pxd);
+ pxd_builder_put_s32 (&b, vardict->case_index);
+ pxd_builder_put_link (&b, var_save (vardict->var, pxd));
+ return pxd_builder_commit (&b);
+}
+
+struct pxd_object *
+dict_save (const struct dictionary *dict, struct pxd *pxd)
+{
+ struct pxd_array_builder ab;
+ struct pxd_object *vars;
+ struct pxd_builder b;
+ size_t i;
+
+ pxd_array_builder_init (&ab, pxd);
+ for (i = 0; i < dict->var_cnt; i++)
+ pxd_array_builder_add (&ab, vardict_info_save (&dict->var[i], pxd));
+ vars = pxd_array_builder_commit (&ab);
+
+ pxd_builder_init (&b, pxd);
+ pxd_builder_put_link (&b, vars);
+ pxd_builder_put_u32 (&b, dict->next_value_idx);
+
+ pxd_builder_put_size_t (&b, dict->split_cnt);
+ for (i = 0; i < dict->split_cnt; i++)
+ pxd_builder_put_u32 (&b, var_get_dict_index (dict->split[i]));
+
+ pxd_builder_put_s32 (&b,
+ (dict->weight == NULL ? -1
+ : var_get_dict_index (dict->weight)));
+ pxd_builder_put_s32 (&b,
+ (dict->filter == NULL ? -1
+ : var_get_dict_index (dict->filter)));
+
+ pxd_builder_put_casenumber (&b, dict->case_limit);
+ pxd_builder_put_string (&b, dict->label != NULL ? dict->label : "");
+ //XXX pxd_builder_put_string (&b, ds_cstr (&dict->documents));
+
+ pxd_builder_put_size_t (&b, dict->vector_cnt);
+ for (i = 0; i < dict->split_cnt; i++)
+ pxd_builder_put_link (&b, vector_save (dict->vector[i], pxd));
+
+ pxd_builder_put_link (&b, attrset_save (&dict->attributes, pxd));
+
+ pxd_builder_put_size_t (&b, dict->n_mrsets);
+ for (i = 0; i < dict->n_mrsets; i++)
+ pxd_builder_put_link (&b, mrset_save (dict->mrsets[i], pxd));
+
+ pxd_builder_put_string (&b, dict->encoding ? dict->encoding : "");
+
+ return pxd_builder_commit (&b);
+}
+
+static void
+vardict_info_load (struct dictionary *dict, struct pxd_object *obj,
+ const struct pxd *pxd)
+{
+ struct pxd_parser p;
+ struct variable *var;
+ int case_index;
+
+ pxd_parser_init (&p, obj, pxd);
+ case_index = pxd_parser_get_u32 (&p);
+ var = add_var (dict, var_load (pxd_parser_get_link (&p), pxd));
+ var_get_vardict (var)->case_index = case_index;
+ pxd_parser_destroy (&p);
+}
+
+struct dictionary *
+dict_load (struct pxd_object *obj, const struct pxd *pxd)
+{
+ struct dictionary *dict;
+ struct pxd_array array;
+ struct pxd_parser p;
+ char *encoding;
+ int weight_idx;
+ int filter_idx;
+ size_t i;
+
+ pxd_parser_init (&p, obj, pxd);
+
+ encoding = pxd_parser_get_string (&p);
+ dict = dict_create (encoding);
+ free (encoding);
+
+ pxd_array_init (&array, pxd_parser_get_link (&p), pxd);
+ for (i = 0; i < pxd_array_size (&array); i++)
+ vardict_info_load (dict, pxd_array_get (&array, i), pxd);
+ pxd_array_destroy (&array);
+
+ dict->next_value_idx = pxd_parser_get_u32 (&p);
+
+ dict->split_cnt = pxd_parser_get_size_t (&p);
+ if (dict->split_cnt > 0)
+ {
+ dict->split = xnmalloc (dict->split_cnt, sizeof *dict->split);
+ for (i = 0; i < dict->split_cnt; i++)
+ dict->split[i] = dict_get_var (dict, i);
+ }
+
+ weight_idx = pxd_parser_get_s32 (&p);
+ if (weight_idx >= 0)
+ dict_set_weight (dict, dict_get_var (dict, weight_idx));
+
+ filter_idx = pxd_parser_get_s32 (&p);
+ if (filter_idx >= 0)
+ dict_set_filter (dict, dict_get_var (dict, filter_idx));
+
+ dict->case_limit = pxd_parser_get_casenumber (&p);
+
+ dict->label = pxd_parser_get_string (&p);
+ if (dict->label[0] == '\0')
+ dict_set_label (dict, NULL);
+
+#if 0 /* XXX */
+ documents = pxd_parser_get_string (&p);
+ if (documents[0] != '\0')
+ ds_assign_cstr (&dict->documents, documents);
+ free (documents);
+#endif
+
+ dict->vector_cnt = pxd_parser_get_size_t (&p);
+ if (dict->vector_cnt > 0)
+ {
+ dict->vector = xnmalloc (dict->vector_cnt, sizeof *dict->vector);
+ for (i = 0; i < dict->vector_cnt; i++)
+ dict->vector[i] = vector_load (pxd_parser_get_link (&p), pxd, dict);
+ }
+
+ attrset_destroy (&dict->attributes);
+ attrset_load (&dict->attributes, pxd_parser_get_link (&p), pxd);
+
+ dict->n_mrsets = pxd_parser_get_size_t (&p);
+ if (dict->n_mrsets > 0)
+ {
+ dict->mrsets = xnmalloc (dict->n_mrsets, sizeof *dict->mrsets);
+ for (i = 0; i < dict->n_mrsets; i++)
+ dict->mrsets[i] = mrset_load (pxd_parser_get_link (&p), pxd, dict);
+ }
+
+ dict->encoding = pxd_parser_get_string (&p);
+ if (dict->encoding[0] == '\0')
+ {
+ free (dict->encoding);
+ dict->encoding = NULL;
+ }
+
+ pxd_parser_destroy (&p);
+
+ return dict;
+}
+
+static void
+dict_uncache (struct dictionary *dict UNUSED)
+{
+}
+