X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fdictionary.c;fp=src%2Fdata%2Fdictionary.c;h=7cf2a7917de2e74cb85e8ac7db01ccad356246c4;hb=52c54183e360053b1845e46cb96cd44a0cf96040;hp=4eaaefae18ed9ae4889275bccd00b0e568c26e8d;hpb=2ca3267c1110bbff675c560b19d02defb96ee2f9;p=pspp diff --git a/src/data/dictionary.c b/src/data/dictionary.c index 4eaaefae18..7cf2a7917d 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -1,5 +1,5 @@ /* 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 @@ -41,6 +41,7 @@ #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" @@ -87,6 +88,8 @@ struct dictionary 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 * @@ -255,6 +258,8 @@ dict_clone (const struct dictionary *s) 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 ) @@ -1674,3 +1679,166 @@ vardict_get_dict_index (const struct vardict_info *vardict) { return vardict - vardict->dict->var; } + +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) +{ +} +