1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "data/casereader-provider.h"
20 #include "data/subcase.h"
22 #include "gl/xalloc.h"
25 projection_is_no_op (const struct casereader
*reader
, const struct subcase
*sc
)
27 size_t n
= subcase_get_n_fields (sc
);
30 if (n
!= caseproto_get_n_widths (casereader_get_proto (reader
)))
33 for (i
= 0; i
< n
; i
++)
34 if (subcase_get_case_index (sc
, i
) != i
)
40 struct casereader_project
42 struct subcase old_sc
;
43 struct subcase new_sc
;
47 project_case (struct ccase
*old
, void *project_
)
49 const struct casereader_project
*project
= project_
;
50 struct ccase
*new = case_create (subcase_get_proto (&project
->new_sc
));
51 subcase_copy (&project
->old_sc
, old
, &project
->new_sc
, new);
57 destroy_projection (void *project_
)
59 struct casereader_project
*project
= project_
;
60 subcase_uninit (&project
->old_sc
);
61 subcase_uninit (&project
->new_sc
);
66 /* Returns a casereader in which each row is obtained by extracting the subcase
67 SC from the corresponding row of SUBREADER. */
69 casereader_project (struct casereader
*subreader
, const struct subcase
*sc
)
71 if (projection_is_no_op (subreader
, sc
))
72 return casereader_rename (subreader
);
75 struct casereader_project
*project
= xmalloc (sizeof *project
);
76 const struct caseproto
*proto
;
78 subcase_clone (&project
->old_sc
, sc
);
79 proto
= subcase_get_proto (&project
->old_sc
);
81 subcase_init_empty (&project
->new_sc
);
82 subcase_add_proto_always (&project
->new_sc
, proto
);
84 static const struct casereader_translator_class
class = {
85 project_case
, destroy_projection
,
88 return casereader_translate_stateless (subreader
, proto
,
93 /* Returns a casereader in which each row is obtained by extracting the value
94 with index COLUMN from the corresponding row of SUBREADER. */
96 casereader_project_1 (struct casereader
*subreader
, int column
)
98 const struct caseproto
*subproto
= casereader_get_proto (subreader
);
99 struct casereader
*reader
;
102 subcase_init (&sc
, column
, caseproto_get_width (subproto
, column
),
104 reader
= casereader_project (subreader
, &sc
);
105 subcase_uninit (&sc
);