db5_bin.c

Go to the documentation of this file.
00001 /*                       D B 5 _ B I N . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2000-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup db5 */
00023 
00024 /*@{*/
00025 /** @file db5_bin.c
00026  *      Handle bulk binary objects
00027  *
00028  *  Author -
00029  *      Paul J. Tanenbaum
00030  *
00031  *  Source -
00032  *      The U. S. Army Research Laboratory
00033  *      Aberdeen Proving Ground, Maryland  21005-5066
00034  *
00035  */
00036 /*@}*/
00037 
00038 #ifndef lint
00039 static const char RCSell[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db5_bin.c,v 14.13 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00040 #endif
00041 
00042 #include "common.h"
00043 
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <math.h>
00047 #include <string.h>
00048 #include <ctype.h>
00049 
00050 #include "machine.h"
00051 #include "bu.h"
00052 #include "vmath.h"
00053 #include "db5.h"
00054 #include "nmg.h"
00055 #include "rtgeom.h"
00056 #include "raytrace.h"
00057 #include "nurb.h"
00058 #include "./debug.h"
00059 
00060 
00061 /* this array depends on the values of the definitions of the DB5_MINORTYPE_BINU_... in db5.h */
00062 const char *binu_types[]={
00063         NULL,
00064         NULL,
00065         "binary(float)",
00066         "binary(double)",
00067         "binary(u_8bit_int)",
00068         "binary(u_16bit_int)",
00069         "binary(u_32bit_int)",
00070         "binary(u_64bit_int)",
00071         NULL,
00072         NULL,
00073         NULL,
00074         NULL,
00075         "binary(8bit_int)",
00076         "binary(16bit_int)",
00077         "binary(32bit_int)",
00078         "binary(64bit_int)"
00079 };
00080 
00081 /* size of each element (in bytes) for the different BINUNIF types */
00082 /* this array depends on the values of the definitions of the DB5_MINORTYPE_BINU_... in db5.h */
00083 const int binu_sizes[]={
00084         0,
00085         0,
00086         SIZEOF_NETWORK_FLOAT,
00087         SIZEOF_NETWORK_DOUBLE,
00088         1,
00089         2,
00090         4,
00091         8,
00092         0,
00093         0,
00094         0,
00095         0,
00096         1,
00097         2,
00098         4,
00099         8
00100 };
00101 /*
00102  * XXX these are the interface routines needed for table.c
00103  */
00104 int
00105 rt_bin_expm_export5(struct bu_external *ep,
00106                         const struct rt_db_internal *ip,
00107                         double local2mm,
00108                         const struct db_i *dbip,
00109                         struct resource *resp)
00110 {
00111         bu_log("rt_bin_expm_export5() not implemented\n");
00112         return -1;
00113 }
00114 
00115 int
00116 rt_bin_unif_export5(struct bu_external *ep,
00117                         const struct rt_db_internal *ip,
00118                         double local2mm,
00119                         const struct db_i *dbip,
00120                         struct resource *resp)
00121 {
00122         bu_log("rt_bin_unif_export5() not implemented\n");
00123         return -1;
00124 }
00125 int
00126 rt_bin_unif_import5(struct rt_db_internal * ip,
00127                         const struct bu_external *ep,
00128                         const mat_t mat,
00129                         const struct db_i *dbip,
00130                               struct resource *resp)
00131 {
00132         bu_log("rt_bin_unif_import5() not implemented\n");
00133         return -1;
00134 }
00135 int
00136 rt_bin_expm_import5(struct rt_db_internal * ip,
00137                         const struct bu_external *ep,
00138                         const mat_t mat,
00139                         const struct db_i *dbip,
00140                               struct resource *resp)
00141 {
00142         bu_log("rt_bin_expm_import5() not implemented\n");
00143         return -1;
00144 }
00145 
00146 int
00147 rt_bin_mime_import5(struct rt_db_internal * ip,
00148                         const struct bu_external *ep,
00149                         const mat_t mat,
00150                         const struct db_i *dbip,
00151                               struct resource *resp)
00152 {
00153         bu_log("rt_bin_mime_import5() not implemented\n");
00154         return -1;
00155 }
00156 
00157 /**
00158  *                      R T _ B I N U N I F _ I M P O R T 5
00159  *
00160  *  Import a uniform-array binary object from the database format to
00161  *  the internal structure.
00162  */
00163 int
00164 rt_binunif_import5( struct rt_db_internal       *ip,
00165                     const struct bu_external    *ep,
00166                     const mat_t                 mat,
00167                     const struct db_i           *dbip,
00168                     struct resource             *resp,
00169                     const int                   minor_type)
00170 {
00171         struct rt_binunif_internal      *bip;
00172         int                             i;
00173         unsigned char                   *srcp;
00174         unsigned long                   *ldestp;
00175         int                             in_cookie, out_cookie;
00176         int                             gotten;
00177 
00178         BU_CK_EXTERNAL( ep );
00179 
00180         /*
00181          *      There's no particular size to expect
00182          *
00183          * BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 3*4 );
00184          */
00185 
00186         RT_CK_DB_INTERNAL( ip );
00187         ip->idb_major_type = DB5_MAJORTYPE_BINARY_UNIF;
00188         ip->idb_minor_type = minor_type;
00189         ip->idb_meth = &rt_functab[ID_BINUNIF];
00190         ip->idb_ptr = bu_malloc( sizeof(struct rt_binunif_internal),
00191             "rt_binunif_internal");
00192 
00193         bip = (struct rt_binunif_internal *)ip->idb_ptr;
00194         bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
00195         bip->type = minor_type;
00196 
00197         /*
00198          * Convert from database (network) to internal (host) format
00199          */
00200         switch (bip->type) {
00201             case DB5_MINORTYPE_BINU_FLOAT:
00202                 bip->count = ep->ext_nbytes/SIZEOF_NETWORK_FLOAT;
00203                 bip->u.uint8 = (unsigned char *) bu_malloc( bip->count * sizeof(float),
00204                     "rt_binunif_internal" );
00205                 ntohf( (unsigned char *) bip->u.uint8,
00206                         ep->ext_buf, bip->count );
00207                 break;
00208             case DB5_MINORTYPE_BINU_DOUBLE:
00209                 bip->count = ep->ext_nbytes/SIZEOF_NETWORK_DOUBLE;
00210                 bip->u.uint8 = (unsigned char *) bu_malloc( bip->count * sizeof(double),
00211                     "rt_binunif_internal" );
00212                 ntohd( (unsigned char *) bip->u.uint8,
00213                         ep->ext_buf, bip->count );
00214                 break;
00215             case DB5_MINORTYPE_BINU_8BITINT:
00216             case DB5_MINORTYPE_BINU_8BITINT_U:
00217                 bip->count = ep->ext_nbytes;
00218                 bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
00219                     "rt_binunif_internal" );
00220                 bcopy( (char *) ep->ext_buf, (char *) bip->u.uint8, ep->ext_nbytes );
00221                 break;
00222             case DB5_MINORTYPE_BINU_16BITINT:
00223             case DB5_MINORTYPE_BINU_16BITINT_U:
00224                 bip->count = ep->ext_nbytes/2;
00225                 bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
00226                     "rt_binunif_internal" );
00227 #if 0
00228                 srcp = (unsigned char *) ep->ext_buf;
00229                 sdestp = (unsigned short *) bip->u.uint8;
00230                 for (i = 0; i < bip->count; ++i, ++sdestp, srcp += 2) {
00231                     *sdestp = bu_gshort( srcp );
00232                     bu_log("Just got %d", *sdestp);
00233                 }
00234 #endif
00235                 in_cookie = bu_cv_cookie("nus");
00236                 out_cookie = bu_cv_cookie("hus");
00237                 if (bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie)) {
00238                     gotten =
00239                     bu_cv_w_cookie((genptr_t)bip->u.uint8, out_cookie,
00240                                    ep->ext_nbytes,
00241                                    ep->ext_buf, in_cookie, bip->count);
00242                     if (gotten != bip->count) {
00243                         bu_log("%s:%d: Tried to convert %d, did %d",
00244                             __FILE__, __LINE__, bip->count, gotten);
00245                         bu_bomb("\n");
00246                     }
00247                 } else
00248                     bcopy( (char *) ep->ext_buf, (char *) bip->u.uint8,
00249                         ep->ext_nbytes );
00250                 break;
00251             case DB5_MINORTYPE_BINU_32BITINT:
00252             case DB5_MINORTYPE_BINU_32BITINT_U:
00253                 bip->count = ep->ext_nbytes/4;
00254                 bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
00255                     "rt_binunif_internal" );
00256                 srcp = (unsigned char *) ep->ext_buf;
00257                 ldestp = (unsigned long *) bip->u.uint8;
00258                 for (i = 0; i < bip->count; ++i, ++ldestp, srcp += 4) {
00259                     *ldestp = bu_glong( srcp );
00260                     bu_log("Just got %ld", *ldestp);
00261                 }
00262                 break;
00263             case DB5_MINORTYPE_BINU_64BITINT:
00264             case DB5_MINORTYPE_BINU_64BITINT_U:
00265                 bu_log("rt_binunif_import5() Can't handle 64-bit integers yet\n");
00266                 return -1;
00267         }
00268 
00269         return 0;               /* OK */
00270 }
00271 
00272 /**
00273  *                      R T _ B I N U N I F _ D U M P
00274  *
00275  *  Diagnostic routine
00276  */
00277 void
00278 rt_binunif_dump( struct rt_binunif_internal *bip) {
00279     RT_CK_BINUNIF(bip);
00280     bu_log("rt_bin_unif_internal <%x>...\n", bip);
00281     bu_log("  type = x%x = %d", bip -> type, bip -> type);
00282     bu_log("  count = %ld  first = 0x%02x", bip -> count,
00283            bip->u.uint8[0] & 0x0ff);
00284     bu_log("- - - - -\n");
00285 }
00286 
00287 
00288 /**
00289  *                      R T _ B I N E X P M _ I M P O R T 5
00290  *
00291  *  Import an experimental binary object from the database format to
00292  *  the internal structure.
00293  */
00294 int
00295 rt_binexpm_import5( struct rt_db_internal       *ip,
00296                     const unsigned char         minor_type,
00297                     const struct bu_external    *ep,
00298                     const struct db_i           *dbip )
00299 {
00300         bu_log("rt_binexpm_import5() not implemented yet\n");
00301         return -1;
00302 }
00303 
00304 
00305 /**
00306  *                      R T _ B I N M I M E _ I M P O R T 5
00307  *
00308  *  Import a MIME-typed binary object from the database format to
00309  *  the internal structure.
00310  */
00311 int
00312 rt_binmime_import5( struct rt_db_internal       *ip,
00313                     const unsigned char         minor_type,
00314                     const struct bu_external    *ep,
00315                     const struct db_i           *dbip )
00316 {
00317         bu_log("rt_binmime_import5() not implemented yet\n");
00318         return -1;
00319 }
00320 
00321 
00322 /**
00323  *                      R T _ B I N _ I M P O R T 5
00324  *
00325  *  Wrapper for importing binary objects from the database format to
00326  *  the internal structure.
00327  */
00328 int
00329 rt_bin_import5( struct rt_db_internal           *ip,
00330                 const unsigned char             major_type,
00331                 const unsigned char             minor_type,
00332                 const struct bu_external        *ep,
00333                 const struct db_i               *dbip )
00334 {
00335     RT_CK_DB_INTERNAL(ip);
00336 
00337     switch (major_type) {
00338         case DB5_MAJORTYPE_BINARY_EXPM:
00339             return rt_binexpm_import5( ip, minor_type, ep, dbip );
00340         case DB5_MAJORTYPE_BINARY_UNIF:
00341             return rt_binunif_import5( ip, ep, 0, dbip, 0, minor_type );
00342         case DB5_MAJORTYPE_BINARY_MIME:
00343             return rt_binmime_import5( ip, minor_type, ep, dbip );
00344     }
00345     return -1;
00346 }
00347 
00348 /**
00349  *                      R T _ B I N U N I F _ E X P O R T 5
00350  *
00351  *      Create the "body" portion of external form
00352  */
00353 int
00354 rt_binunif_export5( struct bu_external          *ep,
00355                     const struct rt_db_internal *ip,
00356                     double                      local2mm,       /* we ignore */
00357                     const struct db_i           *dbip,
00358                     struct resource             *resp,
00359                     const int                   minor_type )
00360 {
00361         struct rt_binunif_internal      *bip;
00362         int                             i;
00363         unsigned char                   *destp;
00364         unsigned long                   *lsrcp;
00365         int                             in_cookie, out_cookie;
00366         int                             gotten;
00367 
00368         RT_CK_DB_INTERNAL(ip);
00369         if( ip->idb_minor_type != minor_type ) {
00370                 bu_log("ip->idb_minor_type(%d) != minor_type(%d)\n",
00371                        ip->idb_minor_type, minor_type );
00372                 return -1;
00373         }
00374         bip = (struct rt_binunif_internal *)ip->idb_ptr;
00375         RT_CK_BINUNIF(bip);
00376         if( bip->type != minor_type ) {
00377                 bu_log("bip->type(%d) != minor_type(%d)\n",
00378                        bip->type, minor_type );
00379                 return -1;
00380         }
00381 
00382         BU_INIT_EXTERNAL(ep);
00383 
00384         /*
00385          * Convert from internal (host) to database (network) format
00386          */
00387         switch (bip->type) {
00388             case DB5_MINORTYPE_BINU_FLOAT:
00389                 ep->ext_nbytes = bip->count * SIZEOF_NETWORK_FLOAT;
00390                 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes,
00391                     "binunif external");
00392                 htonf( ep->ext_buf, (unsigned char *) bip->u.uint8, bip->count );
00393                 break;
00394             case DB5_MINORTYPE_BINU_DOUBLE:
00395                 ep->ext_nbytes = bip->count * SIZEOF_NETWORK_DOUBLE;
00396                 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes,
00397                     "binunif external");
00398                 htond( ep->ext_buf, (unsigned char *) bip->u.uint8, bip->count );
00399                 break;
00400             case DB5_MINORTYPE_BINU_8BITINT:
00401             case DB5_MINORTYPE_BINU_8BITINT_U:
00402                 ep->ext_nbytes = bip->count;
00403                 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes,
00404                     "binunif external");
00405                 bcopy( (char *) bip->u.uint8, (char *) ep->ext_buf, bip->count );
00406                 break;
00407             case DB5_MINORTYPE_BINU_16BITINT:
00408             case DB5_MINORTYPE_BINU_16BITINT_U:
00409                 ep->ext_nbytes = bip->count * 2;
00410                 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "binunif external");
00411                 in_cookie = bu_cv_cookie("hus");
00412                 out_cookie = bu_cv_cookie("nus");
00413                 if (bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie)) {
00414                     gotten =
00415                             bu_cv_w_cookie(ep->ext_buf, out_cookie,
00416                                            ep->ext_nbytes,
00417                                            (genptr_t) bip->u.uint8, in_cookie,
00418                                            bip->count);
00419 
00420                     if (gotten != bip->count) {
00421                         bu_log("%s:%d: Tried to convert %d, did %d",
00422                             __FILE__, __LINE__, bip->count, gotten);
00423                         bu_bomb("\n");
00424                     }
00425                 } else {
00426                     bcopy( (char *) bip->u.uint8, (char *) ep->ext_buf,
00427                         ep->ext_nbytes );
00428                 }
00429                 break;
00430             case DB5_MINORTYPE_BINU_32BITINT:
00431             case DB5_MINORTYPE_BINU_32BITINT_U:
00432                 ep->ext_nbytes = bip->count * 4;
00433                 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "binunif external");
00434 
00435                 lsrcp = (unsigned long *) bip->u.uint8;
00436                 destp = (unsigned char *) ep->ext_buf;
00437                 for (i = 0; i < bip->count; ++i, ++destp, ++lsrcp) {
00438                     (void) bu_plong( destp, *lsrcp );
00439                 }
00440                 break;
00441             case DB5_MINORTYPE_BINU_64BITINT:
00442             case DB5_MINORTYPE_BINU_64BITINT_U:
00443                 bu_log("rt_binunif_export5() Can't handle 64-bit integers yet\n");
00444                 return -1;
00445         }
00446 
00447         return 0;
00448 }
00449 
00450 /**
00451  *                      R T _ B I N U N I F _ D E S C R I B E
00452  *
00453  *  Make human-readable formatted presentation of this object.
00454  *  First line describes type of object.
00455  *  Additional lines are indented one tab, and give parameter values.
00456  */
00457 int
00458 rt_binunif_describe( struct bu_vls              *str,
00459                     const struct rt_db_internal *ip,
00460                     int                         verbose,
00461                     double                      mm2local )
00462 {
00463         register struct rt_binunif_internal     *bip;
00464         char                                    buf[256];
00465         unsigned short                          wid;
00466 
00467         bip = (struct rt_binunif_internal *) ip->idb_ptr;
00468         RT_CK_BINUNIF(bip);
00469         bu_vls_strcat( str, "uniform-array binary object (BINUNIF)\n");
00470         wid = (bip->type & DB5_MINORTYPE_BINU_WID_MASK) >> 4;
00471         switch (wid) {
00472             case 0:
00473                 sprintf( buf, "%ld ", bip->count ); break;
00474             case 1:
00475                 sprintf( buf, "%ld pairs of ", bip->count / 2 ); break;
00476             case 2:
00477                 sprintf( buf, "%ld triples of ", bip->count / 3 ); break;
00478             case 3:
00479                 sprintf( buf, "%ld quadruples of ", bip->count / 4 ); break;
00480         }
00481         bu_vls_strcat( str, buf );
00482         switch (bip->type & DB5_MINORTYPE_BINU_ATM_MASK) {
00483             case DB5_MINORTYPE_BINU_FLOAT:
00484                 bu_vls_strcat( str, "floats\n"); break;
00485             case DB5_MINORTYPE_BINU_DOUBLE:
00486                 bu_vls_strcat( str, "doubles\n"); break;
00487             case DB5_MINORTYPE_BINU_8BITINT:
00488                 bu_vls_strcat( str, "8-bit ints\n"); break;
00489             case DB5_MINORTYPE_BINU_16BITINT:
00490                 bu_vls_strcat( str, "16-bit ints\n"); break;
00491             case DB5_MINORTYPE_BINU_32BITINT:
00492                 bu_vls_strcat( str, "32-bit ints\n"); break;
00493             case DB5_MINORTYPE_BINU_64BITINT:
00494                 bu_vls_strcat( str, "64-bit ints\n"); break;
00495             case DB5_MINORTYPE_BINU_8BITINT_U:
00496                 bu_vls_strcat( str, "unsigned 8-bit ints\n"); break;
00497             case DB5_MINORTYPE_BINU_16BITINT_U:
00498                 bu_vls_strcat( str, "unsigned 16-bit ints\n"); break;
00499             case DB5_MINORTYPE_BINU_32BITINT_U:
00500                 bu_vls_strcat( str, "unsigned 32-bit ints\n"); break;
00501             case DB5_MINORTYPE_BINU_64BITINT_U:
00502                 bu_vls_strcat( str, "unsigned 64-bit ints\n"); break;
00503             default:
00504                 bu_log("%s:%d: This shouldn't happen", __FILE__, __LINE__);
00505                 return(1);
00506         }
00507 
00508         return(0);
00509 }
00510 
00511 /**
00512  *              R T _ B I N U N I F _ F R E E
00513  *
00514  *      Free the storage associated with a binunif_internal object
00515  */
00516 void
00517 rt_binunif_free( struct rt_binunif_internal *bip) {
00518         RT_CK_BINUNIF(bip);
00519         bu_free( (genptr_t) bip->u.uint8, "binunif free uint8" );
00520         bu_free( bip, "binunif free");
00521         bip = GENPTR_NULL; /* sanity */
00522 }
00523 
00524 /**
00525  *                      R T _ B I N U N I F _ I F R E E
00526  *
00527  *  Free the storage associated with the rt_db_internal version of this thing.
00528  */
00529 void
00530 rt_binunif_ifree( struct rt_db_internal *ip )
00531 {
00532         struct rt_binunif_internal      *bip;
00533 
00534         RT_CK_DB_INTERNAL(ip);
00535         bip = (struct rt_binunif_internal *)ip->idb_ptr;
00536         RT_CK_BINUNIF(bip);
00537         bu_free( (genptr_t) bip->u.uint8, "binunif ifree" );
00538         bu_free( ip->idb_ptr, "binunif ifree" );
00539         ip->idb_ptr = GENPTR_NULL;
00540 }
00541 
00542 
00543 int
00544 rt_retrieve_binunif(struct rt_db_internal *intern,
00545                     struct db_i *dbip,
00546                     char *name)
00547 {
00548         register struct directory       *dp;
00549         struct rt_binunif_internal      *bip;
00550         struct bu_external              ext;
00551         struct db5_raw_internal         raw;
00552         char                            *tmp;
00553 
00554         /*
00555          *      Find the guy we're told to write
00556          */
00557         if( (dp = db_lookup( dbip, name, LOOKUP_NOISY)) == DIR_NULL )
00558                 return -1;
00559 
00560         RT_INIT_DB_INTERNAL(intern);
00561         if ( rt_db_get_internal5( intern, dp, dbip, NULL, &rt_uniresource)
00562              != ID_BINUNIF     || db_get_external( &ext, dp, dbip ) < 0 )
00563                 return -1;
00564 
00565         if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
00566             bu_log("%s:%d\n", __FILE__, __LINE__);
00567                 bu_free_external( &ext );
00568                 return -1;
00569         }
00570         if (db5_type_descrip_from_codes(&tmp, raw.major_type, raw.minor_type))
00571                 tmp = 0;
00572 
00573         if (RT_G_DEBUG & DEBUG_VOL)
00574                 bu_log("get_body() sees type (%d, %d)='%s'\n",
00575                        raw.major_type, raw.minor_type, tmp);
00576 
00577         if (raw.major_type != DB5_MAJORTYPE_BINARY_UNIF)
00578                 return -1;
00579 
00580         bip = intern->idb_ptr;
00581         RT_CK_BINUNIF(bip);
00582         if (RT_G_DEBUG & DEBUG_HF)
00583                 rt_binunif_dump(bip);
00584 
00585         if (RT_G_DEBUG & DEBUG_VOL)
00586                 bu_log("cmd_export_body() thinks bip->count=%d\n",
00587                        bip->count);
00588 
00589         switch (bip -> type) {
00590         case DB5_MINORTYPE_BINU_FLOAT:
00591                 if (RT_G_DEBUG & DEBUG_VOL)
00592                         bu_log("bip->type switch... float");
00593                 break;
00594         case DB5_MINORTYPE_BINU_DOUBLE:
00595                 if (RT_G_DEBUG & DEBUG_VOL)
00596                         bu_log("bip->type switch... double");
00597                 break;
00598         case DB5_MINORTYPE_BINU_8BITINT:
00599                 if (RT_G_DEBUG & DEBUG_VOL)
00600                         bu_log("bip->type switch... 8bitint");
00601                 break;
00602         case DB5_MINORTYPE_BINU_8BITINT_U:
00603                 if (RT_G_DEBUG & DEBUG_VOL)
00604                         bu_log("bip->type switch... 8bituint");
00605                 break;
00606         case DB5_MINORTYPE_BINU_16BITINT:
00607                 if (RT_G_DEBUG & DEBUG_VOL)
00608                         bu_log("bip->type switch... 16bituint");
00609                 break;
00610         case DB5_MINORTYPE_BINU_16BITINT_U:
00611                 if (RT_G_DEBUG & DEBUG_VOL)
00612                         bu_log("bip->type switch... 16bitint");
00613                 break;
00614         case DB5_MINORTYPE_BINU_32BITINT:
00615         case DB5_MINORTYPE_BINU_32BITINT_U:
00616                 if (RT_G_DEBUG & DEBUG_VOL)
00617                         bu_log("bip->type switch... 32bitint");
00618                 break;
00619         case DB5_MINORTYPE_BINU_64BITINT:
00620         case DB5_MINORTYPE_BINU_64BITINT_U:
00621                 if (RT_G_DEBUG & DEBUG_VOL)
00622                         bu_log("bip->type switch... 64bitint");
00623                 break;
00624         default:
00625                 /* XXX  This shouln't happen!!    */
00626                 bu_log("bip->type switch... default");
00627                 break;
00628         }
00629 
00630         bu_free_external( &ext );
00631 
00632         return 0;
00633 }
00634 
00635 void
00636 rt_binunif_make(const struct rt_functab *ftp, struct rt_db_internal *intern, double diameter)
00637 {
00638         struct rt_binunif_internal *bip;
00639 
00640         intern->idb_type = DB5_MINORTYPE_BINU_8BITINT;
00641         intern->idb_major_type = DB5_MAJORTYPE_BINARY_UNIF;
00642         BU_ASSERT(&rt_functab[ID_BINUNIF] == ftp);
00643 
00644         intern->idb_meth = ftp;
00645         bip = (struct rt_binunif_internal *)bu_calloc( sizeof( struct rt_binunif_internal), 1,
00646                                                        "rt_binunif_make");
00647         intern->idb_ptr = (genptr_t) bip;
00648         bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
00649         bip->type = DB5_MINORTYPE_BINU_8BITINT;
00650         bip->count = 0;
00651         bip->u.int8 = NULL;
00652 }
00653 
00654 int
00655 rt_binunif_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *attr )
00656 {
00657         register struct rt_binunif_internal *bip=(struct rt_binunif_internal *)intern->idb_ptr;
00658         struct bu_external      ext;
00659         Tcl_DString             ds;
00660         struct bu_vls           vls;
00661         int                     status=TCL_OK;
00662         int                     i;
00663         unsigned char           *c;
00664 
00665         RT_CHECK_BINUNIF( bip );
00666 
00667         Tcl_DStringInit( &ds );
00668         bu_vls_init( &vls );
00669 
00670         if( attr == (char *)NULL )
00671         {
00672                 /* export the object to get machine independent form */
00673                 if( rt_binunif_export5( &ext, intern, 1.0, NULL, NULL, intern->idb_minor_type ) ) {
00674                         bu_vls_strcpy( &vls, "Failed to export binary object!!\n" );
00675                         status = TCL_ERROR;
00676                 } else {
00677                         bu_vls_strcpy( &vls, "binunif" );
00678                         bu_vls_printf( &vls, " T %d D {", bip->type );
00679                         c = ext.ext_buf;
00680                         for( i=0 ; i<ext.ext_nbytes ; i++,c++ ) {
00681                                 if( i%40 == 0 ) bu_vls_strcat( &vls, "\n" );
00682                                 bu_vls_printf( &vls, "%2.2x", *c );
00683                         }
00684                         bu_vls_strcat( &vls, "}" );
00685                         bu_free_external( &ext );
00686                 }
00687 
00688         } else {
00689                 if( !strcmp( attr, "T" ) ) {
00690                         bu_vls_printf( &vls, "%d", bip->type );
00691                 } else if( !strcmp( attr, "D" ) ) {
00692                         /* export the object to get machine independent form */
00693                         if( rt_binunif_export5( &ext, intern, 1.0, NULL, NULL,
00694                                                 intern->idb_minor_type ) ) {
00695                                 bu_vls_strcpy( &vls, "Failed to export binary object!!\n" );
00696                                 status = TCL_ERROR;
00697                         } else {
00698                                 c = ext.ext_buf;
00699                                 for( i=0 ; i<ext.ext_nbytes ; i++,c++ ) {
00700                                         if( i != 0 && i%40 == 0 ) bu_vls_strcat( &vls, "\n" );
00701                                         bu_vls_printf( &vls, "%2.2x", *c );
00702                                 }
00703                                 bu_free_external( &ext );
00704                         }
00705                 } else {
00706                         bu_vls_printf( &vls, "Binary object has no attribute '%s'", attr );
00707                         status = TCL_ERROR;
00708                 }
00709         }
00710 
00711         Tcl_DStringAppend( &ds, bu_vls_addr( &vls ), -1 );
00712         Tcl_DStringResult( interp, &ds );
00713         Tcl_DStringFree( &ds );
00714         bu_vls_free( &vls );
00715 
00716         return( status );
00717 }
00718 
00719 int
00720 rt_binunif_tcladjust( Tcl_Interp *interp, struct rt_db_internal *intern, int argc, char **argv )
00721 {
00722         struct rt_binunif_internal *bip;
00723         int i;
00724 
00725         RT_CK_DB_INTERNAL( intern );
00726         bip = (struct rt_binunif_internal *)intern->idb_ptr;
00727         RT_CHECK_BINUNIF( bip );
00728 
00729         while( argc >= 2 ) {
00730                 if( !strcmp( argv[0], "T" ) ) {
00731                         int new_type=-1;
00732                         char *c;
00733                         int type_is_digit=1;
00734 
00735                         c = argv[1];
00736                         while( *c != '\0' ) {
00737                                 if( !isdigit( *c ) ) {
00738                                         type_is_digit = 0;
00739                                         break;
00740                                 }
00741                                 c++;
00742                         }
00743 
00744                         if( type_is_digit ) {
00745                                 new_type = atoi( argv[1] );
00746                         } else {
00747                                 if( argv[1][1] != '\0' ) {
00748                                         Tcl_AppendResult( interp, "Illegal type: ",
00749                                            argv[1],
00750                                            ", must be 'f', 'd', 'c', 'i', 'l', 'C', 'S', 'I', or 'L'",
00751                                            (char *)NULL );
00752                                         return TCL_ERROR;
00753                                 }
00754                                 switch( argv[1][0] ) {
00755                                         case 'f':
00756                                                 new_type = 2;
00757                                                 break;
00758                                         case 'd':
00759                                                 new_type = 3;
00760                                                 break;
00761                                         case 'c':
00762                                                 new_type = 4;
00763                                                 break;
00764                                         case 's':
00765                                                 new_type = 5;
00766                                                 break;
00767                                         case 'i':
00768                                                 new_type = 6;
00769                                                 break;
00770                                         case 'l':
00771                                                 new_type = 7;
00772                                                 break;
00773                                         case 'C':
00774                                                 new_type = 12;
00775                                                 break;
00776                                         case 'S':
00777                                                 new_type = 13;
00778                                                 break;
00779                                         case 'I':
00780                                                 new_type = 14;
00781                                                 break;
00782                                         case 'L':
00783                                                 new_type = 15;
00784                                                 break;
00785                                 }
00786                         }
00787                         if( new_type < 0 ||
00788                             new_type > DB5_MINORTYPE_BINU_64BITINT ||
00789                             binu_types[new_type] == NULL ) {
00790                                 /* Illegal value for type */
00791                                 Tcl_AppendResult( interp, "Illegal value for binary type: ", argv[1],
00792                                                   (char *)NULL );
00793                                 return TCL_ERROR;
00794                         } else {
00795                                 if( bip->u.uint8 ) {
00796                                         int new_count;
00797                                         int old_byte_count, new_byte_count;
00798                                         int remainder;
00799 
00800                                         old_byte_count = bip->count * binu_sizes[bip->type];
00801                                         new_count = old_byte_count / binu_sizes[new_type];
00802                                         remainder = old_byte_count % binu_sizes[new_type];
00803                                         if( remainder ) {
00804                                                 new_count++;
00805                                                 new_byte_count = new_count * binu_sizes[new_type];
00806                                         } else {
00807                                                 new_byte_count = old_byte_count;
00808                                         }
00809 
00810                                         if( new_byte_count != old_byte_count ) {
00811                                                 bip->u.uint8 = bu_realloc( bip->u.uint8,
00812                                                                            new_byte_count,
00813                                                                            "new bytes for binunif" );
00814                                                 /* zero out the new bytes */
00815                                                 for( i=old_byte_count ; i<new_byte_count ; i++ ) {
00816                                                         bip->u.uint8[i] = 0;
00817                                                 }
00818                                         }
00819                                         bip->count = new_count;
00820                                 }
00821                                 bip->type = new_type;
00822                                 intern->idb_type = new_type;
00823                         }
00824                 } else if( !strcmp( argv[0], "D" ) ) {
00825                         Tcl_Obj *obj, *list, **obj_array;
00826                         int list_len;
00827                         unsigned char *buf, *d;
00828                         char *s;
00829                         int hexlen;
00830                         unsigned int h;
00831 
00832                         obj = Tcl_NewStringObj( argv[1], -1 );
00833                         list = Tcl_NewListObj( 0, NULL );
00834                         Tcl_ListObjAppendList( interp, list, obj );
00835                         (void)Tcl_ListObjGetElements( interp, list, &list_len, &obj_array );
00836 
00837                         hexlen = 0;
00838                         for( i=0 ; i<list_len ; i++ ) {
00839                                 hexlen += Tcl_GetCharLength( obj_array[i] );
00840                         }
00841 
00842                         if( hexlen % 2 ) {
00843                                 Tcl_AppendResult( interp,
00844                                     "Hex form of binary data must have an even number of hex digits",
00845                                     (char *)NULL );
00846                                 return TCL_ERROR;
00847                         }
00848 
00849                         buf = (unsigned char *)bu_malloc( hexlen / 2, "tcladjust binary data" );
00850                         d = buf;
00851                         for( i=0 ; i<list_len ; i++ ) {
00852                                 s = Tcl_GetString( obj_array[i] );
00853                                 while( *s ) {
00854                                         sscanf( s, "%2x", &h );
00855                                         *d++ = h;
00856                                         s += 2;
00857                                 }
00858                         }
00859                         Tcl_DecrRefCount( list );
00860 
00861                         if( bip->u.uint8 ) {
00862                                 bu_free( bip->u.uint8, "binary data" );
00863                         }
00864                         bip->u.uint8 = buf;
00865                         bip->count = hexlen / 2 / binu_sizes[bip->type];
00866                 }
00867 
00868                 argc -= 2;
00869                 argv += 2;
00870         }
00871 
00872         return TCL_OK;
00873 }
00874 
00875 /*
00876  * Local Variables:
00877  * mode: C
00878  * tab-width: 8
00879  * c-basic-offset: 4
00880  * indent-tabs-mode: t
00881  * End:
00882  * ex: shiftwidth=4 tabstop=8
00883  */

Generated on Mon Sep 18 01:24:48 2006 for BRL-CAD by  doxygen 1.4.6