struct casereader_translator
{
struct casereader *subreader; /* Source of input cases. */
-
- struct ccase *(*translate) (struct ccase *input, void *aux);
- bool (*destroy) (void *aux);
+ const struct casereader_translator_class *class;
void *aux;
};
struct casereader *
casereader_create_translator (struct casereader *subreader,
const struct caseproto *output_proto,
- struct ccase *(*translate) (struct ccase *input,
- void *aux),
- bool (*destroy) (void *aux),
+ const struct casereader_translator_class *class,
void *aux)
{
struct casereader_translator *ct = xmalloc (sizeof *ct);
- struct casereader *reader;
- ct->subreader = casereader_rename (subreader);
- ct->translate = translate;
- ct->destroy = destroy;
- ct->aux = aux;
- reader = casereader_create_sequential (
+ *ct = (struct casereader_translator) {
+ .subreader = casereader_rename (subreader),
+ .class = class,
+ .aux = aux,
+ };
+
+ struct casereader *reader = casereader_create_sequential (
NULL, output_proto, casereader_get_n_cases (ct->subreader),
&casereader_translator_class, ct);
taint_propagate (casereader_get_taint (ct->subreader),
struct casereader_translator *ct = ct_;
struct ccase *tmp = casereader_read (ct->subreader);
if (tmp)
- tmp = ct->translate (tmp, ct->aux);
+ tmp = ct->class->translate (tmp, ct->aux);
return tmp;
}
{
struct casereader_translator *ct = ct_;
casereader_destroy (ct->subreader);
- ct->destroy (ct->aux);
+ ct->class->destroy (ct->aux);
free (ct);
}
/* Casereader that applies a user-supplied function to translate
each case into another in a stateless fashion. */
-/* A statelessly translating casereader. */
-struct casereader_stateless_translator
- {
- struct casereader *subreader; /* Source of input cases. */
-
- casenumber case_offset;
- struct ccase *(*translate) (struct ccase *input, casenumber,
- const void *aux);
- bool (*destroy) (void *aux);
- void *aux;
- };
-
static const struct casereader_random_class
casereader_stateless_translator_class;
cases may be skipped and never retrieved at all. If TRANSLATE is stateful,
use casereader_create_translator instead.
- The casenumber argument to the TRANSLATE function is the absolute case
- number in SUBREADER, that is, 0 when the first case in SUBREADER is being
- translated, 1 when the second case is being translated, and so on.
-
The cases returned by TRANSLATE must match OUTPUT_PROTO.
When the stateless translating casereader is destroyed, DESTROY will be
casereader_translate_stateless (
struct casereader *subreader,
const struct caseproto *output_proto,
- struct ccase *(*translate) (struct ccase *input, casenumber,
- const void *aux),
- bool (*destroy) (void *aux),
+ const struct casereader_translator_class *class,
void *aux)
{
- struct casereader_stateless_translator *cst = xmalloc (sizeof *cst);
- struct casereader *reader;
- cst->subreader = casereader_rename (subreader);
- cst->translate = translate;
- cst->destroy = destroy;
- cst->aux = aux;
- reader = casereader_create_random (
- output_proto, casereader_get_n_cases (cst->subreader),
- &casereader_stateless_translator_class, cst);
- taint_propagate (casereader_get_taint (cst->subreader),
+ struct casereader_translator *ct = xmalloc (sizeof *ct);
+ *ct = (struct casereader_translator) {
+ .subreader = casereader_rename (subreader),
+ .class = class,
+ .aux = aux,
+ };
+
+ struct casereader *reader = casereader_create_random (
+ output_proto, casereader_get_n_cases (ct->subreader),
+ &casereader_stateless_translator_class, ct);
+ taint_propagate (casereader_get_taint (ct->subreader),
casereader_get_taint (reader));
return reader;
}
/* Internal read function for stateless translating casereader. */
static struct ccase *
casereader_stateless_translator_read (struct casereader *reader UNUSED,
- void *cst_, casenumber idx)
+ void *ct_, casenumber idx)
{
- struct casereader_stateless_translator *cst = cst_;
- struct ccase *tmp = casereader_peek (cst->subreader, idx);
+ struct casereader_translator *ct = ct_;
+ struct ccase *tmp = casereader_peek (ct->subreader, idx);
if (tmp != NULL)
- tmp = cst->translate (tmp, cst->case_offset + idx, cst->aux);
+ tmp = ct->class->translate (tmp, ct->aux);
return tmp;
}
/* Internal destroy function for translating casereader. */
static void
casereader_stateless_translator_destroy (struct casereader *reader UNUSED,
- void *cst_)
+ void *ct_)
{
- struct casereader_stateless_translator *cst = cst_;
- casereader_destroy (cst->subreader);
- cst->destroy (cst->aux);
- free (cst);
-}
-
-static void
-casereader_stateless_translator_advance (struct casereader *reader UNUSED,
- void *cst_, casenumber n)
-{
- struct casereader_stateless_translator *cst = cst_;
- cst->case_offset += casereader_advance (cst->subreader, n);
+ struct casereader_translator *ct = ct_;
+ casereader_destroy (ct->subreader);
+ ct->class->destroy (ct->aux);
+ free (ct);
}
/* Casereader class for stateless translating casereader. */
{
casereader_stateless_translator_read,
casereader_stateless_translator_destroy,
- casereader_stateless_translator_advance,
+ NULL,
};
\f
can->aux = aux;
can->func = func;
can->destroy = destroy;
- return casereader_create_translator (subreader, can->proto,
- can_translate, can_destroy, can);
+
+ static const struct casereader_translator_class class = {
+ can_translate, can_destroy,
+ };
+ return casereader_create_translator (subreader, can->proto, &class, can);
}
car->err = err;
car->prev_value = SYSMIS;
- return casereader_create_translator (subreader, car->proto,
- car_translate, car_destroy, car);
+ static const struct casereader_translator_class class = {
+ car_translate, car_destroy
+ };
+ return casereader_create_translator (subreader, car->proto, &class, car);
}
const struct variable *weight)
{
struct casereader *u ;
- struct casereader *ud ;
struct caseproto *output_proto = caseproto_ref (casereader_get_proto (input));
struct consolidator *cdr = xmalloc (sizeof (*cdr));
u = casereader_create_filter_func (input, uniquify,
NULL, cdr, NULL);
- ud = casereader_create_translator (u,
- output_proto,
- consolodate_weight,
- uniquify_destroy,
- cdr);
-
- return ud;
+ static const struct casereader_translator_class class = {
+ consolodate_weight, uniquify_destroy,
+ };
+ return casereader_create_translator (u, output_proto, &class, cdr);
}