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