1
2 #include "config.h"
3 #include <assert.h>
4 #ifdef HAVE_MALLOC_H
5 #include <malloc.h>
6 #endif
7 #include <fcntl.h>
8 #include <stdio.h>
9 #ifdef STDC_HEADERS
10 #include <stdlib.h>
11 #endif
12 #include <string.h>
13 #include "ffs.h"
14 #include "unix_defs.h"
15
16 typedef struct _first_rec {
17 int integer_field;
18 double double_field;
19 char char_field;
20 } first_rec, *first_rec_ptr;
21
22 typedef enum {
23 Red_Stripe, Paulaner, Pilsner
24 } enum_type;
25
26 static IOField field_list[] =
27 {
28 {"integer field", "integer",
29 sizeof(int), IOOffset(first_rec_ptr, integer_field)},
30 {"double field", "float",
31 sizeof(double), IOOffset(first_rec_ptr, double_field)},
32 {"char field", "char",
33 sizeof(char), IOOffset(first_rec_ptr, char_field)},
34 {NULL, NULL, 0, 0}
35 };
36
37 #define ARRAY_SIZE 14
38
39 typedef struct _fourth_rec {
40 long ifield;
41 int int_array[ARRAY_SIZE];
42 #if SIZEOF_LONG_DOUBLE != 0 && SIZEOF_LONG_DOUBLE != SIZEOF_DOUBLE
43 long double double_array[2][2];
44 #else
45 double double_array[2][2];
46 #endif
47 } fourth_rec, *fourth_rec_ptr;
48
49 static IOField field_list4[] =
50 {
51 {"ifield", "integer",
52 sizeof(long), IOOffset(fourth_rec_ptr, ifield)},
53 {"int_array", IOArrayDecl(integer, ARRAY_SIZE),
54 sizeof(int), IOOffset(fourth_rec_ptr, int_array[0])},
55 {"double field", "float[2][2]",
56 sizeof(((fourth_rec_ptr) 0)->double_array[0][0]),
57 IOOffset(fourth_rec_ptr, double_array[0][0])},
58 {NULL, NULL, 0, 0}
59 };
60
61 int
main(argc,argv)62 main(argc, argv)
63 int argc;
64 char **argv;
65 {
66 IOFile iofile = NULL;
67 IOFormat two_string_format, first_ioformat, fourth_ioformat;
68 IOFieldPtr long_field_descr, ulong_field_descr, uint_field_descr,
69 string2_descr, integer_field_descr, double_field_descr, string_field_descr,
70 char_field_descr, enum_field_descr;
71 char *buffer;
72 int buffer_size;
73 int check_only = 0;
74
75 switch (argc) {
76 case 1:
77 iofile = open_IOfile("test_output", "r");
78 break;
79 case 2:
80 if (strcmp(argv[1], "-check") == 0) {
81 iofile = open_IOfile("test_output", "r");
82 check_only++;
83 } else {
84 iofile = open_IOfile(argv[1], "r");
85 }
86 break;
87 case 3:
88 if (strcmp(argv[1], "-check") == 0) {
89 check_only++;
90 } else {
91 printf("Unknown arg \"%s\"\n", argv[1]);
92 exit(1);
93 }
94 iofile = open_IOfile(argv[2], "r");
95 break;
96 }
97
98 if (iofile == NULL) {
99 printf("Open failed\n");
100 exit(1);
101 }
102 if (!check_only)
103 dump_IOFile(iofile);
104
105 /* open two formats (Ignore the third) */
106 two_string_format = get_IOformat_by_name(iofile, "two string format");
107 assert(two_string_format != NULL);
108 first_ioformat = get_IOformat_by_name(iofile, "first format");
109 assert(first_ioformat != NULL);
110
111 set_IOconversion(iofile, "first format", field_list, sizeof(first_rec));
112
113 fourth_ioformat = get_IOformat_by_name(iofile, "internal array format");
114 assert(fourth_ioformat != NULL);
115
116 set_IOconversion(iofile, "internal array format", field_list4,
117 sizeof(fourth_rec));
118
119 /*
120 * for the second, we'll get each field individually.
121 * (Necessary if the formats differ) Get IOFieldPtr values for
122 * each of the fields.
123 */
124 long_field_descr = get_IOfieldPtr(iofile, "two string format",
125 "long field");
126 assert(long_field_descr != NULL);
127
128 uint_field_descr = get_IOfieldPtr(iofile, "two string format",
129 "uint field");
130 assert(uint_field_descr != NULL);
131
132 ulong_field_descr = get_IOfieldPtr(iofile, "two string format",
133 "ulong field");
134 assert(ulong_field_descr != NULL);
135
136 string2_descr = get_IOfieldPtr(iofile, "two string format",
137 "string field2");
138 assert(string2_descr != NULL);
139
140 integer_field_descr = get_IOfieldPtr(iofile, "two string format",
141 "integer field");
142 assert(integer_field_descr != NULL);
143
144 double_field_descr = get_IOfieldPtr(iofile, "two string format",
145 "double field");
146 assert(double_field_descr != NULL);
147
148 string_field_descr = get_IOfieldPtr(iofile, "two string format",
149 "string field");
150 assert(string_field_descr != NULL);
151
152 char_field_descr = get_IOfieldPtr(iofile, "two string format",
153 "char field");
154 assert(char_field_descr != NULL);
155
156 enum_field_descr = get_IOfieldPtr(iofile, "two string format",
157 "enum field");
158 assert(enum_field_descr != NULL);
159
160
161 /* start reading the file. allocate buffer space if you know
162 * the max record size before hand, use that here. variant records
163 * (with strings) have variant size though, so you'll have to do
164 * some dynamic stuff or set a max string length somehow
165 */
166 buffer = malloc(2048);
167 buffer_size = 2048;
168
169 while (next_IOrecord_format(iofile)) {
170 if (buffer_size < next_raw_IOrecord_length(iofile)) {
171 buffer_size = next_raw_IOrecord_length(iofile);
172 buffer = realloc(buffer, buffer_size);
173 }
174 if (next_IOrecord_format(iofile) == first_ioformat) {
175 if (next_IOrecord_count(iofile) == 1) {
176 /* read data directly to mem structure */
177 first_rec read_data;
178 if (!read_IOfile(iofile, &read_data))
179 fprintf(stderr, "read failed for format1\n");
180 printf("first format rec had %d, %g, %c\n",
181 read_data.integer_field, read_data.double_field,
182 read_data.char_field);
183 } else {
184 int i, count = 7;
185 first_rec *read_data = (first_rec *) malloc(sizeof(first_rec) *
186 count);
187 if (next_IOrecord_count(iofile) < count) {
188 count = next_IOrecord_count(iofile);
189 }
190 if (read_array_IOfile(iofile, read_data,
191 count, sizeof(first_rec)) != count) {
192 printf("array read failed\n");
193 }
194 printf("read %d elements of first_rec:\n", count);
195 for (i = 0; i < count; i++) {
196 printf("\t rec %d had %d, %g, %c\n", i,
197 read_data[i].integer_field,
198 read_data[i].double_field,
199 read_data[i].char_field);
200 }
201 }
202 } else if (next_IOrecord_format(iofile) == two_string_format) {
203 char *string1, *string2;
204 int int_var;
205 long long_var;
206 unsigned int uint_var;
207 unsigned long ulong_var;
208 enum_type enum_var;
209 double double_var;
210 char char_var;
211 if (!read_raw_IOfile(iofile, buffer, buffer_size, NULL))
212 fprintf(stderr, "read failed for format2\n");
213 string1 = get_IOstring(string_field_descr, buffer);
214 string2 = get_IOstring(string2_descr, buffer);
215 if (string1 == NULL)
216 string1 = "(null)";
217 if (string2 == NULL)
218 string2 = "(null)";
219 int_var = get_IOint(integer_field_descr, buffer);
220 double_var = get_IOdouble(double_field_descr, buffer);
221 long_var = get_IOlong(long_field_descr, buffer);
222 ulong_var = get_IOulong(ulong_field_descr, buffer);
223 uint_var = get_IOuint(uint_field_descr, buffer);
224 char_var = get_IOchar(char_field_descr, buffer);
225 enum_var = (enum_type) get_IOenum(enum_field_descr, buffer);
226 printf("int=%d, long=%ld, uint=%u, ulong=%lu, string1=%s, double=%g, string2=%s, char=%c, enum=",
227 int_var, long_var, uint_var, ulong_var, string1, double_var,
228 string2, char_var);
229 switch (enum_var) {
230 case Red_Stripe:
231 printf("Red_Stripe\n");
232 break;
233 case Paulaner:
234 printf("Paulaner\n");
235 break;
236 case Pilsner:
237 printf("Pilsner\n");
238 break;
239 default:
240 printf("Unknown_ enum_%d\n", (int) enum_var);
241 break;
242 }
243 } else if (next_IOrecord_format(iofile) == fourth_ioformat) {
244 /* read data directly to mem structure */
245 int i;
246 fourth_rec rec4;
247 if (!read_IOfile(iofile, &rec4))
248 fprintf(stderr, "read failed for format1\n");
249 printf("fourth format rec had %ld, in_array = (%d",
250 rec4.ifield, rec4.int_array[0]);
251 for (i = 1; i < ARRAY_SIZE; i++) {
252 printf(", %d", rec4.int_array[i]);
253 }
254 printf(")\n\t\tdouble array is ((%g, %g), (%g, %g))\n",
255 (double) rec4.double_array[0][0],
256 (double) rec4.double_array[0][1],
257 (double) rec4.double_array[1][0],
258 (double) rec4.double_array[1][1]);
259 } else {
260 /* read and discard */
261 printf("discarding a record\n");
262 read_IOfile(iofile, NULL);
263 }
264 }
265 close_IOfile(iofile);
266 free_IOfile(iofile);
267 return 0;
268 }
269