int
rt_db_put_internal(
    struct directory *dp,
    struct db_i *dbip,
    struct rt_db_internal *ip,
    struct resource *resp)
{
    struct bu_external ext;
    int ret;

    RT_CK_DB_INTERNAL(ip);

    if (db_version(dbip) > 4)
	return rt_db_put_internal5(dp, dbip, ip, resp,
				   DB5_MAJORTYPE_BRLCAD);

    BU_EXTERNAL_INIT(&ext);

    /* Scale change on export is 1.0 -- no change */
    ret = -1;
    if (ip->idb_meth->ft_export4) {
	ret = ip->idb_meth->ft_export4(&ext, ip, 1.0, dbip, resp);
    }
    if (ret < 0) {
	bu_log("rt_db_put_internal(%s):  solid export failure\n",
	       dp->d_namep);
	rt_db_free_internal(ip);
	bu_free_external(&ext);
	return -2;		/* FAIL */
    }
    rt_db_free_internal(ip);

    if (db_put_external(&ext, dp, dbip) < 0) {
	bu_free_external(&ext);
	return -1;		/* FAIL */
    }

    bu_free_external(&ext);
    return 0;			/* OK */
}
Esempio n. 2
0
/*
 *		C M D _ I M P O R T _ B O D Y ( )
 *
 *	Read an object's body from disk file
 *
 */
int
cmd_import_body(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    register struct directory	*dp;
    struct stat			stat_buf;
    int				major_code, minor_code;
    int				majc, minc;
    char			*descrip;
    struct bu_vls		vls;
    struct rt_db_internal	intern;
    struct rt_binunif_internal	*bip;
    int				fd;
    int				gotten;

    CHECK_DBI_NULL;

    if (argc != 4) {
	struct bu_vls vls;

	bu_vls_init(&vls);
	bu_vls_printf(&vls, "help %s", argv[0]);
	Tcl_Eval(interp, bu_vls_addr(&vls));
	bu_vls_free(&vls);
	return TCL_ERROR;
    }

    switch (sscanf(argv[3], "%d %d", &major_code, &minor_code)) {
	case 1:
	    /* XXX is it safe to have no minor code? */
	    minor_code = 0;
	case 2:
	    break;
	case 0:
	    if ( db5_type_codes_from_descrip(&majc, &minc,
					     argv[3])
		 && db5_type_codes_from_tag(&majc, &minc,
					    argv[3])) {
		bu_vls_init( &vls );
		bu_vls_printf( &vls,
			       "Invalid data type: '%s'\n", argv[3] );
		Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
		bu_vls_free( &vls );
		mged_print_result( TCL_ERROR );
		return TCL_ERROR;
	    }
	    major_code = majc;
	    minor_code = minc;
	    break;
    }
    bu_vls_init( &vls );
    if (db5_type_descrip_from_codes( &descrip, major_code, minor_code )) {
	bu_vls_printf( &vls,
		       "Invalid maj/min: %d %d\n",
		       major_code, minor_code);
	Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	bu_vls_free( &vls );
	mged_print_result( TCL_ERROR );
	return TCL_ERROR;
    }
    if (RT_G_DEBUG & DEBUG_VOL)
	bu_log( "Type is %d %d '%s'\n", major_code, minor_code, descrip);

    /*
     *	Check to see if we need to create a new object
     */
    if ((dp = db_lookup( dbip, argv[1], LOOKUP_QUIET)) == DIR_NULL) {
	bu_vls_init( &vls );
	bu_vls_printf( &vls, "object \"%s\" does not exist.\n", argv[1] );
	Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	bu_vls_free( &vls );
	mged_print_result( TCL_ERROR );
	return TCL_ERROR;
    } else {
	RT_INIT_DB_INTERNAL( &intern );
    }

    /*
     *	How much data do we have to suck in?
     */
    if ( stat( argv[2], &stat_buf ) ) {
	bu_vls_init( &vls );
	bu_vls_printf( &vls, "Cannot get status of file %s\n", argv[2] );
	Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	bu_vls_free( &vls );
	mged_print_result( TCL_ERROR );
	return TCL_ERROR;
    }

    if (RT_G_DEBUG & DEBUG_VOL) {
	bu_log ("File '%s' is %ld bytes long\n", argv[2], (long)stat_buf.st_size);
    }

    if ( (fd = open( argv[2], O_RDONLY  )) == -1 ) {
	bu_vls_init( &vls );
	bu_vls_printf( &vls,
		       "Cannot open file %s for reading\n", argv[2] );
	Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	bu_vls_free( &vls );
	mged_print_result( TCL_ERROR );
	return TCL_ERROR;
    }

    if (db5_type_descrip_from_codes( &descrip, major_code, minor_code )) {
	bu_vls_printf( &vls,
		       "Invalid major_code/minor_code: %d\n", major_code);
	Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	bu_vls_free( &vls );
	mged_print_result( TCL_ERROR );
	return TCL_ERROR;
    }
    switch (major_code) {
	case DB5_MAJORTYPE_BINARY_UNIF:
	    bip = bu_malloc(sizeof(struct rt_binunif_internal),
			    "rt_binunif_internal");
	    bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
	    bip->type = minor_code;
	    bip->u.uint8 = (unsigned char *) bu_malloc((size_t)stat_buf.st_size, "binunif");
	    if (RT_G_DEBUG & DEBUG_VOL)
		bu_log("Created an rt_binunif_internal for type '%s' (minor=%d)\n", descrip, minor_code);

	    gotten = read( fd, (void *) (bip->u.uint8), (size_t)stat_buf.st_size);
	    if (gotten == -1) {
		perror( "import_body" );
		return TCL_ERROR;
	    } else if (gotten < stat_buf.st_size) {
		bu_vls_init( &vls );
		bu_vls_printf( &vls,
			       "Incomplete read of object %s from file %s, got %d bytes\n",
			       argv[1], argv[2], gotten );
		Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
		bu_vls_free( &vls );
		mged_print_result( TCL_ERROR );
		return TCL_ERROR;
	    }
	    if (RT_G_DEBUG & DEBUG_VOL)
		bu_log("gotten=%d,  minor_code is %d\n",
		       gotten, minor_code);
	    bip->count = gotten / db5_type_sizeof_n_binu( minor_code );
	    if (RT_G_DEBUG & DEBUG_VOL) {
		bu_log("Got 'em!\nThink I own %d of 'em\n", bip->count);
		fflush(stderr);
	    }
	    intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	    intern.idb_type = minor_code;
	    intern.idb_meth = &rt_functab[ID_BINUNIF];
	    intern.idb_ptr = (genptr_t)bip;
	    rt_binunif_dump(bip);
	    rt_db_put_internal5( dp, dbip, &intern, &rt_uniresource, DB5_MAJORTYPE_BINARY_UNIF );
	    rt_db_free_internal( &intern, &rt_uniresource );
	    break;
	default:
	    bu_vls_printf( &vls,
			   "Haven't gotten around to supporting type: %s\n",
			   descrip);
	    Tcl_SetResult(interp, bu_vls_addr( &vls ), TCL_VOLATILE );
	    bu_vls_free( &vls );
	    mged_print_result( TCL_ERROR );
	    return TCL_ERROR;
    }

    return TCL_OK;
}