X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fstorage-stream.c;h=4ff939cd02a1559ebdcaafeb8b51738ffc9a8973;hb=687adf53eae434e88a47bb3409f946f3a26115a4;hp=912a10398cb9d5bee1e584907d6ee0368f0db65d;hpb=f43378497b8400e9c22a3485c534693dc1bc9554;p=pspp-builds.git diff --git a/src/data/storage-stream.c b/src/data/storage-stream.c index 912a1039..4ff939cd 100644 --- a/src/data/storage-stream.c +++ b/src/data/storage-stream.c @@ -1,6 +1,5 @@ /* PSPP - computes sample statistics. Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -28,37 +27,34 @@ #include #include #include -#include +#include #include "xalloc.h" -/* Information about storage sink or source. */ -struct storage_stream_info +/* Storage sink. */ + +/* Information about storage sink. */ +struct storage_sink_info { struct casefile *casefile; /* Storage. */ }; - -/* Storage sink. */ + +static struct storage_sink_info * +get_storage_sink_info (struct case_sink *sink) +{ + assert (sink->class == &storage_sink_class); + return sink->aux; +} /* Initializes a storage sink. */ static void storage_sink_open (struct case_sink *sink) { - struct storage_stream_info *info; + struct storage_sink_info *info; sink->aux = info = xmalloc (sizeof *info); - info->casefile = fastfile_create (sink->value_cnt); -} - -/* Destroys storage stream represented by INFO. */ -static void -destroy_storage_stream_info (struct storage_stream_info *info) -{ - if (info != NULL) - { - casefile_destroy (info->casefile); - free (info); - } + info->casefile = sink->factory->create_casefile (sink->factory, + sink->value_cnt); } /* Writes case C to the storage sink SINK. @@ -66,8 +62,7 @@ destroy_storage_stream_info (struct storage_stream_info *info) static bool storage_sink_write (struct case_sink *sink, const struct ccase *c) { - struct storage_stream_info *info = sink->aux; - + struct storage_sink_info *info = get_storage_sink_info (sink); return casefile_append (info->casefile, c); } @@ -75,7 +70,9 @@ storage_sink_write (struct case_sink *sink, const struct ccase *c) static void storage_sink_destroy (struct case_sink *sink) { - destroy_storage_stream_info (sink->aux); + struct storage_sink_info *info = get_storage_sink_info (sink); + casefile_destroy (info->casefile); + free (info); } /* Closes the sink and returns a storage source to read back the @@ -83,9 +80,9 @@ storage_sink_destroy (struct case_sink *sink) static struct case_source * storage_sink_make_source (struct case_sink *sink) { - struct case_source *source - = create_case_source (&storage_source_class, sink->aux); - sink->aux = NULL; + struct storage_sink_info *info = get_storage_sink_info (sink); + struct case_source *source = storage_source_create (info->casefile); + info->casefile = NULL; return source; } @@ -101,65 +98,73 @@ const struct case_sink_class storage_sink_class = /* Storage source. */ +struct storage_source_info + { + struct casefile *casefile; /* Storage. */ + struct casereader *reader; /* Reader. */ + }; + +static struct storage_source_info * +get_storage_source_info (const struct case_source *source) +{ + assert (source->class == &storage_source_class); + return source->aux; +} + /* Returns the number of cases that will be read by storage_source_read(). */ static int storage_source_count (const struct case_source *source) { - struct storage_stream_info *info = source->aux; - + struct storage_source_info *info = get_storage_source_info (source); return casefile_get_case_cnt (info->casefile); } -/* Reads all cases from the storage source and passes them one by one to - write_case(). */ +/* Reads one case into OUTPUT_CASE. + Returns true if successful, false at end of file or if an + I/O error occurred. */ static bool -storage_source_read (struct case_source *source, - struct ccase *output_case, - write_case_func *write_case, write_case_data wc_data) +storage_source_read (struct case_source *source, struct ccase *output_case) { - struct storage_stream_info *info = source->aux; + struct storage_source_info *info = get_storage_source_info (source); struct ccase casefile_case; - struct casereader *reader; - bool ok = true; - for (reader = casefile_get_reader (info->casefile, NULL); - ok && casereader_read (reader, &casefile_case); - case_destroy (&casefile_case)) + if (info->reader == NULL) + info->reader = casefile_get_reader (info->casefile, NULL); + + if (casereader_read (info->reader, &casefile_case)) { case_copy (output_case, 0, &casefile_case, 0, casefile_get_value_cnt (info->casefile)); - ok = write_case (wc_data); + return true; } - casereader_destroy (reader); - - return ok; + else + return false; } -/* Destroys the source's internal data. */ -static void +/* Destroys the source. + Returns true if successful read, false if an I/O occurred + during destruction or previously. */ +static bool storage_source_destroy (struct case_source *source) { - destroy_storage_stream_info (source->aux); + struct storage_source_info *info = get_storage_source_info (source); + bool ok = true; + if (info->casefile) + { + ok = !casefile_error (info->casefile); + casefile_destroy (info->casefile); + } + free (info); + return ok; } -/* Storage source. */ -const struct case_source_class storage_source_class = - { - "storage", - storage_source_count, - storage_source_read, - storage_source_destroy, - }; - /* Returns the casefile encapsulated by SOURCE. */ struct casefile * storage_source_get_casefile (struct case_source *source) { - struct storage_stream_info *info = source->aux; - - assert (source->class == &storage_source_class); + struct storage_source_info *info = get_storage_source_info (source); return info->casefile; } @@ -168,25 +173,33 @@ storage_source_get_casefile (struct case_source *source) struct casefile * storage_source_decapsulate (struct case_source *source) { - struct storage_stream_info *info = source->aux; - struct casefile *casefile; - - assert (source->class == &storage_source_class); - casefile = info->casefile; + struct storage_source_info *info = get_storage_source_info (source); + struct casefile *casefile = info->casefile; + assert (info->reader == NULL); info->casefile = NULL; free_case_source (source); return casefile; } -/* Creates and returns a new storage stream that encapsulates +/* Creates and returns a new storage source that encapsulates CASEFILE. */ struct case_source * storage_source_create (struct casefile *casefile) { - struct storage_stream_info *info; + struct storage_source_info *info; info = xmalloc (sizeof *info); info->casefile = casefile; + info->reader = NULL; return create_case_source (&storage_source_class, info); } + +/* Storage source. */ +const struct case_source_class storage_source_class = + { + "storage", + storage_source_count, + storage_source_read, + storage_source_destroy, + };