annotate ater/read_file.c @ 20:5405c1573027

ater: implement file reading
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 24 Jun 2024 08:50:29 +0000
parents
children db39e8855f3d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
20
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Here we implement the function that reads binary files
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * in our ad hoc format for TRAU testing.
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 */
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <sys/types.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <sys/file.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <sys/stat.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdint.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdbool.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdlib.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <string.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <unistd.h>
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include "read_file.h"
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 static int check_magic(const uint8_t *buf, unsigned nframes, bool *got_fr,
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 bool *got_efr)
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 unsigned n;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 for (n = 0; n < nframes; n++) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 switch (*buf & 0xF0) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 case 0xC0:
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 *got_efr = true;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 break;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 case 0xD0:
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 *got_fr = true;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 break;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 default:
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 buf += 34;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 return 0;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 int read_binary_file(const char *filename, bool is_efr, uint8_t **bufret,
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 unsigned *size_ret)
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 int fd, rc;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 struct stat st;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 uint8_t *buf;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 unsigned nframes;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 bool got_fr, got_efr;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 fd = open(filename, O_RDONLY);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 if (fd < 0) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 perror(filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 fstat(fd, &st);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 if (!S_ISREG(st.st_mode)) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 close(fd);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 fprintf(stderr, "error: %s is not a regular file\n", filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 if (!st.st_size) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 close(fd);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 fprintf(stderr, "error: %s is an empty file\n", filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 if (st.st_size % 34) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 close(fd);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 fprintf(stderr,
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 "error: size of %s is not a multiple of 34 bytes\n",
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 buf = malloc(st.st_size);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 if (!buf) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 close(fd);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 fprintf(stderr, "unable to malloc buffer for %s\n", filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 read(fd, buf, st.st_size);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 close(fd);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 nframes = st.st_size / 34;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 got_fr = false;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 got_efr = false;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 rc = check_magic(buf, nframes, &got_fr, &got_efr);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 if (rc < 0 || got_fr && got_efr) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 free(buf);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 fprintf(stderr, "error: %s is not a valid TRAU-UL test file\n",
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 if (is_efr != got_efr) {
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 free(buf);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 fprintf(stderr, "error: %s is for the wrong codec\n", filename);
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 return -1;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 }
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 *bufret = buf;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 *size_ret = nframes;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 return 0;
5405c1573027 ater: implement file reading
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 }