示例#1
0
int
rt_mk_binunif(struct rt_wdb *wdbp, const char *obj_name, const char *file_name, unsigned int minor_type, size_t max_count)
{
    int ret;
    struct stat st;
    size_t num_items = 0;
    size_t obj_length = 0;
    size_t item_length = 0;
    unsigned int major_type = DB5_MAJORTYPE_BINARY_UNIF;
    struct directory *dp = NULL;
    struct bu_mapped_file *bu_fd = NULL;
    struct rt_binunif_internal *bip = NULL;
    struct bu_external body;
    struct bu_external bin_ext;
    struct rt_db_internal intern;

    item_length = db5_type_sizeof_h_binu(minor_type);
    if (item_length == 0) {
	bu_log("Unrecognized minor type (%d)!\n", minor_type);
	return -1;
    }

    if (bu_stat(file_name, &st)) {
	bu_log("Cannot stat input file (%s)", file_name);
	return -1;
    }

    bu_fd = bu_open_mapped_file(file_name, NULL);
    if (bu_fd == NULL) {
	bu_log("Cannot open input file (%s) for reading", file_name);
	return -1;
    }

    /* create the rt_binunif internal form */
    BU_ALLOC(bip, struct rt_binunif_internal);
    bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
    bip->type = minor_type;

    num_items = (size_t)(st.st_size / item_length);

    /* maybe only a partial file read */
    if (max_count > 0 && max_count < num_items) {
	num_items = max_count;
    }

    obj_length = num_items * item_length;
    if (obj_length < 1) {
	obj_length = 1;
    }

    /* just copy the bytes */
    bip->count = (long)num_items;
    bip->u.int8 = (char *)bu_malloc(obj_length, "binary uniform object");
    memcpy(bip->u.int8, bu_fd->buf, obj_length);

    bu_close_mapped_file(bu_fd);

    /* create the rt_internal form */
    RT_DB_INTERNAL_INIT(&intern);
    intern.idb_major_type = major_type;
    intern.idb_minor_type = minor_type;
    intern.idb_ptr = (genptr_t)bip;
    intern.idb_meth = &rt_functab[ID_BINUNIF];

    /* create body portion of external form */
    ret = -1;
    if (intern.idb_meth->ft_export5) {
	ret = intern.idb_meth->ft_export5(&body, &intern, 1.0, wdbp->dbip, wdbp->wdb_resp);
    }
    if (ret != 0) {
	bu_log("Error while attempting to export %s\n", obj_name);
	rt_db_free_internal(&intern);
	return -1;
    }

    /* create entire external form */
    db5_export_object3(&bin_ext, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
		       obj_name, 0, NULL, &body,
		       intern.idb_major_type, intern.idb_minor_type,
		       DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED);

    rt_db_free_internal(&intern);
    bu_free_external(&body);

    /* make sure the database directory is initialized */
    if (wdbp->dbip->dbi_eof == RT_DIR_PHONY_ADDR) {
	ret = db_dirbuild(wdbp->dbip);
	if (ret) {
	    return -1;
	}
    }

    /* add this (phony until written) object to the directory */
    if ((dp=db_diradd5(wdbp->dbip, obj_name, RT_DIR_PHONY_ADDR, major_type,
		       minor_type, 0, 0, NULL)) == RT_DIR_NULL) {
	bu_log("Error while attempting to add new name (%s) to the database",
	       obj_name);
	bu_free_external(&bin_ext);
	return -1;
    }

    /* and write it to the database */
    if (db_put_external5(&bin_ext, dp, wdbp->dbip)) {
	bu_log("Error while adding new binary object (%s) to the database",
	       obj_name);
	bu_free_external(&bin_ext);
	return -1;
    }

    bu_free_external(&bin_ext);

    return 0;
}
int
ged_bo(struct ged *gedp, int argc, const char *argv[])
{
    int c;
    unsigned int minor_type=0;
    char *obj_name;
    char *file_name;
    int input_mode=0;
    int output_mode=0;
    struct rt_binunif_internal *bip;
    struct rt_db_internal intern;
    struct directory *dp;
    const char *argv0;
    static const char *usage = "{-i major_type minor_type | -o} dest source";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    argv0 = argv[0];

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_HELP;
    }

    /* check that we are using a version 5 database */
    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	bu_vls_printf(gedp->ged_result_str, "This is an older database version.\nIt does not support binary objects.Use \"dbupgrade\" to upgrade this database to the current version.\n");
	return GED_ERROR;
    }

    bu_optind = 1;		/* re-init bu_getopt() */
    bu_opterr = 0;          /* suppress bu_getopt()'s error message */
    while ((c=bu_getopt(argc, (char * const *)argv, "iou:")) != -1) {
	switch (c) {
	    case 'i':
		input_mode = 1;
		break;
	    case 'o':
		output_mode = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c);
		return GED_ERROR;

	}
    }

    if (input_mode + output_mode != 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    argc -= bu_optind;
    argv += bu_optind;

    if ((input_mode && argc != 4) || (output_mode && argc != 2)) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }


    if (input_mode) {
	if (argv[0][0] == 'u') {

	    if (argv[1][1] != '\0') {
		bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		return GED_ERROR;
	    }

	    switch ((int)argv[1][0]) {
		case 'f':
		    minor_type = DB5_MINORTYPE_BINU_FLOAT;
		    break;
		case 'd':
		    minor_type = DB5_MINORTYPE_BINU_DOUBLE;
		    break;
		case 'c':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT;
		    break;
		case 's':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT;
		    break;
		case 'i':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT;
		    break;
		case 'l':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT;
		    break;
		case 'C':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT_U;
		    break;
		case 'S':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT_U;
		    break;
		case 'I':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT_U;
		    break;
		case 'L':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT_U;
		    break;
		default:
		    bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		    return GED_ERROR;
	    }
	} else {
	    bu_vls_printf(gedp->ged_result_str, "Unrecognized major type: %s", argv[0]);
	    return GED_ERROR;
	}

	/* skip past major_type and minor_type */
	argc -= 2;
	argv += 2;

	if (minor_type == 0) {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	    return GED_ERROR;
	}

	obj_name = (char *)*argv;
	GED_CHECK_EXISTS(gedp, obj_name, LOOKUP_QUIET, GED_ERROR);

	argc--;
	argv++;

	file_name = (char *)*argv;

	/* make a binunif of the entire file */
	if (rt_mk_binunif (gedp->ged_wdbp, obj_name, file_name, minor_type, 0)) {
	    bu_vls_printf(gedp->ged_result_str, "Error creating %s", obj_name);
	    return GED_ERROR;
	}

    } else if (output_mode) {
	FILE *fp;

	file_name = (char *)*argv;

	argc--;
	argv++;

	obj_name = (char *)*argv;

	if ((dp=db_lookup(gedp->ged_wdbp->dbip, obj_name, LOOKUP_NOISY)) == RT_DIR_NULL) {
	    return GED_ERROR;
	}
	if (!(dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK)) {
	    bu_vls_printf(gedp->ged_result_str, "%s is not a binary object", obj_name);
	    return GED_ERROR;
	}

	if (dp->d_major_type != DB5_MAJORTYPE_BINARY_UNIF) {
	    bu_vls_printf(gedp->ged_result_str, "source must be a uniform binary object");
	    return GED_ERROR;
	}

	fp = fopen(file_name, "w+b");
	if (fp == NULL) {
	    bu_vls_printf(gedp->ged_result_str, "Error: cannot open file %s for writing", file_name);
	    return GED_ERROR;
	}

	if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, NULL,
			       &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Error reading %s from database", dp->d_namep);
	    fclose(fp);
	    return GED_ERROR;
	}

	RT_CK_DB_INTERNAL(&intern);

	bip = (struct rt_binunif_internal *)intern.idb_ptr;
	if (bip->count < 1) {
	    bu_vls_printf(gedp->ged_result_str, "%s has no contents", obj_name);
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	if (fwrite(bip->u.int8, bip->count * db5_type_sizeof_h_binu(bip->type),
		   1, fp) != 1) {
	    bu_vls_printf(gedp->ged_result_str, "Error writing contents to file");
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	fclose(fp);
	rt_db_free_internal(&intern);

    } else {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    return GED_OK;
}
示例#3
0
int
rt_mk_binunif(struct rt_wdb *wdbp, const char *obj_name, const char *file_name, unsigned int minor_type, long max_count)
{
    struct stat st;
    unsigned int major_type=DB5_MAJORTYPE_BINARY_UNIF;
#if defined(_WIN32) && !defined(__CYGWIN__)
    __int64 num_items=-1;
    __int64 obj_length=-1;
#else
    long long num_items=-1;
    long long obj_length=-1;
#endif
    int item_length=0;
    struct bu_mapped_file *bu_fd;
    struct rt_binunif_internal *bip;
    struct rt_db_internal intern;
    struct bu_external body;
    struct bu_external bin_ext;
    struct directory *dp;

    if ( (item_length=db5_type_sizeof_h_binu( minor_type ) ) <= 0 ) {
	bu_log( "Unrecognized minor type!!!\n" );
	return -1;
    }

    if ( stat( file_name, &st ) ) {
	bu_log( "Cannot stat input file(%s)", file_name );
	return -1;
    }

    if ( (bu_fd=bu_open_mapped_file( file_name, NULL)) == NULL ) {
	bu_log( "Cannot open input file(%s) for reading",
		file_name );
	return -1;
    }

    /* create the rt_binunif internal form */
    BU_GETSTRUCT( bip, rt_binunif_internal );
    bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
    bip->type = minor_type;

    num_items = (long)(st.st_size / item_length);

    /* maybe only a partial file read */
    if (max_count > 0 && max_count < num_items) {
	num_items = max_count;
    }

    obj_length = num_items * item_length;

    if (obj_length > __LONG_MAX__) {
	bu_log("Unable to create binary objects larger than %ld bytes\n", __LONG_MAX__);
	return -1;
    }

    /* just copy the bytes */
    bip->count = num_items;
    bip->u.int8 = (char *)bu_malloc( obj_length, "binary uniform object" );
    memcpy(bip->u.int8, bu_fd->buf, obj_length);

    bu_close_mapped_file( bu_fd );

    /* create the rt_internal form */
    RT_INIT_DB_INTERNAL( &intern );
    intern.idb_major_type = major_type;
    intern.idb_minor_type = minor_type;
    intern.idb_ptr = (genptr_t)bip;
    intern.idb_meth = &rt_functab[ID_BINUNIF];

    /* create body portion of external form */
    if ( intern.idb_meth->ft_export5( &body, &intern, 1.0, wdbp->dbip, wdbp->wdb_resp, intern.idb_minor_type ) ) {

	bu_log( "Error while attemptimg to export %s\n", obj_name );
	rt_db_free_internal( &intern, wdbp->wdb_resp );
	return -1;
    }

    /* create entire external form */
    db5_export_object3( &bin_ext, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
			obj_name, 0, NULL, &body,
			intern.idb_major_type, intern.idb_minor_type,
			DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED );

    rt_db_free_internal( &intern, wdbp->wdb_resp );
    bu_free_external( &body );

    /* add this object to the directory */
    if ( (dp=db_diradd5( wdbp->dbip, obj_name, -1, major_type,
			 minor_type, 0, 0, NULL )) == DIR_NULL ) {
	bu_log( "Error while attemptimg to add new name (%s) to the database",
		obj_name );
	bu_free_external( &bin_ext );
	return -1;
    }

    /* and write it to the database */
    if ( db_put_external5( &bin_ext, dp, wdbp->dbip ) ) {
	bu_log( "Error while adding new binary object (%s) to the database",
		obj_name );
	bu_free_external( &bin_ext );
	return -1;
    }

    bu_free_external( &bin_ext );

    return 0;
}