aboutsummaryrefslogtreecommitdiffstats
path: root/service/src/stlfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'service/src/stlfile.c')
-rw-r--r--service/src/stlfile.c108
1 files changed, 78 insertions, 30 deletions
diff --git a/service/src/stlfile.c b/service/src/stlfile.c
index 6a59dd1..4f6d0e1 100644
--- a/service/src/stlfile.c
+++ b/service/src/stlfile.c
@@ -68,16 +68,16 @@ skip_set(char *p, const char *set)
}
char*
-consume_arg(char **start)
+consume_arg(char **start, char **end)
{
char *p, *tmp;
p = skip_set(*start, wsset);
for (; !strchr(wsset, *p); p++);
if (!*p) return NULL;
- *p = '\0';
tmp = *start;
*start = p + 1;
+ *end = p;
return tmp;
}
@@ -107,7 +107,7 @@ consume_keyword(char **start)
int
parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
{
- char *bp, *arg, *prev, *tmp;
+ char *bp, *arg, *prev, *tmp, *end;
struct stack states;
float farg;
int i, kw;
@@ -117,6 +117,8 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
info->type = TYPE_ASCII;
info->loopcount = 0;
+ memset(info->header, 0, 80);
+
for (i = 0; i < 3; i++) {
info->bbmin[i] = INFINITY;
info->bbmax[i] = -INFINITY;
@@ -130,8 +132,8 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
if (stack_ind(&states, KW_SOLID_BEGIN) != -1)
PARSE_FAIL("Multiple nested solids!\n");
tmp = bp;
- if (!consume_keyword(&bp) && (arg = consume_arg(&bp))) {
- strncpy(info->extra, arg, sizeof(info->extra));
+ if (!consume_keyword(&bp) && (arg = consume_arg(&bp, &end))) {
+ info->modelname = strndup(arg, end - arg);
} else {
bp = tmp;
}
@@ -140,9 +142,9 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
if ((kw = stack_pop(&states)) != STATE_SOLID)
PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
tmp = bp;
- if (*info->extra && !consume_keyword(&bp)
- && (arg = consume_arg(&bp))) {
- if (strncmp(info->extra, arg, sizeof(info->extra)))
+ if (info->modelname && !consume_keyword(&bp)
+ && (arg = consume_arg(&bp, &end))) {
+ if (strncmp(info->modelname, arg, end - arg))
PARSE_FAIL("Solid end/begin names do not match!\n");
} else {
bp = tmp;
@@ -163,10 +165,10 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
if (stack_ind(&states, KW_LOOP_BEGIN) != -1)
PARSE_FAIL("Multiple nested facets!\n");
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp)))
+ if (!(arg = consume_arg(&bp, &end)))
PARSE_FAIL("Facet with less than 3 args!\n");
farg = strtof(arg, &tmp);
- if (*tmp)
+ if (!strchr(wsset, *tmp))
PARSE_FAIL("Facet with invalid arg '%s'!\n", arg);
}
break;
@@ -176,10 +178,10 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
break;
case KW_VERTEX:
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp)))
+ if (!(arg = consume_arg(&bp, &end)))
PARSE_FAIL("Vertex with less than 3 args!\n");
farg = strtof(arg, &tmp);
- if (*tmp)
+ if (!strchr(wsset, *tmp))
PARSE_FAIL("Vertex with invalid arg '%s'!\n", arg);
info->bbmin[i] = MIN(info->bbmin[i], farg);
info->bbmax[i] = MAX(info->bbmax[i], farg);
@@ -215,7 +217,7 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
if (len < 84)
PARSE_FAIL("Truncated data! (header missing)\n");
- memcpy(info->extra, buf, 80);
+ memcpy(info->header, buf, 80);
bp = buf + 80;
info->loopcount = le32toh(*(uint32_t*)bp);
@@ -249,33 +251,79 @@ int
parse_file(struct parseinfo *info, char *buf, size_t len)
{
int status;
+ const char *tmp;
char *bp;
if (info->valid) free_info(info);
- /* check bin vs ascii */
for (bp = buf; strchr(wsset, *bp); bp++);
+ /* check bin vs ascii with first keyword */
status = !strncmp("solid ", bp, 6)
? parse_file_ascii(info, buf, len)
: parse_file_bin(info, buf, len);
if (status == FAIL) return FAIL;
- /* create model hash */
- strncpy(info->hash, mhash(info->extra, sizeof(info->extra)), MHASHLEN);
+ if (!info->modelname) {
+ tmp = ask("Please enter your model name:\n");
+ if (strlen(tmp) < 4) {
+ fprintf(stderr, "Model name is too short!\n");
+ return FAIL;
+ }
+ info->modelname = checkp(strdup(tmp));
+ }
+
+ info->hash = checkp(strdup(mhash(info->modelname, -1)));
return OK;
}
int
-save_info(struct parseinfo *info, const char *resultdir)
+save_info(struct parseinfo *info, FILE *f)
{
- /* <HASH>:
- * - info : binary file info
- * - model : original stl file
- */
+ size_t nwrote = 0;
+ int i;
- return FAIL;
+ nwrote += fwrite(&info->type, sizeof(int), 1, f);
+ nwrote += fwrite(&info->loopcount, sizeof(int), 1, f);
+
+ for (i = 0; i < 3; i++) {
+ nwrote += fwrite(&info->bbmin[i], sizeof(float), 1, f);
+ nwrote += fwrite(&info->bbmax[i], sizeof(float), 1, f);
+ }
+
+ nwrote += fwrite(info->header, 80, 1, f);
+
+ if (nwrote != 9) return FAIL;
+
+ fputstr(f, info->modelname);
+ fputstr(f, info->hash);
+
+ return OK;
+}
+
+int
+load_info(struct parseinfo *info, FILE *f)
+{
+ size_t nread = 0;
+ int i;
+
+ nread += fread(&info->type, sizeof(int), 1, f);
+ nread += fread(&info->loopcount, sizeof(int), 1, f);
+
+ for (i = 0; i < 3; i++) {
+ nread += fwrite(&info->bbmin[i], sizeof(float), 1, f);
+ nread += fwrite(&info->bbmax[i], sizeof(float), 1, f);
+ }
+
+ nread += fread(info->header, 80, 1, f);
+
+ if (nread != 9) return FAIL;
+
+ freadstr(f, &info->modelname);
+ freadstr(f, &info->hash);
+
+ return OK;
}
void
@@ -285,16 +333,16 @@ print_info(struct parseinfo *info)
#define FILTERCHAR(c) ((c) >= 32 ? (c) : ' ')
- if (info->type == TYPE_ASCII) {
- printf("Modelname: %s\n", info->extra);
- } else {
- printf("Model Header:\n");
+ printf("Name: %s\n", info->modelname);
+
+ if (info->type == TYPE_BIN) {
+ printf("Header:\n");
for (i = 0; i < 80; i += k) {
for (k = 0; k < MIN(80 - i, 20); k++)
- printf(" %02x", (uint8_t) info->extra[i+k]);
+ printf(" %02x", (uint8_t) info->header[i+k]);
printf(" | ");
for (k = 0; k < MIN(80 - i, 20); k++)
- printf("%c", FILTERCHAR(info->extra[i+k]));
+ printf("%c", FILTERCHAR(info->header[i+k]));
printf("\n");
}
}
@@ -310,7 +358,7 @@ print_info(struct parseinfo *info)
void
free_info(struct parseinfo *info)
{
- NULLFREE(info->stlpath);
- NULLFREE(info->infopath);
+ NULLFREE(info->hash);
+ NULLFREE(info->modelname);
info->valid = 0;
}