casereader: Implement save, load.
[pspp] / src / data / casereader.c
index 9f3d5cf9dbeb25c94683a8f739218d6cb6c0ba0d..be5509935957adb3c265d90ac496084b2f90b17f 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2010, 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
@@ -118,25 +118,6 @@ casereader_clone (const struct casereader *reader_)
   return clone;
 }
 
-/* Makes a copy of ORIGINAL into *NEW1 (if NEW1 is non-null) and
-   *NEW2 (if NEW2 is non-null), then destroys ORIGINAL. */
-void
-casereader_split (struct casereader *original,
-                  struct casereader **new1, struct casereader **new2)
-{
-  if (new1 != NULL && new2 != NULL)
-    {
-      *new1 = casereader_rename (original);
-      *new2 = casereader_clone (*new1);
-    }
-  else if (new1 != NULL)
-    *new1 = casereader_rename (original);
-  else if (new2 != NULL)
-    *new2 = casereader_rename (original);
-  else
-    casereader_destroy (original);
-}
-
 /* Returns a copy of READER, which is itself destroyed.
    Useful for taking over ownership of a casereader, to enforce
    preventing the original owner from accessing the casereader
@@ -344,6 +325,56 @@ casereader_transfer (struct casereader *reader, struct casewriter *writer)
   casereader_destroy (reader);
 }
 
+struct pxd_object *
+casereader_save (const struct casereader *reader_, struct pxd *pxd)
+{
+  struct pxd_array_builder ab;
+  struct casereader *reader;
+  struct pxd_builder b;
+  struct ccase *c;
+
+  pxd_array_builder_init (&ab, pxd);
+  reader = casereader_clone (reader_);
+  while ((c = casereader_read (reader)) != NULL)
+    {
+      pxd_array_builder_add (&ab, case_save (c, pxd));
+      case_unref (c);
+    }
+  casereader_destroy (reader);
+
+  pxd_builder_init (&b, pxd);
+  pxd_builder_put_link (&b, caseproto_save (reader->proto, pxd));
+  pxd_builder_put_link (&b, pxd_array_builder_commit (&ab));
+
+  return pxd_builder_commit (&b);
+}
+
+struct casereader *
+casereader_load (struct pxd_object *object, const struct pxd *pxd)
+{
+  struct casewriter *writer;
+  struct caseproto *proto;
+  struct pxd_array array;
+  struct pxd_parser p;
+  size_t i;
+
+  pxd_parser_init (&p, object, pxd);
+
+  proto = caseproto_load (pxd_parser_get_link (&p), pxd);
+  writer = autopaging_writer_create (proto);
+  caseproto_unref (proto);
+
+  pxd_array_init (&array, pxd_parser_get_link (&p), pxd);
+  for (i = 0; i < pxd_array_size (&array); i++)
+    casewriter_write (writer, case_load (pxd_array_get (&array, i), pxd));
+  pxd_array_destroy (&array);
+
+  pxd_parser_destroy (&p);
+
+  return casewriter_make_reader (writer);
+}
+
+
 /* Creates and returns a new casereader.  This function is
    intended for use by casereader implementations, not by
    casereader clients.