}
static casenumber
-casereader_count_cases__ (struct casereader *reader, casenumber max_cases)
+casereader_count_cases__ (const struct casereader *reader,
+ casenumber max_cases)
{
struct casereader *clone;
casenumber n_cases;
clone = casereader_clone (reader);
- for (n_cases = 0; n_cases < max_cases; n_cases++)
- {
- struct ccase *c = casereader_read (clone);
- if (c == NULL)
- break;
- case_unref (c);
- }
+ n_cases = casereader_advance (clone, max_cases);
casereader_destroy (clone);
return n_cases;
of the contents of a clone of READER. Thus, the return value
is always correct in the absence of I/O errors. */
casenumber
-casereader_count_cases (struct casereader *reader)
+casereader_count_cases (const struct casereader *reader)
{
if (reader->case_cnt == CASENUMBER_MAX)
- reader->case_cnt = casereader_count_cases__ (reader, CASENUMBER_MAX);
+ {
+ struct casereader *reader_rw = CONST_CAST (struct casereader *, reader);
+ reader_rw->case_cnt = casereader_count_cases__ (reader, CASENUMBER_MAX);
+ }
return reader->case_cnt;
}
return reader->proto;
}
+/* Skips past N cases in READER, stopping when the last case in
+ READER has been read or on an input error. Returns the number
+ of cases successfully skipped. */
+casenumber
+casereader_advance (struct casereader *reader, casenumber n)
+{
+ casenumber i;
+
+ for (i = 0; i < n; i++)
+ {
+ struct ccase *c = casereader_read (reader);
+ if (c == NULL)
+ break;
+ case_unref (c);
+ }
+
+ return i;
+}
+
+
/* Copies all the cases in READER to WRITER, propagating errors
appropriately. */
void
shim_destroy,
shim_advance,
};
+\f
+static const struct casereader_class casereader_null_class;
+
+/* Returns a casereader with no cases. The casereader has the prototype
+ specified by PROTO. PROTO may be specified as a null pointer, in which case
+ the casereader has no variables. */
+struct casereader *
+casereader_create_empty (const struct caseproto *proto_)
+{
+ struct casereader *reader;
+ struct caseproto *proto;
+
+ proto = proto_ != NULL ? caseproto_ref (proto_) : caseproto_create ();
+ reader = casereader_create_sequential (NULL, proto, 0,
+ &casereader_null_class, NULL);
+ caseproto_unref (proto);
+
+ return reader;
+}
+
+static struct ccase *
+casereader_null_read (struct casereader *reader UNUSED, void *aux UNUSED)
+{
+ return NULL;
+}
+
+static void
+casereader_null_destroy (struct casereader *reader UNUSED, void *aux UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static const struct casereader_class casereader_null_class =
+ {
+ casereader_null_read,
+ casereader_null_destroy,
+ NULL, /* clone */
+ NULL, /* peek */
+ };