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
|
#include "stlfile.h"
#include "util.h"
void
stack_init(struct stack *stack)
{
stack->cap = 10;
stack->data = checkp(malloc(sizeof(int) * stack->cap));
stack->count = 0;
}
void
stack_push(struct stack *stack, int v)
{
if (stack->count == stack->cap) {
stack->cap *= 2;
stack->data = checkp(realloc(stack->data, sizeof(int) * stack->cap));
}
stack->data[stack->count] = v;
stack->count++;
}
int
stack_pop(struct stack *stack)
{
if (stack->count == 0)
die("popping empty stack!\n");
stack->count--;
return stack->data[stack->count];
}
void
stack_free(struct stack *stack)
{
free(stack->data);
}
int
consume_keyword(char **bp, char *end)
{
/* TODO */
return KW_SOLID_BEGIN;
}
int
parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
{
char *bp, *pbp, *end = buf + len;
struct stack states;
int type, kw;
stack_init(&states);
info = checkp(malloc(sizeof(struct parseinfo)));
info->type = TYPE_ASCII;
while ((kw = consume_keyword(&bp, end))) {
/* TODO */
}
stack_free(&states);
return OK;
fail:
stack_free(&states);
free(info);
return FAIL;
}
int
parse_file_bin(struct parseinfo *info, char *buf, size_t len)
{
char *bp, *end = buf + len;
unsigned int i;
if (len < 84) {
fprintf(stderr, "Truncated data! (header missing)\n");
return FAIL;
}
/* treat header as model name */
info->namehash = strdup(mhash(buf, 80));
bp = buf + 80;
info->loopcount = le32toh(*(uint32_t*)bp);
for (i = 0; i < info->loopcount; i++) {
if (bp + 50 > end) {
fprintf(stderr, "Truncated data! (loops missing)\n");
return FAIL;
}
bp += 50;
}
return OK;
}
int
parse_file(struct parseinfo *info, char *buf, size_t len)
{
char *bp;
if (info->valid) {
NULLFREE(info->infopath);
NULLFREE(info->namehash);
NULLFREE(info->stlpath);
}
/* check bin vs ascii */
for (bp = buf; strchr(" \n\r\t", *bp); bp++);
return !strncmp("solid ", bp, 6)
? parse_file_ascii(info, buf, len)
: parse_file_bin(info, buf, len);
}
|