📄 rply.c
字号:
static int ply_read_scalar_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument) { p_ply_read_cb read_cb = property->read_cb; p_ply_ihandler *driver = ply->idriver->ihandler; p_ply_ihandler handler = driver[property->type]; argument->length = 1; argument->value_index = 0; if (!handler(ply, &argument->value)) { ply_error(ply, "Error reading '%s' of '%s' number %d", property->name, element->name, argument->instance_index); return 0; } if (read_cb && !read_cb(argument)) { ply_error(ply, "Aborted by user"); return 0; } return 1;}static int ply_read_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument) { if (property->type == PLY_LIST) return ply_read_list_property(ply, element, property, argument); else return ply_read_scalar_property(ply, element, property, argument);}static int ply_read_element(p_ply ply, p_ply_element element, p_ply_argument argument) { long j, k; /* for each element of this type */ for (j = 0; j < element->ninstances; j++) { argument->instance_index = j; /* for each property */ for (k = 0; k < element->nproperties; k++) { p_ply_property property = &element->property[k]; argument->property = property; argument->pdata = property->pdata; argument->idata = property->idata; if (!ply_read_property(ply, element, property, argument)) return 0; } } return 1;}static int ply_find_string(const char *item, const char* const list[]) { int i; assert(item && list); for (i = 0; list[i]; i++) if (!strcmp(list[i], item)) return i; return -1;}static p_ply_element ply_find_element(p_ply ply, const char *name) { p_ply_element element; int i, nelements; assert(ply && name); element = ply->element; nelements = ply->nelements; assert(element || nelements == 0); assert(!element || nelements > 0); for (i = 0; i < nelements; i++) if (!strcmp(element[i].name, name)) return &element[i]; return NULL;}static p_ply_property ply_find_property(p_ply_element element, const char *name) { p_ply_property property; int i, nproperties; assert(element && name); property = element->property; nproperties = element->nproperties; assert(property || nproperties == 0); assert(!property || nproperties > 0); for (i = 0; i < nproperties; i++) if (!strcmp(property[i].name, name)) return &property[i]; return NULL;}static int ply_check_word(p_ply ply) { if (strlen(BLINE(ply)) >= WORDSIZE) { ply_error(ply, "Word too long"); return 0; } return 1;}static int ply_read_word(p_ply ply) { size_t t = 0; assert(ply && ply->fp && ply->io_mode == PLY_READ); /* skip leading blanks */ while (1) { t = strspn(BFIRST(ply), " \n\r\t"); /* check if all buffer was made of blanks */ if (t >= BSIZE(ply)) { if (!BREFILL(ply)) { ply_error(ply, "Unexpected end of file"); return 0; } } else break; } BSKIP(ply, t); /* look for a space after the current word */ t = strcspn(BFIRST(ply), " \n\r\t"); /* if we didn't reach the end of the buffer, we are done */ if (t < BSIZE(ply)) { ply->buffer_token = ply->buffer_first; BSKIP(ply, t); *BFIRST(ply) = '\0'; BSKIP(ply, 1); return ply_check_word(ply); } /* otherwise, try to refill buffer */ if (!BREFILL(ply)) { ply_error(ply, "Unexpected end of file"); return 0; } /* keep looking from where we left */ t += strcspn(BFIRST(ply) + t, " \n\r\t"); /* check if the token is too large for our buffer */ if (t >= BSIZE(ply)) { ply_error(ply, "Token too large"); return 0; } /* we are done */ ply->buffer_token = ply->buffer_first; BSKIP(ply, t); *BFIRST(ply) = '\0'; BSKIP(ply, 1); return ply_check_word(ply);}static int ply_check_line(p_ply ply) { if (strlen(BLINE(ply)) >= LINESIZE) { ply_error(ply, "Line too long"); return 0; } return 1;}static int ply_read_line(p_ply ply) { const char *end = NULL; assert(ply && ply->fp && ply->io_mode == PLY_READ); /* look for a end of line */ end = strchr(BFIRST(ply), '\n'); /* if we didn't reach the end of the buffer, we are done */ if (end) { ply->buffer_token = ply->buffer_first; BSKIP(ply, end - BFIRST(ply)); *BFIRST(ply) = '\0'; BSKIP(ply, 1); return ply_check_line(ply); } else { end = ply->buffer + BSIZE(ply); /* otherwise, try to refill buffer */ if (!BREFILL(ply)) { ply_error(ply, "Unexpected end of file"); return 0; } } /* keep looking from where we left */ end = strchr(end, '\n'); /* check if the token is too large for our buffer */ if (!end) { ply_error(ply, "Token too large"); return 0; } /* we are done */ ply->buffer_token = ply->buffer_first; BSKIP(ply, end - BFIRST(ply)); *BFIRST(ply) = '\0'; BSKIP(ply, 1); return ply_check_line(ply);}static int ply_read_chunk(p_ply ply, void *anybuffer, size_t size) { char *buffer = (char *) anybuffer; size_t i = 0; assert(ply && ply->fp && ply->io_mode == PLY_READ); assert(ply->buffer_first <= ply->buffer_last); while (i < size) { if (ply->buffer_first < ply->buffer_last) { buffer[i] = ply->buffer[ply->buffer_first]; ply->buffer_first++; i++; } else { ply->buffer_first = 0; ply->buffer_last = fread(ply->buffer, 1, BUFFERSIZE, ply->fp); if (ply->buffer_last <= 0) return 0; } } return 1;}static int ply_write_chunk(p_ply ply, void *anybuffer, size_t size) { char *buffer = (char *) anybuffer; size_t i = 0; assert(ply && ply->fp && ply->io_mode == PLY_WRITE); assert(ply->buffer_last <= BUFFERSIZE); while (i < size) { if (ply->buffer_last < BUFFERSIZE) { ply->buffer[ply->buffer_last] = buffer[i]; ply->buffer_last++; i++; } else { ply->buffer_last = 0; if (fwrite(ply->buffer, 1, BUFFERSIZE, ply->fp) < BUFFERSIZE) return 0; } } return 1;}static int ply_write_chunk_reverse(p_ply ply, void *anybuffer, size_t size) { int ret = 0; ply_reverse(anybuffer, size); ret = ply_write_chunk(ply, anybuffer, size); ply_reverse(anybuffer, size); return ret;}static int ply_read_chunk_reverse(p_ply ply, void *anybuffer, size_t size) { if (!ply_read_chunk(ply, anybuffer, size)) return 0; ply_reverse(anybuffer, size); return 1;}static void ply_reverse(void *anydata, size_t size) { char *data = (char *) anydata; char temp; size_t i; for (i = 0; i < size/2; i++) { temp = data[i]; data[i] = data[size-i-1]; data[size-i-1] = temp; }}static void ply_init(p_ply ply) { ply->c = ' '; ply->element = NULL; ply->nelements = 0; ply->comment = NULL; ply->ncomments = 0; ply->obj_info = NULL; ply->nobj_infos = 0; ply->idriver = NULL; ply->odriver = NULL; ply->buffer[0] = '\0'; ply->buffer_first = ply->buffer_last = ply->buffer_token = 0; ply->welement = 0; ply->wproperty = 0; ply->winstance_index = 0; ply->wlength = 0; ply->wvalue_index = 0;}static void ply_element_init(p_ply_element element) { element->name[0] = '\0'; element->ninstances = 0; element->property = NULL; element->nproperties = 0; }static void ply_property_init(p_ply_property property) { property->name[0] = '\0'; property->type = -1; property->length_type = -1; property->value_type = -1; property->read_cb = (p_ply_read_cb) NULL; property->pdata = NULL; property->idata = 0;}static p_ply ply_alloc(void) { p_ply ply = (p_ply) malloc(sizeof(t_ply)); if (!ply) return NULL; ply_init(ply); return ply;}static void *ply_grow_array(p_ply ply, void **pointer, long *nmemb, long size) { void *temp = *pointer; long count = *nmemb + 1; if (!temp) temp = malloc(count*size); else temp = realloc(temp, count*size); if (!temp) { ply_error(ply, "Out of memory"); return NULL; } *pointer = temp; *nmemb = count; return (char *) temp + (count-1) * size;}static p_ply_element ply_grow_element(p_ply ply) { p_ply_element element = NULL; assert(ply); assert(ply->element || ply->nelements == 0); assert(!ply->element || ply->nelements > 0); element = (p_ply_element) ply_grow_array(ply, (void **) &ply->element, &ply->nelements, sizeof(t_ply_element)); if (!element) return NULL; ply_element_init(element); return element; }static p_ply_property ply_grow_property(p_ply ply, p_ply_element element) { p_ply_property property = NULL; assert(ply); assert(element); assert(element->property || element->nproperties == 0); assert(!element->property || element->nproperties > 0); property = (p_ply_property) ply_grow_array(ply, (void **) &element->property, &element->nproperties, sizeof(t_ply_property)); if (!property) return NULL; ply_property_init(property); return property;}static int ply_read_header_format(p_ply ply) { assert(ply && ply->fp && ply->io_mode == PLY_READ); if (strcmp(BWORD(ply), "format")) return 0; if (!ply_read_word(ply)) return 0; ply->storage_mode = ply_find_string(BWORD(ply), ply_storage_mode_list); if (ply->storage_mode == (e_ply_storage_mode) (-1)) return 0; if (ply->storage_mode == PLY_ASCII) ply->idriver = &ply_idriver_ascii; else if (ply->storage_mode == ply_arch_endian()) ply->idriver = &ply_idriver_binary; else ply->idriver = &ply_idriver_binary_reverse; if (!ply_read_word(ply)) return 0; if (strcmp(BWORD(ply), "1.0")) return 0; if (!ply_read_word(ply)) return 0; return 1;}static int ply_read_header_comment(p_ply ply) { assert(ply && ply->fp && ply->io_mode == PLY_READ); if (strcmp(BWORD(ply), "comment")) return 0; if (!ply_read_line(ply)) return 0; if (!ply_add_comment(ply, BLINE(ply))) return 0; if (!ply_read_word(ply)) return 0; return 1;}static int ply_read_header_obj_info(p_ply ply) { assert(ply && ply->fp && ply->io_mode == PLY_READ); if (strcmp(BWORD(ply), "obj_info")) return 0; if (!ply_read_line(ply)) return 0; if (!ply_add_obj_info(ply, BLINE(ply))) return 0; if (!ply_read_word(ply)) return 0; return 1;}static int ply_read_header_property(p_ply ply) { p_ply_element element = NULL; p_ply_property property = NULL; /* make sure it is a property */ if (strcmp(BWORD(ply), "property")) return 0; element = &ply->element[ply->nelements-1]; property = ply_grow_property(ply, element); if (!property) return 0; /* get property type */ if (!ply_read_word(ply)) return 0; property->type = ply_find_string(BWORD(ply), ply_type_list); if (property->type == (e_ply_type) (-1)) return 0; if (property->type == PLY_LIST) { /* if it's a list, we need the base types */ if (!ply_read_word(ply)) return 0; property->length_type = ply_find_string(BWORD(ply), ply_type_list); if (property->length_type == (e_ply_type) (-1)) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -