-
Notifications
You must be signed in to change notification settings - Fork 16
/
load_text.c
138 lines (129 loc) · 3.32 KB
/
load_text.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Author: Peter Sovietov */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "load_text.h"
static int load_file(const char* name, char** buffer, int* size) {
FILE* f = fopen(name, "rb");
if (f == NULL) {
return 0;
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
rewind(f);
*buffer = (char*) malloc(*size + 1);
if (*buffer == NULL) {
fclose(f);
return 0;
}
if ((int) fread(*buffer, 1, *size, f) != *size) {
free(*buffer);
fclose(f);
return 0;
}
fclose(f);
(*buffer)[*size] = 0;
return 1;
}
static void skip(struct text_parser* p, int (*is_valid)(int)) {
for (; p->index < p->size && is_valid(p->text[p->index]); p->index += 1) {
}
}
static int parse_next(struct text_parser* p, const char* name) {
int size = (int) strlen(name);
skip(p, isspace);
if (strncmp(&p->text[p->index], name, size)) {
return 0;
}
p->index += size;
return 1;
}
int parse_int(struct text_parser* p, int* n) {
int size;
char* start;
char* end;
skip(p, isspace);
start = &p->text[p->index];
*n = strtol(start, &end, 0);
size = (int) (end - start);
if (size > 0) {
p->index += size;
return 1;
}
return 0;
}
int parse_float(struct text_parser* p, double* n) {
int size;
char* start;
char* end;
skip(p, isspace);
start = &p->text[p->index];
*n = strtod(start, &end);
size = (int) (end - start);
if (size > 0) {
p->index += size;
return 1;
}
return 0;
}
static int parse_frames(struct text_parser* p, int* frame_data, int frame_count) {
int i;
int* buffer = frame_data;
for (i = 0; i < frame_count * 16; i += 1) {
if(!parse_int(p, buffer)) {
return 0;
}
buffer += 1;
}
return 1;
}
static int is_not_space(int c) {
return !isspace(c);
}
int load_text_file(const char* name, struct text_data* t) {
int n;
double f;
struct text_parser p;
int ok = 1;
if (!load_file(name, &p.text, &p.size)) {
return 0;
}
p.index = 0;
while (p.index < p.size) {
if (parse_next(&p, "sample_rate") && parse_int(&p, &n)) {
t->sample_rate = n;
} else if (parse_next(&p, "is_ym") && parse_int(&p, &n)) {
t->is_ym = n;
} else if (parse_next(&p, "clock_rate") && parse_int(&p, &n)) {
t->clock_rate = n;
} else if (parse_next(&p, "frame_rate") && parse_float(&p, &f)) {
t->frame_rate = f;
} else if (parse_next(&p, "pan_a") && parse_int(&p, &n)) {
t->pan[0] = n / 100.;
} else if (parse_next(&p, "pan_b") && parse_int(&p, &n)) {
t->pan[1] = n / 100.;
} else if (parse_next(&p, "pan_c") && parse_int(&p, &n)) {
t->pan[2] = n / 100.;
} else if (parse_next(&p, "volume") && parse_int(&p, &n)) {
t->volume = n / 100.;
} else if (parse_next(&p, "eqp_stereo_on") && parse_int(&p, &n)) {
t->eqp_stereo_on = n;
} else if (parse_next(&p, "dc_filter_on") && parse_int(&p, &n)) {
t->dc_filter_on = n;
} else if (parse_next(&p, "frame_count") && parse_int(&p, &n) && t->frame_data == NULL) {
t->frame_data = (int*) malloc(n * 16 * sizeof(int));
if (t->frame_data == NULL) {
ok = 0;
break;
}
t->frame_count = n;
} else if (parse_next(&p, "frame_data") && parse_frames(&p, t->frame_data, t->frame_count)) {
break;
} else {
skip(&p, is_not_space);
}
}
free(p.text);
return ok;
}