From 9fec5bb8185313eda6234ce052342ffac776908e Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 9 May 2013 22:56:26 -0700 Subject: [PATCH] case, caseproto: Implement save and load. --- src/data/case.c | 24 ++++++++++++++++++++++- src/data/case.h | 14 +++++++------- src/data/casenumber.h | 26 +++++++++++++++++++++++++ src/data/caseproto.c | 44 ++++++++++++++++++++++++++++++++++++++++++- src/data/caseproto.h | 8 +++++++- src/libpspp/pxd.h | 4 ++-- 6 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 src/data/casenumber.h diff --git a/src/data/case.c b/src/data/case.c index bb6f7c0a8e..9d459ac078 100644 --- a/src/data/case.c +++ b/src/data/case.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2009, 2010, 2011, 2013 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 @@ -435,6 +435,28 @@ case_data_all_rw (struct ccase *c) return c->values; } +struct pxd_object * +case_save (const struct ccase *c, struct pxd *pxd) +{ + struct pxd_builder b; + size_t i; + + pxd_builder_init (&b, pxd); + + pxd_builder_put_link (&b, caseproto_save (c->proto, pxd)); + for (i = 0; i < caseproto_get_n_widths (c->proto); i++) + { + int width = caseproto_get_width (c->proto, i); + if (width >= 0) + pxd_builder_put_value (&b, case_data_idx (c, i), width); + } + + return pxd_builder_commit (&b); +} + +struct ccase *case_load (struct pxd_object *, const struct pxd *); + + /* Internal helper function for case_unshare. */ struct ccase * case_unshare__ (struct ccase *old) diff --git a/src/data/case.h b/src/data/case.h index 1f5e192f3d..97fa2a6921 100644 --- a/src/data/case.h +++ b/src/data/case.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2009, 2010, 2011, 2013 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 @@ -22,16 +22,13 @@ #include #include -#include "libpspp/compiler.h" #include "data/caseproto.h" +#include "libpspp/compiler.h" +#include "libpspp/pxd.h" +#include "data/casenumber.h" struct variable; -/* A count of cases or the index of a case within a collection of - them. */ -#define CASENUMBER_MAX LONG_MAX -typedef long int casenumber; - /* Reference-counted case implementation. A newly created case has a single owner (the code that created @@ -109,6 +106,9 @@ int case_compare_2dict (const struct ccase *, const struct ccase *, const union value *case_data_all (const struct ccase *); union value *case_data_all_rw (struct ccase *); + +struct pxd_object *case_save (const struct ccase *, struct pxd *); +struct ccase *case_load (struct pxd_object *, const struct pxd *); struct ccase *case_unshare__ (struct ccase *); void case_unref__ (struct ccase *); diff --git a/src/data/casenumber.h b/src/data/casenumber.h new file mode 100644 index 0000000000..9cfca335ec --- /dev/null +++ b/src/data/casenumber.h @@ -0,0 +1,26 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2004, 2007, 2009, 2010, 2011, 2013 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 . */ + +#ifndef DATA_CASENUMBER_H +#define DATA_CASENUMBER_H 1 + +/* A count of cases or the index of a case within a collection of + them. */ +#define CASENUMBER_MAX LONG_MAX +typedef long int casenumber; + +#endif /* data/casenumber.h */ + diff --git a/src/data/caseproto.c b/src/data/caseproto.c index d62af283de..2b2fcb408d 100644 --- a/src/data/caseproto.c +++ b/src/data/caseproto.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011 Free Software Foundation, Inc. + Copyright (C) 2009, 2011, 2013 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 @@ -221,6 +221,45 @@ caseproto_equal (const struct caseproto *a, size_t a_start, return true; } +struct pxd_object * +caseproto_save (const struct caseproto *proto, struct pxd *pxd) +{ + if (proto->pxd == NULL) + { + struct pxd_builder b; + size_t i; + + pxd_builder_init (&b, pxd); + + pxd_builder_put_size_t (&b, proto->n_widths); + for (i = 0; i < proto->n_widths; i++) + pxd_builder_put_s16 (&b, proto->widths[i]); + + CONST_CAST (struct caseproto *, proto)->pxd = pxd_builder_commit (&b); + } + return pxd_object_ref (proto->pxd); +} + +struct caseproto * +caseproto_load (struct pxd_object *object, const struct pxd *pxd) +{ + struct caseproto *proto; + struct pxd_parser p; + size_t n, i; + + pxd_parser_init (&p, object, pxd); + + n = pxd_parser_get_size_t (&p); + proto = caseproto_reserve (caseproto_create (), n); + + for (i = 0; i < n; i++) + proto = caseproto_add_width (proto, pxd_parser_get_s16 (&p)); + + pxd_parser_destroy (&p); + + return proto; +} + /* Returns true if an array of values that is to be used for data of the format specified in PROTO needs to be initialized by calling caseproto_init_values, false if that step may be @@ -314,6 +353,7 @@ caseproto_copy (const struct caseproto *proto, size_t idx, size_t count, void caseproto_free__ (struct caseproto *proto) { + pxd_object_unref (proto->pxd); free (proto->long_strings); free (proto); } @@ -350,6 +390,8 @@ caseproto_unshare (struct caseproto *old) { new = old; free (new->long_strings); + pxd_object_unref (new->pxd); + new->pxd = NULL; } new->long_strings = NULL; return new; diff --git a/src/data/caseproto.h b/src/data/caseproto.h index 0bc02812d1..d675bfe1d7 100644 --- a/src/data/caseproto.h +++ b/src/data/caseproto.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011 Free Software Foundation, Inc. + Copyright (C) 2009, 2011, 2013 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 @@ -25,6 +25,7 @@ #include "data/value.h" #include "libpspp/cast.h" #include "libpspp/compiler.h" +#include "libpspp/pxd.h" /* Case prototype. @@ -69,6 +70,7 @@ struct caseproto the former must be regenerated. */ size_t *long_strings; /* Array of indexes of long string widths. */ size_t n_long_strings; /* Number of long string widths. */ + struct pxd_object *pxd; /* Saved copy. */ /* Widths. */ size_t n_widths; /* Number of widths. */ @@ -135,6 +137,10 @@ bool caseproto_is_conformable (const struct caseproto *a, bool caseproto_equal (const struct caseproto *a, size_t a_start, const struct caseproto *b, size_t b_start, size_t n); + +/* Save and load. */ +struct pxd_object *caseproto_save (const struct caseproto *, struct pxd *); +struct caseproto *caseproto_load (struct pxd_object *, const struct pxd *); /* Creation and destruction. */ diff --git a/src/libpspp/pxd.h b/src/libpspp/pxd.h index 22b34c4606..36c8e5f28b 100644 --- a/src/libpspp/pxd.h +++ b/src/libpspp/pxd.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2010, 2012 Free Software Foundation, Inc. + Copyright (C) 2010, 2012, 2013 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 @@ -22,7 +22,7 @@ #include #include -#include "data/case.h" +#include "data/casenumber.h" #include "libpspp/hmap.h" struct pxd; -- 2.30.2