📄 rply.c
字号:
* Write support functions * ---------------------------------------------------------------------- */p_ply ply_create(const char *name, e_ply_storage_mode storage_mode, p_ply_error_cb error_cb) { FILE *fp = NULL; p_ply ply = NULL; if (error_cb == NULL) error_cb = ply_error_cb; if (!ply_type_check()) { error_cb("Incompatible type system"); return NULL; } assert(name && storage_mode <= PLY_DEFAULT); fp = fopen(name, "wb"); if (!fp) { error_cb("Unable to create file"); return NULL; } ply = ply_alloc(); if (!ply) { fclose(fp); error_cb("Out of memory"); return NULL; } ply->io_mode = PLY_WRITE; if (storage_mode == PLY_DEFAULT) storage_mode = ply_arch_endian(); if (storage_mode == PLY_ASCII) ply->odriver = &ply_odriver_ascii; else if (storage_mode == ply_arch_endian()) ply->odriver = &ply_odriver_binary; else ply->odriver = &ply_odriver_binary_reverse; ply->storage_mode = storage_mode; ply->fp = fp; ply->error_cb = error_cb; return ply;}int ply_add_element(p_ply ply, const char *name, long ninstances) { p_ply_element element = NULL; assert(ply && ply->fp && ply->io_mode == PLY_WRITE); assert(name && strlen(name) < WORDSIZE && ninstances >= 0); if (strlen(name) >= WORDSIZE || ninstances < 0) { ply_error(ply, "Invalid arguments"); return 0; } element = ply_grow_element(ply); if (!element) return 0; strcpy(element->name, name); element->ninstances = ninstances; return 1;}int ply_add_scalar_property(p_ply ply, const char *name, e_ply_type type) { p_ply_element element = NULL; p_ply_property property = NULL; assert(ply && ply->fp && ply->io_mode == PLY_WRITE); assert(name && strlen(name) < WORDSIZE); assert(type < PLY_LIST); if (strlen(name) >= WORDSIZE || type >= PLY_LIST) { ply_error(ply, "Invalid arguments"); return 0; } element = &ply->element[ply->nelements-1]; property = ply_grow_property(ply, element); if (!property) return 0; strcpy(property->name, name); property->type = type; return 1;}int ply_add_list_property(p_ply ply, const char *name, e_ply_type length_type, e_ply_type value_type) { p_ply_element element = NULL; p_ply_property property = NULL; assert(ply && ply->fp && ply->io_mode == PLY_WRITE); assert(name && strlen(name) < WORDSIZE); if (strlen(name) >= WORDSIZE) { ply_error(ply, "Invalid arguments"); return 0; } assert(length_type < PLY_LIST); assert(value_type < PLY_LIST); if (length_type >= PLY_LIST || value_type >= PLY_LIST) { ply_error(ply, "Invalid arguments"); return 0; } element = &ply->element[ply->nelements-1]; property = ply_grow_property(ply, element); if (!property) return 0; strcpy(property->name, name); property->type = PLY_LIST; property->length_type = length_type; property->value_type = value_type; return 1;}int ply_add_property(p_ply ply, const char *name, e_ply_type type, e_ply_type length_type, e_ply_type value_type) { if (type == PLY_LIST) return ply_add_list_property(ply, name, length_type, value_type); else return ply_add_scalar_property(ply, name, type);}int ply_add_comment(p_ply ply, const char *comment) { char *new_comment = NULL; assert(ply && comment && strlen(comment) < LINESIZE); if (!comment || strlen(comment) >= LINESIZE) { ply_error(ply, "Invalid arguments"); return 0; } new_comment = (char *) ply_grow_array(ply, (void **) &ply->comment, &ply->ncomments, LINESIZE); if (!new_comment) return 0; strcpy(new_comment, comment); return 1;}int ply_add_obj_info(p_ply ply, const char *obj_info) { char *new_obj_info = NULL; assert(ply && obj_info && strlen(obj_info) < LINESIZE); if (!obj_info || strlen(obj_info) >= LINESIZE) { ply_error(ply, "Invalid arguments"); return 0; } new_obj_info = (char *) ply_grow_array(ply, (void **) &ply->obj_info, &ply->nobj_infos, LINESIZE); if (!new_obj_info) return 0; strcpy(new_obj_info, obj_info); return 1;}int ply_write_header(p_ply ply) { long i, j; assert(ply && ply->fp && ply->io_mode == PLY_WRITE); assert(ply->element || ply->nelements == 0); assert(!ply->element || ply->nelements > 0); if (fprintf(ply->fp, "ply\nformat %s 1.0\n", ply_storage_mode_list[ply->storage_mode]) <= 0) goto error; for (i = 0; i < ply->ncomments; i++) if (fprintf(ply->fp, "comment %s\n", ply->comment + LINESIZE*i) <= 0) goto error; for (i = 0; i < ply->nobj_infos; i++) if (fprintf(ply->fp, "obj_info %s\n", ply->obj_info + LINESIZE*i) <= 0) goto error; for (i = 0; i < ply->nelements; i++) { p_ply_element element = &ply->element[i]; assert(element->property || element->nproperties == 0); assert(!element->property || element->nproperties > 0); if (fprintf(ply->fp, "element %s %ld\n", element->name, element->ninstances) <= 0) goto error; for (j = 0; j < element->nproperties; j++) { p_ply_property property = &element->property[j]; if (property->type == PLY_LIST) { if (fprintf(ply->fp, "property list %s %s %s\n", ply_type_list[property->length_type], ply_type_list[property->value_type], property->name) <= 0) goto error; } else { if (fprintf(ply->fp, "property %s %s\n", ply_type_list[property->type], property->name) <= 0) goto error; } } } return fprintf(ply->fp, "end_header\n") > 0;error: ply_error(ply, "Error writing to file"); return 0;}int ply_write(p_ply ply, double value) { p_ply_element element = NULL; p_ply_property property = NULL; int type = -1; int breakafter = 0; if (ply->welement > ply->nelements) return 0; element = &ply->element[ply->welement]; if (ply->wproperty > element->nproperties) return 0; property = &element->property[ply->wproperty]; if (property->type == PLY_LIST) { if (ply->wvalue_index == 0) { type = property->length_type; ply->wlength = (long) value; } else type = property->value_type; } else { type = property->type; ply->wlength = 0; } if (!ply->odriver->ohandler[type](ply, value)) { ply_error(ply, "Failed writing %s of %s %d (%s: %s)", property->name, element->name, ply->winstance_index, ply->odriver->name, ply_type_list[type]); return 0; } ply->wvalue_index++; if (ply->wvalue_index > ply->wlength) { ply->wvalue_index = 0; ply->wproperty++; } if (ply->wproperty >= element->nproperties) { ply->wproperty = 0; ply->winstance_index++; if (ply->storage_mode == PLY_ASCII) breakafter = 1; } if (ply->winstance_index >= element->ninstances) { ply->winstance_index = 0; ply->welement++; } return !breakafter || putc('\n', ply->fp) > 0;}int ply_close(p_ply ply) { long i; assert(ply && ply->fp); assert(ply->element || ply->nelements == 0); assert(!ply->element || ply->nelements > 0); /* write last chunk to file */ if (ply->io_mode == PLY_WRITE && fwrite(ply->buffer, 1, ply->buffer_last, ply->fp) < ply->buffer_last) { ply_error(ply, "Error closing up"); return 0; } fclose(ply->fp); /* free all memory used by handle */ if (ply->element) { for (i = 0; i < ply->nelements; i++) { p_ply_element element = &ply->element[i]; if (element->property) free(element->property); } free(ply->element); } if (ply->obj_info) free(ply->obj_info); if (ply->comment) free(ply->comment); free(ply); return 1;}/* ---------------------------------------------------------------------- * Query support functions * ---------------------------------------------------------------------- */p_ply_element ply_get_next_element(p_ply ply, p_ply_element last) { assert(ply); if (!last) return ply->element; last++; if (last < ply->element + ply->nelements) return last; else return NULL;}int ply_get_element_info(p_ply_element element, const char** name, long *ninstances) { assert(element); if (name) *name = element->name; if (ninstances) *ninstances = (long) element->ninstances; return 1;}p_ply_property ply_get_next_property(p_ply_element element, p_ply_property last) { assert(element); if (!last) return element->property; last++; if (last < element->property + element->nproperties) return last; else return NULL;}int ply_get_property_info(p_ply_property property, const char** name, e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type) { assert(property); if (name) *name = property->name; if (type) *type = property->type; if (length_type) *length_type = property->length_type; if (value_type) *value_type = property->value_type; return 1;}const char *ply_get_next_comment(p_ply ply, const char *last) { assert(ply); if (!last) return ply->comment; last += LINESIZE; if (last < ply->comment + LINESIZE*ply->ncomments) return last; else return NULL;}const char *ply_get_next_obj_info(p_ply ply, const char *last) { assert(ply); if (!last) return ply->obj_info; last += LINESIZE; if (last < ply->obj_info + LINESIZE*ply->nobj_infos) return last; else return NULL;}/* ---------------------------------------------------------------------- * Callback argument support functions * ---------------------------------------------------------------------- */int ply_get_argument_element(p_ply_argument argument, p_ply_element *element, long *instance_index) { assert(argument); if (!argument) return 0; if (element) *element = argument->element; if (instance_index) *instance_index = argument->instance_index; return 1;}int ply_get_argument_property(p_ply_argument argument, p_ply_property *property, long *length, long *value_index) { assert(argument); if (!argument) return 0; if (property) *property = argument->property; if (length) *length = argument->length; if (value_index) *value_index = argument->value_index; return 1;}int ply_get_argument_user_data(p_ply_argument argument, void **pdata, long *idata) { assert(argument); if (!argument) return 0; if (pdata) *pdata = argument->pdata; if (idata) *idata = argument->idata; return 1;}double ply_get_argument_value(p_ply_argument argument) { assert(argument); if (!argument) return 0.0; return argument->value;}/* ---------------------------------------------------------------------- * Internal functions * ---------------------------------------------------------------------- */static int ply_read_list_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument) { int l; p_ply_read_cb read_cb = property->read_cb; p_ply_ihandler *driver = ply->idriver->ihandler; /* get list length */ p_ply_ihandler handler = driver[property->length_type]; double length; if (!handler(ply, &length)) { ply_error(ply, "Error reading '%s' of '%s' number %d", property->name, element->name, argument->instance_index); return 0; } /* invoke callback to pass length in value field */ argument->length = (long) length; argument->value_index = -1; argument->value = length; if (read_cb && !read_cb(argument)) { ply_error(ply, "Aborted by user"); return 0; } /* read list values */ handler = driver[property->value_type]; /* for each value in list */ for (l = 0; l < (long) length; l++) { /* read value from file */ argument->value_index = l; if (!handler(ply, &argument->value)) { ply_error(ply, "Error reading value number %d of '%s' of " "'%s' number %d", l+1, property->name, element->name, argument->instance_index); return 0; } /* invoke callback to pass value */ if (read_cb && !read_cb(argument)) { ply_error(ply, "Aborted by user"); return 0; } } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -