Add support for reading and writing SPV files.
[pspp] / src / output / spv / spv.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2017 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17 #ifndef OUTPUT_SPV_H
18 #define OUTPUT_SPV_H 1
19
20 /* SPSS Viewer (SPV) file reader.
21
22    An SPV file, represented as struct spv_reader, contains a number of
23    top-level headings, each of which recursively contains other headings and
24    tables.  Here, we model a heading, text, table, or other element as an
25    "item", and a an SPV file as a single root item that contains each of the
26    top-level headings as a child item.
27  */
28
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include "libpspp/compiler.h"
33
34 struct pivot_table;
35 struct spv_data;
36 struct spv_reader;
37 struct spvlb_table;
38 struct _xmlDoc;
39
40 /* SPV files. */
41
42 char *spv_open (const char *filename, struct spv_reader **) WARN_UNUSED_RESULT;
43 void spv_close (struct spv_reader *);
44
45 char *spv_detect (const char *filename) WARN_UNUSED_RESULT;
46
47 const char *spv_get_errors (const struct spv_reader *);
48 void spv_clear_errors (struct spv_reader *);
49
50 struct spv_item *spv_get_root (const struct spv_reader *);
51 void spv_item_dump (const struct spv_item *, int indentation);
52
53 const struct page_setup *spv_get_page_setup (const struct spv_reader *);
54
55 /* Items.
56
57    An spv_item represents of the elements that can occur in an SPV file.  Items
58    form a tree because "heading" items can have an arbitrary number of child
59    items, which in turn may also be headings.  The root item, that is, the item
60    returned by spv_get_root(), is always a heading. */
61
62 enum spv_item_type
63   {
64     SPV_ITEM_HEADING,
65     SPV_ITEM_TEXT,
66     SPV_ITEM_TABLE,
67     SPV_ITEM_GRAPH,
68     SPV_ITEM_MODEL,
69     SPV_ITEM_OBJECT,
70   };
71
72 const char *spv_item_type_to_string (enum spv_item_type);
73
74 #define SPV_CLASSES                                \
75     SPV_CLASS(CHARTS, "charts")                    \
76     SPV_CLASS(HEADINGS, "headings")                \
77     SPV_CLASS(LOGS, "logs")                        \
78     SPV_CLASS(MODELS, "models")                    \
79     SPV_CLASS(TABLES, "tables")                    \
80     SPV_CLASS(TEXTS, "texts")                      \
81     SPV_CLASS(TREES, "trees")                      \
82     SPV_CLASS(WARNINGS, "warnings")                \
83     SPV_CLASS(OUTLINEHEADERS, "outlineheaders")    \
84     SPV_CLASS(PAGETITLE, "pagetitle")              \
85     SPV_CLASS(NOTES, "notes")                      \
86     SPV_CLASS(UNKNOWN, "unknown")                  \
87     SPV_CLASS(OTHER, "other")
88 enum spv_item_class
89   {
90 #define SPV_CLASS(ENUM, NAME) SPV_CLASS_##ENUM,
91     SPV_CLASSES
92 #undef SPV_CLASS
93   };
94 enum
95   {
96 #define SPV_CLASS(ENUM, NAME) +1
97     SPV_N_CLASSES = SPV_CLASSES
98 #undef SPV_CLASS
99 };
100
101 const char *spv_item_class_to_string (enum spv_item_class);
102 enum spv_item_class spv_item_class_from_string (const char *);
103
104 struct spv_item
105   {
106     struct spv_reader *spv;
107     struct spv_item *parent;
108     size_t parent_idx;
109
110     bool error;
111
112     char *structure_member;
113
114     enum spv_item_type type;
115     char *label;
116     char *command_id;           /* Unique command identifier. */
117
118     /* Whether the item is visible.
119        For SPV_ITEM_HEADING, false indicates that the item is collapsed.
120        For SPV_ITEM_TABLE, false indicates that the item is not shown. */
121     bool visible;
122
123     /* SPV_ITEM_HEADING only. */
124     struct spv_item **children;
125     size_t n_children, allocated_children;
126
127     /* SPV_ITEM_TABLE only. */
128     struct pivot_table *table;    /* NULL if not yet loaded. */
129     struct spv_legacy_properties *legacy_properties;
130     char *bin_member;
131     char *xml_member;
132     char *subtype;
133
134     /* SPV_ITEM_TEXT only.  */
135     struct pivot_value *text;
136
137     /* SPV_ITEM_OBJECT only. */
138     char *object_type;
139     char *uri;
140   };
141
142 void spv_item_load (const struct spv_item *);
143
144 enum spv_item_type spv_item_get_type (const struct spv_item *);
145 enum spv_item_class spv_item_get_class (const struct spv_item *);
146
147 const char *spv_item_get_label (const struct spv_item *);
148
149 bool spv_item_is_heading (const struct spv_item *);
150 size_t spv_item_get_n_children (const struct spv_item *);
151 struct spv_item *spv_item_get_child (const struct spv_item *, size_t idx);
152
153 bool spv_item_is_table (const struct spv_item *);
154 struct pivot_table *spv_item_get_table (const struct spv_item *);
155
156 bool spv_item_is_text (const struct spv_item *);
157 const struct pivot_value *spv_item_get_text (const struct spv_item *);
158
159 bool spv_item_is_visible (const struct spv_item *);
160
161 #define SPV_ITEM_FOR_EACH(ITER, ROOT) \
162   for ((ITER) = (ROOT); (ITER) != NULL; (ITER) = spv_item_next(ITER))
163 #define SPV_ITEM_FOR_EACH_SKIP_ROOT(ITER, ROOT) \
164   for ((ITER) = (ROOT); ((ITER) = spv_item_next(ITER)) != NULL; )
165 struct spv_item *spv_item_next (const struct spv_item *);
166
167 const struct spv_item *spv_item_get_parent (const struct spv_item *);
168 size_t spv_item_get_level (const struct spv_item *);
169
170 const char *spv_item_get_member_name (const struct spv_item *);
171 const char *spv_item_get_command_id (const struct spv_item *);
172 const char *spv_item_get_subtype (const struct spv_item *);
173
174 char *spv_item_get_structure (const struct spv_item *, struct _xmlDoc **)
175   WARN_UNUSED_RESULT;
176
177 bool spv_item_is_light_table (const struct spv_item *);
178 char *spv_item_get_light_table (const struct spv_item *,
179                                     struct spvlb_table **)
180   WARN_UNUSED_RESULT;
181 char *spv_item_get_raw_light_table (const struct spv_item *,
182                                     void **data, size_t *size)
183   WARN_UNUSED_RESULT;
184
185 bool spv_item_is_legacy_table (const struct spv_item *);
186 char *spv_item_get_raw_legacy_data (const struct spv_item *item,
187                                     void **data, size_t *size)
188   WARN_UNUSED_RESULT;
189 char *spv_item_get_legacy_data (const struct spv_item *, struct spv_data *)
190   WARN_UNUSED_RESULT;
191 char *spv_item_get_legacy_table (const struct spv_item *, struct _xmlDoc **)
192   WARN_UNUSED_RESULT;
193
194 struct fmt_spec spv_decode_fmt_spec (uint32_t u32);
195
196 #endif /* output/spv/spv.h */