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; }
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; }