aboutsummaryrefslogtreecommitdiffstats
path: root/service/src/stlfile.c
blob: 3ae1441b996480fe57ab4452b92964623769e9cf (plain) (blame)
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);
}