case, caseproto: Implement save and load.
[pspp] / src / data / caseproto.c
index d62af283de2945cc2139f980d8c4dea5a0a431b2..2b2fcb408d61d396a18f830abfb264bd2653aae7 100644 (file)
@@ -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;