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