00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db5_io.c,v 14.17 2006/09/16 02:04:24 lbutler Exp $ (ARL)";
00039 #endif
00040
00041 #include "common.h"
00042
00043 #include <stdio.h>
00044 #ifdef HAVE_STRING_H
00045 # include <string.h>
00046 #else
00047 # include <strings.h>
00048 #endif
00049
00050 #include "machine.h"
00051 #include "bu.h"
00052 #include "vmath.h"
00053 #include "bn.h"
00054 #include "db5.h"
00055 #include "raytrace.h"
00056
00057 #include "mater.h"
00058
00059 #include "./debug.h"
00060
00061
00062 const int db5_enc_len[4] = {
00063 1,
00064 2,
00065 4,
00066 8
00067 };
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 int
00079 db5_header_is_valid(const unsigned char *hp)
00080 {
00081 const struct db5_ondisk_header *odp = (const struct db5_ondisk_header *)hp;
00082
00083 if( odp->db5h_magic1 != DB5HDR_MAGIC1 ) return 0;
00084 if( hp[7] != DB5HDR_MAGIC2 ) return 0;
00085
00086
00087 if( (odp->db5h_hflags & DB5HDR_HFLAGS_DLI_MASK) != DB5HDR_HFLAGS_DLI_HEADER_OBJECT )
00088 return 0;
00089 if( (odp->db5h_hflags & DB5HDR_HFLAGS_NAME_PRESENT) ) return 0;
00090 if( ((odp->db5h_hflags & DB5HDR_HFLAGS_OBJECT_WIDTH_MASK) >> DB5HDR_HFLAGS_OBJECT_WIDTH_SHIFT)
00091 != DB5HDR_WIDTHCODE_8BIT ) return 0;
00092
00093
00094 if( (odp->db5h_aflags & DB5HDR_AFLAGS_ZZZ_MASK) != DB5_ZZZ_UNCOMPRESSED ) return 0;
00095 if( odp->db5h_aflags & DB5HDR_AFLAGS_PRESENT ) return 0;
00096 if( ((odp->db5h_aflags & DB5HDR_AFLAGS_WIDTH_MASK) >> DB5HDR_AFLAGS_WIDTH_SHIFT)
00097 != DB5HDR_WIDTHCODE_8BIT ) return 0;
00098
00099
00100 if( (odp->db5h_bflags & DB5HDR_BFLAGS_ZZZ_MASK) != DB5_ZZZ_UNCOMPRESSED ) return 0;
00101 if( odp->db5h_bflags & DB5HDR_BFLAGS_PRESENT ) return 0;
00102 if( ((odp->db5h_bflags & DB5HDR_BFLAGS_WIDTH_MASK) >> DB5HDR_BFLAGS_WIDTH_SHIFT)
00103 != DB5HDR_WIDTHCODE_8BIT ) return 0;
00104
00105
00106 if( odp->db5h_major_type != DB5_MAJORTYPE_RESERVED ) return 0;
00107 if( odp->db5h_minor_type != 0 ) return 0;
00108
00109
00110 if( hp[6] != 1 ) return 0;
00111
00112 return 1;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 int
00122 db5_select_length_encoding(long int len)
00123 {
00124 if( len <= 255 ) return DB5HDR_WIDTHCODE_8BIT;
00125 if( len <= 65535 ) return DB5HDR_WIDTHCODE_16BIT;
00126 if( len < 0x7ffffffe ) return DB5HDR_WIDTHCODE_32BIT;
00127 return DB5HDR_WIDTHCODE_64BIT;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 int
00142 db5_decode_length(long int *lenp, const unsigned char *cp, int format)
00143 {
00144 switch( format ) {
00145 case DB5HDR_WIDTHCODE_8BIT:
00146 *lenp = (*cp);
00147 return 1;
00148 case DB5HDR_WIDTHCODE_16BIT:
00149 *lenp = BU_GSHORT(cp);
00150 return 2;
00151 case DB5HDR_WIDTHCODE_32BIT:
00152 *lenp = BU_GLONG(cp);
00153 return 4;
00154 case DB5HDR_WIDTHCODE_64BIT:
00155 #if defined(IRIX64)
00156 if( sizeof(long) >= 8 ) {
00157 *lenp = BU_GLONGLONG(cp);
00158 return 8;
00159 }
00160 #endif
00161 bu_bomb("db5_decode_length(): encountered 64-bit length on 32-bit machine\n");
00162 }
00163 bu_bomb("db5_decode_length(): unknown width code\n");
00164 return 0;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 int
00179 db5_decode_signed(long int *lenp, const unsigned char *cp, int format)
00180 {
00181 switch( format ) {
00182 case DB5HDR_WIDTHCODE_8BIT:
00183 if( (*lenp = (*cp)) & 0x80 ) *lenp |= (-1L ^ 0xFF);
00184 return 1;
00185 case DB5HDR_WIDTHCODE_16BIT:
00186 if( (*lenp = BU_GSHORT(cp)) & 0x8000 ) *lenp |= (-1L ^ 0xFFFF);
00187 return 2;
00188 case DB5HDR_WIDTHCODE_32BIT:
00189 if( (*lenp = BU_GLONG(cp)) & 0x80000000 )
00190 *lenp |= (-1L ^ 0xFFFFFFFF);
00191 return 4;
00192 case DB5HDR_WIDTHCODE_64BIT:
00193 #if defined(IRIX64)
00194 if( sizeof(long) >= 8 ) {
00195 *lenp = BU_GLONGLONG(cp);
00196 return 8;
00197 }
00198 #endif
00199 bu_bomb("db5_decode_length(): encountered 64-bit length on 32-bit machine\n");
00200 }
00201 bu_bomb("db5_decode_length(): unknown width code\n");
00202 return 0;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 unsigned char *
00215 db5_encode_length(
00216 unsigned char *cp,
00217 long val,
00218 int format)
00219 {
00220 switch( format ) {
00221 case DB5HDR_WIDTHCODE_8BIT:
00222 *cp = val & 0xFF;
00223 return cp+1;
00224 case DB5HDR_WIDTHCODE_16BIT:
00225 return bu_pshort( cp, (short)val );
00226 case DB5HDR_WIDTHCODE_32BIT:
00227 return bu_plong( cp, val );
00228 case DB5HDR_WIDTHCODE_64BIT:
00229 #if defined(IRIX64)
00230 #endif
00231 bu_bomb("db5_encode_length(): encountered 64-bit length\n");
00232 }
00233 bu_bomb("db5_encode_length(): unknown width code\n");
00234 return 0;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244 int
00245 db5_crack_disk_header(struct db5_raw_internal *rip, const unsigned char *cp)
00246 {
00247 if( cp[0] != DB5HDR_MAGIC1 ) {
00248 bu_log("db5_crack_disk_header() bad magic1 -- database has become corrupted\n expected x%x, got x%x\n",
00249 DB5HDR_MAGIC1, cp[0]);
00250 if( cp[0] == 'I' ) {
00251 bu_log ("Concatenation of different database versions detected.\n");
00252 bu_log ("Run 'dbupgrade' on all databases before concatenation (cat command).\n");
00253 }
00254 return 0;
00255 }
00256
00257
00258 rip->h_dli = (cp[1] & DB5HDR_HFLAGS_DLI_MASK);
00259 rip->h_object_width = (cp[1] & DB5HDR_HFLAGS_OBJECT_WIDTH_MASK) >>
00260 DB5HDR_HFLAGS_OBJECT_WIDTH_SHIFT;
00261 rip->h_name_present = (cp[1] & DB5HDR_HFLAGS_NAME_PRESENT);
00262 rip->h_name_hidden = (cp[1] & DB5HDR_HFLAGS_HIDDEN_OBJECT);
00263 rip->h_name_width = (cp[1] & DB5HDR_HFLAGS_NAME_WIDTH_MASK) >>
00264 DB5HDR_HFLAGS_NAME_WIDTH_SHIFT;
00265
00266
00267 rip->a_width = (cp[2] & DB5HDR_AFLAGS_WIDTH_MASK) >>
00268 DB5HDR_AFLAGS_WIDTH_SHIFT;
00269 rip->a_present = (cp[2] & DB5HDR_AFLAGS_PRESENT);
00270 rip->a_zzz = (cp[2] & DB5HDR_AFLAGS_ZZZ_MASK);
00271
00272
00273 rip->b_width = (cp[3] & DB5HDR_BFLAGS_WIDTH_MASK) >>
00274 DB5HDR_BFLAGS_WIDTH_SHIFT;
00275 rip->b_present = (cp[3] & DB5HDR_BFLAGS_PRESENT);
00276 rip->b_zzz = (cp[3] & DB5HDR_BFLAGS_ZZZ_MASK);
00277
00278 rip->major_type = cp[4];
00279 rip->minor_type = cp[5];
00280
00281 if(RT_G_DEBUG&DEBUG_DB) bu_log("db5_crack_disk_header()\n\
00282 h_dli=%d, h_object_width=%d, h_name_present=%d, h_name_width=%d,\n\
00283 a_width=%d, a_present=%d, a_zzz=%d,\n\
00284 b_width=%d, b_present=%d, b_zzz=%d, major=%d, minor=%d\n",
00285 rip->h_dli,
00286 rip->h_object_width,
00287 rip->h_name_present,
00288 rip->h_name_width,
00289 rip->a_width,
00290 rip->a_present,
00291 rip->a_zzz,
00292 rip->b_width,
00293 rip->b_present,
00294 rip->b_zzz,
00295 rip->major_type,
00296 rip->minor_type );
00297
00298 return 0;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308 const unsigned char *
00309 db5_get_raw_internal_ptr( struct db5_raw_internal *rip, const unsigned char *ip)
00310 {
00311 const unsigned char *cp = ip;
00312
00313 if( db5_crack_disk_header( rip, cp ) < 0 ) return NULL;
00314 cp += sizeof(struct db5_ondisk_header);
00315
00316 cp += db5_decode_length( &rip->object_length, cp, rip->h_object_width );
00317 rip->object_length <<= 3;
00318
00319 if( rip->object_length < sizeof(struct db5_ondisk_header) ) {
00320 bu_log("db5_get_raw_internal_ptr(): object_length=%ld is too short, database is corrupted\n",
00321 rip->object_length);
00322 return NULL;
00323 }
00324
00325
00326 if( ip[rip->object_length-1] != DB5HDR_MAGIC2 ) {
00327 bu_log("db5_get_raw_internal_ptr() bad magic2 -- database has become corrupted.\n expected x%x, got x%x\n",
00328 DB5HDR_MAGIC2, ip[rip->object_length-1] );
00329 return NULL;
00330 }
00331
00332 BU_INIT_EXTERNAL( &rip->name );
00333 BU_INIT_EXTERNAL( &rip->body );
00334 BU_INIT_EXTERNAL( &rip->attributes );
00335
00336
00337 if( rip->h_name_present ) {
00338 cp += db5_decode_length( &rip->name.ext_nbytes,
00339 cp, rip->h_name_width );
00340 rip->name.ext_buf = (genptr_t)cp;
00341 cp += rip->name.ext_nbytes;
00342 }
00343
00344
00345 if( rip->a_present ) {
00346 cp += db5_decode_length( &rip->attributes.ext_nbytes,
00347 cp, rip->a_width );
00348 rip->attributes.ext_buf = (genptr_t)cp;
00349 cp += rip->attributes.ext_nbytes;
00350 }
00351
00352
00353 if( rip->b_present ) {
00354 cp += db5_decode_length( &rip->body.ext_nbytes,
00355 cp, rip->b_width );
00356 rip->body.ext_buf = (genptr_t)cp;
00357 cp += rip->body.ext_nbytes;
00358 }
00359
00360 rip->buf = NULL;
00361
00362 return ip + rip->object_length;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 int
00374 db5_get_raw_internal_fp(struct db5_raw_internal *rip, FILE *fp)
00375 {
00376 struct db5_ondisk_header header;
00377 unsigned char lenbuf[8];
00378 int count = 0;
00379 int used;
00380 long want, got;
00381 unsigned char *cp;
00382
00383 if( fread( (unsigned char *)&header, sizeof header, 1, fp ) != 1 ) {
00384 if( feof(fp) ) return -1;
00385 bu_log("db5_get_raw_internal_fp(): fread header error\n");
00386 return -2;
00387 }
00388 if( db5_crack_disk_header( rip, (unsigned char *)&header ) < 0 )
00389 return -2;
00390 used = sizeof(header);
00391
00392 switch( rip->h_object_width ) {
00393 case DB5HDR_WIDTHCODE_8BIT:
00394 count = 1;
00395 break;
00396 case DB5HDR_WIDTHCODE_16BIT:
00397 count = 2;
00398 break;
00399 case DB5HDR_WIDTHCODE_32BIT:
00400 count = 4;
00401 break;
00402 case DB5HDR_WIDTHCODE_64BIT:
00403 count = 8;
00404 }
00405 if( fread( lenbuf, count, 1, fp ) != 1 ) {
00406 bu_log("db5_get_raw_internal_fp(): fread lenbuf error\n");
00407 return -2;
00408 }
00409 used += db5_decode_length( &rip->object_length, lenbuf, rip->h_object_width );
00410 rip->object_length <<= 3;
00411
00412 if( rip->object_length < sizeof(struct db5_ondisk_header) ) {
00413 bu_log("db5_get_raw_internal_fp(): object_length=%ld is too short, database is corrupted\n",
00414 rip->object_length);
00415 return -1;
00416 }
00417
00418
00419 rip->buf = (unsigned char *)bu_malloc( rip->object_length, "raw v5 object" );
00420
00421 *((struct db5_ondisk_header *)rip->buf) = header;
00422 bcopy( lenbuf, rip->buf+sizeof(header), count );
00423
00424 cp = rip->buf+used;
00425 want = rip->object_length-used;
00426 BU_ASSERT_LONG( want, >, 0 );
00427 if( (got = fread( cp, 1, want, fp )) != want ) {
00428 bu_log("db5_get_raw_internal_fp(), want=%ld, got=%ld, database is too short\n",
00429 want, got );
00430 return -2;
00431 }
00432
00433
00434 if( rip->buf[rip->object_length-1] != DB5HDR_MAGIC2 ) {
00435 bu_log("db5_get_raw_internal_fp() bad magic2 -- database has become corrupted.\n expected x%x, got x%x\n",
00436 DB5HDR_MAGIC2, rip->buf[rip->object_length-1] );
00437 return -2;
00438 }
00439
00440 BU_INIT_EXTERNAL( &rip->name );
00441 BU_INIT_EXTERNAL( &rip->body );
00442 BU_INIT_EXTERNAL( &rip->attributes );
00443
00444
00445 if( rip->h_name_present ) {
00446 cp += db5_decode_length( &rip->name.ext_nbytes,
00447 cp, rip->h_name_width );
00448 rip->name.ext_buf = (genptr_t)cp;
00449 cp += rip->name.ext_nbytes;
00450 }
00451
00452
00453 if( rip->a_present ) {
00454 cp += db5_decode_length( &rip->attributes.ext_nbytes,
00455 cp, rip->a_width );
00456 rip->attributes.ext_buf = (genptr_t)cp;
00457 cp += rip->attributes.ext_nbytes;
00458 }
00459
00460
00461 if( rip->b_present ) {
00462 cp += db5_decode_length( &rip->body.ext_nbytes,
00463 cp, rip->b_width );
00464 rip->body.ext_buf = (genptr_t)cp;
00465 cp += rip->body.ext_nbytes;
00466 }
00467
00468 return 0;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 void
00480 db5_export_object3(
00481 struct bu_external *out,
00482 int dli,
00483 const char *name,
00484 const unsigned char hidden,
00485 const struct bu_external *attrib,
00486 const struct bu_external *body,
00487 int major,
00488 int minor,
00489 int a_zzz,
00490 int b_zzz )
00491 {
00492 struct db5_ondisk_header *odp;
00493 register unsigned char *cp;
00494 long namelen = 0;
00495 long need;
00496 int h_width, n_width, a_width, b_width;
00497 long togo;
00498
00499
00500
00501
00502
00503 need = sizeof(struct db5_ondisk_header);
00504 need += 8;
00505 if( name ) {
00506 namelen = strlen(name) + 1;
00507 if( namelen > 1 ) {
00508 n_width = db5_select_length_encoding(namelen);
00509 need += namelen + db5_enc_len[n_width];
00510 } else {
00511 name = NULL;
00512 namelen = 0;
00513 n_width = 0;
00514 }
00515 } else {
00516 n_width = 0;
00517 }
00518 if( attrib ) {
00519 BU_CK_EXTERNAL(attrib);
00520 if( attrib->ext_nbytes > 0 ) {
00521 a_width = db5_select_length_encoding(attrib->ext_nbytes);
00522 need += attrib->ext_nbytes + db5_enc_len[a_width];
00523 } else {
00524 attrib = NULL;
00525 a_width = 0;
00526 }
00527 } else {
00528 a_width = 0;
00529 }
00530 if( body ) {
00531 BU_CK_EXTERNAL(body);
00532 if( body->ext_nbytes > 0 ) {
00533 b_width = db5_select_length_encoding(body->ext_nbytes);
00534 need += body->ext_nbytes + db5_enc_len[b_width];
00535 } else {
00536 body = NULL;
00537 b_width = 0;
00538 }
00539 } else {
00540 b_width = 0;
00541 }
00542 need += 8;
00543
00544
00545 out->ext_magic = BU_EXTERNAL_MAGIC;
00546 out->ext_buf = bu_malloc( need, "external object3" );
00547 out->ext_nbytes = need;
00548
00549
00550 h_width = db5_select_length_encoding( (need+7)>>3 );
00551
00552
00553 odp = (struct db5_ondisk_header *)out->ext_buf;
00554 odp->db5h_magic1 = DB5HDR_MAGIC1;
00555
00556
00557 odp->db5h_hflags = (h_width << DB5HDR_HFLAGS_OBJECT_WIDTH_SHIFT) |
00558 (dli & DB5HDR_HFLAGS_DLI_MASK);
00559 if( name ) {
00560 odp->db5h_hflags |= DB5HDR_HFLAGS_NAME_PRESENT |
00561 (n_width << DB5HDR_HFLAGS_NAME_WIDTH_SHIFT);
00562
00563 }
00564 if( hidden ) {
00565 odp->db5h_hflags |= DB5HDR_HFLAGS_HIDDEN_OBJECT;
00566 }
00567
00568
00569 odp->db5h_aflags = a_width << DB5HDR_AFLAGS_WIDTH_SHIFT;
00570 if( attrib ) odp->db5h_aflags |= DB5HDR_AFLAGS_PRESENT;
00571 odp->db5h_aflags |= a_zzz & DB5HDR_AFLAGS_ZZZ_MASK;
00572
00573
00574 odp->db5h_bflags = b_width << DB5HDR_BFLAGS_WIDTH_SHIFT;
00575 if( body ) odp->db5h_bflags |= DB5HDR_BFLAGS_PRESENT;
00576 odp->db5h_bflags |= b_zzz & DB5HDR_BFLAGS_ZZZ_MASK;
00577
00578 if( a_zzz || b_zzz ) bu_bomb("db5_export_object3: compression not supported yet\n");
00579
00580
00581 odp->db5h_major_type = major;
00582 odp->db5h_minor_type = minor;
00583
00584
00585 cp = ((unsigned char *)out->ext_buf) + sizeof(struct db5_ondisk_header);
00586 cp = db5_encode_length( cp, 7L, h_width );
00587
00588 if( name ) {
00589 cp = db5_encode_length( cp, namelen, n_width );
00590 bcopy( name, cp, namelen );
00591 cp += namelen;
00592 }
00593
00594 if( attrib ) {
00595
00596
00597
00598
00599 BU_ASSERT_PTR( attrib->ext_nbytes, >=, 4 );
00600 cp = db5_encode_length( cp, attrib->ext_nbytes, a_width );
00601 bcopy( attrib->ext_buf, cp, attrib->ext_nbytes );
00602 cp += attrib->ext_nbytes;
00603 }
00604
00605 if( body ) {
00606 cp = db5_encode_length( cp, body->ext_nbytes, b_width );
00607 bcopy( body->ext_buf, cp, body->ext_nbytes );
00608 cp += body->ext_nbytes;
00609 }
00610
00611 togo = cp - ((unsigned char *)out->ext_buf) + 1;
00612 togo &= 7;
00613 if( togo != 0 ) {
00614 togo = 8 - togo;
00615 while( togo-- > 0 ) *cp++ = '\0';
00616 }
00617 *cp++ = DB5HDR_MAGIC2;
00618
00619
00620 togo = cp - ((unsigned char *)out->ext_buf);
00621 BU_ASSERT_LONG( togo&7, ==, 0 );
00622
00623
00624 cp = ((unsigned char *)out->ext_buf) + sizeof(struct db5_ondisk_header);
00625 cp = db5_encode_length( cp, togo>>3, h_width );
00626
00627 out->ext_nbytes = togo;
00628 BU_ASSERT_LONG( out->ext_nbytes, >=, 8 );
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638 void
00639 db5_make_free_object_hdr( struct bu_external *ep, long length )
00640 {
00641 struct db5_ondisk_header *odp;
00642 int h_width;
00643 unsigned char *cp;
00644
00645 BU_CK_EXTERNAL(ep);
00646
00647 BU_ASSERT_LONG( length, >=, 8 );
00648 BU_ASSERT_LONG( length&7, ==, 0 );
00649
00650
00651 ep->ext_nbytes = 8+8;
00652 ep->ext_buf = bu_calloc( 1, ep->ext_nbytes, "db5_make_free_object_hdr" );
00653
00654
00655 h_width = db5_select_length_encoding( length>>3 );
00656
00657
00658 odp = (struct db5_ondisk_header *)ep->ext_buf;
00659 odp->db5h_magic1 = DB5HDR_MAGIC1;
00660 odp->db5h_hflags = (h_width << DB5HDR_HFLAGS_OBJECT_WIDTH_SHIFT) |
00661 DB5HDR_HFLAGS_DLI_FREE_STORAGE;
00662
00663 cp = ((unsigned char *)ep->ext_buf) + sizeof(struct db5_ondisk_header);
00664 cp = db5_encode_length( cp, length>>3, h_width );
00665 }
00666
00667
00668
00669
00670
00671
00672
00673 void
00674 db5_make_free_object( struct bu_external *ep, long length )
00675 {
00676 struct db5_ondisk_header *odp;
00677 int h_width;
00678 unsigned char *cp;
00679
00680 BU_CK_EXTERNAL(ep);
00681
00682 BU_ASSERT_LONG( length, >=, 8 );
00683 BU_ASSERT_LONG( length&7, ==, 0 );
00684
00685 ep->ext_buf = bu_calloc( 1, length, "db5_make_free_object" );
00686 ep->ext_nbytes = length;
00687
00688
00689 h_width = db5_select_length_encoding( length>>3 );
00690
00691
00692 odp = (struct db5_ondisk_header *)ep->ext_buf;
00693 odp->db5h_magic1 = DB5HDR_MAGIC1;
00694 odp->db5h_hflags = (h_width << DB5HDR_HFLAGS_OBJECT_WIDTH_SHIFT) |
00695 DB5HDR_HFLAGS_DLI_FREE_STORAGE;
00696
00697 cp = ((unsigned char *)ep->ext_buf) + sizeof(struct db5_ondisk_header);
00698 cp = db5_encode_length( cp, length>>3, h_width );
00699
00700 cp = ((unsigned char *)ep->ext_buf) + length-1;
00701 *cp = DB5HDR_MAGIC2;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 int
00722 db5_import_attributes( struct bu_attribute_value_set *avs, const struct bu_external *ap )
00723 {
00724 const char *cp;
00725 const char *ep;
00726 int count = 0;
00727 struct bu_attribute_value_pair *app;
00728
00729 BU_CK_EXTERNAL(ap);
00730
00731 BU_ASSERT_LONG( ap->ext_nbytes, >=, 4 );
00732
00733
00734 cp = (const char *)ap->ext_buf;
00735 ep = (const char *)ap->ext_buf+ap->ext_nbytes;
00736
00737
00738 while( *cp != '\0' ) {
00739 const char *name = cp;
00740 if( cp >= ep ) {
00741 bu_log("db5_import_attributes() ran off end of buffer, database is probably corrupted\n");
00742 return -1;
00743 }
00744 cp += strlen(cp)+1;
00745 cp += strlen(cp)+1;
00746 count++;
00747 }
00748
00749 BU_ASSERT_PTR( cp+1, ==, ep );
00750
00751
00752
00753
00754
00755 bu_avs_init( avs, count, "db5_import_attributes" );
00756
00757
00758
00759
00760
00761
00762
00763
00764 #define AVS_ADD 1
00765
00766 #if AVS_ADD
00767 cp = (const char *)ap->ext_buf;
00768 while( *cp != '\0' ) {
00769 const char *name = cp;
00770 cp += strlen(cp)+1;
00771 bu_avs_add( avs, name, cp );
00772 cp += strlen(cp)+1;
00773 }
00774 #else
00775
00776
00777 cp = (const char *)ap->ext_buf;
00778 app = avs->avp;
00779 while( *cp != '\0' ) {
00780 app->name = cp;
00781 cp += strlen(cp)+1;
00782 app->value = cp;
00783 cp += strlen(cp)+1;
00784 app++;
00785 avs->count++;
00786 }
00787
00788
00789 if ( (!avs->readonly_min) || ((genptr_t)avs->readonly_min > (genptr_t)ap->ext_buf) ) {
00790 avs->readonly_min = (genptr_t)ap->ext_buf;
00791 }
00792 if ( (!avs->readonly_max) || ((genptr_t)avs->readonly_max < (genptr_t)(avs->readonly_min + ap->ext_nbytes)) ) {
00793 avs->readonly_max = (genptr_t)avs->readonly_min + ap->ext_nbytes;
00794 }
00795 #endif
00796
00797 BU_ASSERT_PTR( cp+1, ==, ep );
00798 BU_ASSERT_LONG( avs->count, <=, avs->max );
00799 BU_ASSERT_LONG( avs->count, ==, count );
00800
00801 if(bu_debug & BU_DEBUG_AVS) {
00802 bu_avs_print(avs, "db5_import_attributes");
00803 }
00804 return avs->count;
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 void
00820 db5_export_attributes( struct bu_external *ext, const struct bu_attribute_value_set *avs )
00821 {
00822 int need = 0;
00823 const struct bu_attribute_value_pair *avpp;
00824 char *cp;
00825 int i;
00826
00827 BU_CK_AVS( avs );
00828 avpp = avs->avp;
00829
00830 BU_INIT_EXTERNAL(ext);
00831 if( avs->count <= 0 ) return;
00832 if(bu_debug & BU_DEBUG_AVS) bu_avs_print(avs, "db5_export_attributes");
00833
00834
00835 for( i = 0; i < avs->count; i++, avpp++ ) {
00836 need += strlen( avpp->name ) + strlen( avpp->value ) + 2;
00837 }
00838 if( need <= 0 ) return;
00839 need += 1;
00840
00841 ext->ext_nbytes = need;
00842 ext->ext_buf = bu_malloc( need, "external attributes" );
00843
00844
00845 cp = (char *)ext->ext_buf;
00846 avpp = avs->avp;
00847 for( i = 0; i < avs->count; i++, avpp++ ) {
00848 need = strlen( avpp->name ) + 1;
00849 bcopy( avpp->name, cp, need );
00850 cp += need;
00851
00852 need = strlen( avpp->value ) + 1;
00853 bcopy( avpp->value, cp, need );
00854 cp += need;
00855 }
00856 *cp++ = '\0';
00857 need = cp - ((char *)ext->ext_buf);
00858 BU_ASSERT_LONG( need, ==, ext->ext_nbytes );
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 int
00876 db5_replace_attributes( struct directory *dp, struct bu_attribute_value_set *avsp, struct db_i *dbip )
00877 {
00878 struct bu_external ext;
00879 struct db5_raw_internal raw;
00880 struct bu_external attr;
00881 struct bu_external ext2;
00882 int ret;
00883
00884 RT_CK_DIR(dp);
00885 BU_CK_AVS(avsp);
00886 RT_CK_DBI(dbip);
00887
00888 if(RT_G_DEBUG&DEBUG_DB) {
00889 bu_log("db5_replace_attributes(%s) dbip=x%x\n",
00890 dp->d_namep, dbip );
00891 bu_avs_print( avsp, "new attributes" );
00892 }
00893
00894 if( dbip->dbi_read_only ) {
00895 bu_log("db5_replace_attributes(%s): READ-ONLY file\n",
00896 dbip->dbi_filename);
00897 return -1;
00898 }
00899
00900 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
00901
00902 if( db_get_external( &ext, dp, dbip ) < 0 )
00903 return -2;
00904
00905 if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
00906 bu_log("db5_replace_attributes(%s): import failure\n",
00907 dp->d_namep );
00908 bu_free_external( &ext );
00909 return -3;
00910 }
00911
00912 db5_export_attributes( &attr, avsp );
00913 BU_INIT_EXTERNAL(&ext2);
00914 db5_export_object3( &ext2,
00915 raw.h_dli,
00916 dp->d_namep,
00917 raw.h_name_hidden,
00918 &attr,
00919 &raw.body,
00920 raw.major_type, raw.minor_type,
00921 raw.a_zzz, raw.b_zzz );
00922
00923
00924 ret = db_put_external5( &ext2, dp, dbip );
00925 if( ret < 0 ) bu_log("db5_update_attributes(%s): db_put_external5() failure\n",
00926 dp->d_namep );
00927
00928 bu_free_external( &attr );
00929 bu_free_external( &ext2 );
00930 bu_free_external( &ext );
00931 bu_avs_free( avsp );
00932
00933 return ret;
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 int
00949 db5_update_attributes( struct directory *dp, struct bu_attribute_value_set *avsp, struct db_i *dbip )
00950 {
00951 struct bu_external ext;
00952 struct db5_raw_internal raw;
00953 struct bu_attribute_value_set old_avs;
00954 struct bu_external attr;
00955 struct bu_external ext2;
00956 int ret;
00957
00958 RT_CK_DIR(dp);
00959 BU_CK_AVS(avsp);
00960 RT_CK_DBI(dbip);
00961
00962 if(RT_G_DEBUG&DEBUG_DB) {
00963 bu_log("db5_update_attributes(%s) dbip=x%x\n",
00964 dp->d_namep, dbip );
00965 bu_avs_print( avsp, "new attributes" );
00966 }
00967
00968 if( dbip->dbi_read_only ) {
00969 bu_log("db5_update_attributes(%s): READ-ONLY file\n",
00970 dbip->dbi_filename);
00971 return -1;
00972 }
00973
00974 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
00975
00976 if( db_get_external( &ext, dp, dbip ) < 0 )
00977 return -2;
00978
00979 if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
00980 bu_log("db5_update_attributes(%s): import failure\n",
00981 dp->d_namep );
00982 bu_free_external( &ext );
00983 return -3;
00984 }
00985
00986 bu_avs_init( &old_avs, 4, "db5_update_attributes" );
00987 if( raw.attributes.ext_buf ) {
00988 if( db5_import_attributes( &old_avs, &raw.attributes ) < 0 ) {
00989 bu_log("db5_update_attributes(%s): mal-formed attributes in database\n",
00990 dp->d_namep );
00991 bu_free_external( &ext );
00992 return -8;
00993 }
00994 }
00995
00996 bu_avs_merge( &old_avs, avsp );
00997
00998 db5_export_attributes( &attr, &old_avs );
00999 BU_INIT_EXTERNAL(&ext2);
01000 db5_export_object3( &ext2,
01001 raw.h_dli,
01002 dp->d_namep,
01003 raw.h_name_hidden,
01004 &attr,
01005 &raw.body,
01006 raw.major_type, raw.minor_type,
01007 raw.a_zzz, raw.b_zzz );
01008
01009
01010 ret = db_put_external5( &ext2, dp, dbip );
01011 if( ret < 0 ) bu_log("db5_update_attributes(%s): db_put_external5() failure\n",
01012 dp->d_namep );
01013
01014 bu_free_external( &attr );
01015 bu_free_external( &ext2 );
01016 bu_free_external( &ext );
01017 bu_avs_free( &old_avs );
01018 bu_avs_free( avsp );
01019
01020 return ret;
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 int
01033 db5_update_attribute( const char *obj_name, const char *aname, const char *value, struct db_i *dbip )
01034 {
01035 struct directory *dp;
01036 struct bu_attribute_value_set avs;
01037
01038 RT_CK_DBI(dbip);
01039 if( (dp = db_lookup( dbip, obj_name, LOOKUP_NOISY )) == DIR_NULL )
01040 return -1;
01041
01042 bu_avs_init( &avs, 2, "db5_update_attribute" );
01043 bu_avs_add( &avs, aname, value );
01044
01045 return db5_update_attributes( dp, &avs, dbip );
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 int db5_update_ident( struct db_i *dbip, const char *title, double local2mm )
01061 {
01062 struct bu_attribute_value_set avs;
01063 struct directory *dp;
01064 struct bu_vls units;
01065 int ret;
01066 char *old_title = NULL;
01067
01068 RT_CK_DBI(dbip);
01069
01070 if( (dp = db_lookup( dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_QUIET )) == DIR_NULL ) {
01071 struct bu_external global;
01072 unsigned char minor_type=0;
01073
01074 bu_log("db5_update_ident() WARNING: %s object is missing, creating new one.\nYou may have lost important global state when you deleted this object.\n",
01075 DB5_GLOBAL_OBJECT_NAME );
01076
01077
01078 db5_export_object3( &global,
01079 DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
01080 DB5_GLOBAL_OBJECT_NAME, DB5HDR_HFLAGS_HIDDEN_OBJECT, NULL, NULL,
01081 DB5_MAJORTYPE_ATTRIBUTE_ONLY, 0,
01082 DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED );
01083
01084 dp = db_diradd( dbip, DB5_GLOBAL_OBJECT_NAME, -1L, 0, 0, (genptr_t)&minor_type);
01085 dp->d_major_type = DB5_MAJORTYPE_ATTRIBUTE_ONLY;
01086 if( db_put_external( &global, dp, dbip ) < 0 ) {
01087 bu_log("db5_update_ident() unable to create replacement %s object!\n", DB5_GLOBAL_OBJECT_NAME );
01088 bu_free_external(&global);
01089 return -1;
01090 }
01091 bu_free_external(&global);
01092 }
01093
01094 bu_vls_init( &units );
01095 bu_vls_printf( &units, "%.25e", local2mm );
01096
01097 bu_avs_init( &avs, 4, "db5_update_ident" );
01098 bu_avs_add( &avs, "title", title );
01099 bu_avs_add( &avs, "units", bu_vls_addr(&units) );
01100
01101 ret = db5_update_attributes( dp, &avs, dbip );
01102 bu_vls_free( &units );
01103
01104
01105
01106 if(dbip->dbi_title) {
01107 old_title = dbip->dbi_title;
01108 }
01109 dbip->dbi_title = bu_strdup(title);
01110 if (old_title) {
01111 bu_free(old_title, "replaced dbi_title with new");
01112 }
01113
01114 return ret;
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 int
01140 db5_fwrite_ident(FILE *fp, const char *title, double local2mm)
01141 {
01142 struct bu_attribute_value_set avs;
01143 struct bu_vls units;
01144 struct bu_external out;
01145 struct bu_external attr;
01146 int result;
01147
01148 if( local2mm <= 0 ) {
01149 bu_log("db5_fwrite_ident(%s, %g) local2mm <= 0\n",
01150 title, local2mm );
01151 return -1;
01152 }
01153
01154
01155 db5_export_object3( &out, DB5HDR_HFLAGS_DLI_HEADER_OBJECT,
01156 NULL, 0, NULL, NULL,
01157 DB5_MAJORTYPE_RESERVED, 0,
01158 DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED );
01159
01160 result = bu_fwrite_external( fp, &out );
01161 bu_free_external( &out );
01162 if (result < 0) {
01163 return -1;
01164 }
01165
01166
01167 bu_vls_init( &units );
01168 bu_vls_printf( &units, "%.25e", local2mm );
01169
01170 bu_avs_init( &avs, 4, "db5_fwrite_ident" );
01171 bu_avs_add( &avs, "title", title );
01172 bu_avs_add( &avs, "units", bu_vls_addr(&units) );
01173
01174 db5_export_attributes( &attr, &avs );
01175 db5_export_object3( &out, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
01176 DB5_GLOBAL_OBJECT_NAME, DB5HDR_HFLAGS_HIDDEN_OBJECT, &attr, NULL,
01177 DB5_MAJORTYPE_ATTRIBUTE_ONLY, 0,
01178 DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED );
01179
01180 result = bu_fwrite_external( fp, &out );
01181 bu_free_external( &out );
01182 bu_free_external( &attr );
01183 bu_avs_free( &avs );
01184 bu_vls_free( &units );
01185 if (result < 0) {
01186 return -1;
01187 }
01188
01189 return 0;
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212 int
01213 rt_db_cvt_to_external5(
01214 struct bu_external *ext,
01215 const char *name,
01216 const struct rt_db_internal *ip,
01217 double conv2mm,
01218 struct db_i *dbip,
01219 struct resource *resp,
01220 const int major)
01221 {
01222 struct bu_external attributes;
01223 struct bu_external body;
01224 int minor;
01225
01226 RT_CK_DB_INTERNAL( ip );
01227 if(dbip) RT_CK_DBI(dbip);
01228 RT_CK_RESOURCE(resp);
01229 BU_INIT_EXTERNAL( &body );
01230
01231 minor = ip->idb_type;
01232
01233
01234 if( ip->idb_meth->ft_export5( &body, ip, conv2mm, dbip, resp, minor ) < 0 ) {
01235 bu_log("rt_db_cvt_to_external5(%s): ft_export5 failure\n",
01236 name);
01237 bu_free_external( &body );
01238 BU_INIT_EXTERNAL(ext);
01239 return -1;
01240 }
01241 BU_CK_EXTERNAL( &body );
01242
01243
01244 if( ip->idb_avs.magic == BU_AVS_MAGIC ) {
01245 db5_export_attributes( &attributes, &ip->idb_avs );
01246 BU_CK_EXTERNAL( &attributes );
01247 } else {
01248 BU_INIT_EXTERNAL(&attributes);
01249 }
01250
01251 db5_export_object3( ext, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
01252 name, 0, &attributes, &body,
01253 major, minor,
01254 DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED );
01255 BU_CK_EXTERNAL( ext );
01256 bu_free_external( &body );
01257 bu_free_external( &attributes );
01258
01259 return 0;
01260 }
01261
01262
01263
01264
01265
01266
01267 int
01268 db_wrap_v5_external( struct bu_external *ep, const char *name )
01269 {
01270 struct db5_raw_internal raw;
01271 struct bu_external tmp;
01272
01273 BU_CK_EXTERNAL(ep);
01274
01275
01276 if( db5_get_raw_internal_ptr( &raw, (unsigned char *)ep->ext_buf ) == NULL ) {
01277 bu_log("db_put_external5(%s) failure in db5_get_raw_internal_ptr()\n",
01278 name);
01279 return -1;
01280 }
01281 BU_ASSERT_LONG( raw.h_dli, ==, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT );
01282
01283
01284 if( raw.name.ext_buf == NULL || strcmp( name, raw.name.ext_buf ) != 0 ) {
01285
01286
01287
01288
01289 tmp = *ep;
01290 BU_INIT_EXTERNAL(ep);
01291
01292 db5_export_object3( ep,
01293 DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
01294 name,
01295 raw.h_name_hidden,
01296 &raw.attributes,
01297 &raw.body,
01298 raw.major_type, raw.minor_type,
01299 raw.a_zzz, raw.b_zzz );
01300
01301 bu_free_external( &tmp );
01302 return 0;
01303 }
01304
01305
01306 return 0;
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 int
01334 db_put_external5(struct bu_external *ep, struct directory *dp, struct db_i *dbip)
01335 {
01336 RT_CK_DBI(dbip);
01337 RT_CK_DIR(dp);
01338 BU_CK_EXTERNAL(ep);
01339
01340 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_put_external5(%s) ep=x%x, dbip=x%x, dp=x%x\n",
01341 dp->d_namep, ep, dbip, dp );
01342
01343 if( dbip->dbi_read_only ) {
01344 bu_log("db_put_external5(%s): READ-ONLY file\n",
01345 dbip->dbi_filename);
01346 return -1;
01347 }
01348
01349 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
01350
01351
01352 if( db_wrap_v5_external( ep, dp->d_namep ) < 0 ) {
01353 bu_log("db_put_external5(%s) failure in db_wrap_v5_external()\n",
01354 dp->d_namep);
01355 return -1;
01356 }
01357
01358
01359 if( ep->ext_nbytes != dp->d_len || dp->d_addr == -1L ) {
01360 if( db5_realloc( dbip, dp, ep ) < 0 ) {
01361 bu_log("db_put_external(%s) db_realloc5() failed\n", dp->d_namep);
01362 return -5;
01363 }
01364 }
01365 BU_ASSERT_LONG( ep->ext_nbytes, ==, dp->d_len );
01366
01367 if( dp->d_flags & RT_DIR_INMEM ) {
01368 bcopy( (char *)ep->ext_buf, dp->d_un.ptr, ep->ext_nbytes );
01369 return 0;
01370 }
01371
01372 if( db_write( dbip, (char *)ep->ext_buf, ep->ext_nbytes, dp->d_addr ) < 0 ) {
01373 return -1;
01374 }
01375 return 0;
01376 }
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 int
01395 rt_db_put_internal5(
01396 struct directory *dp,
01397 struct db_i *dbip,
01398 struct rt_db_internal *ip,
01399 struct resource *resp,
01400 const int major)
01401 {
01402 struct bu_external ext;
01403
01404 RT_CK_DIR(dp);
01405 RT_CK_DBI(dbip);
01406 RT_CK_DB_INTERNAL( ip );
01407 RT_CK_RESOURCE(resp);
01408
01409 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
01410
01411 if( rt_db_cvt_to_external5( &ext, dp->d_namep, ip, 1.0, dbip, resp, major ) < 0 ) {
01412 bu_log("rt_db_put_internal5(%s): export failure\n",
01413 dp->d_namep);
01414 goto fail;
01415 }
01416 BU_CK_EXTERNAL( &ext );
01417
01418 if( ext.ext_nbytes != dp->d_len || dp->d_addr == -1L ) {
01419 if( db5_realloc( dbip, dp, &ext ) < 0 ) {
01420 bu_log("rt_db_put_internal5(%s) db_realloc5() failed\n", dp->d_namep);
01421 goto fail;
01422 }
01423 }
01424 BU_ASSERT_LONG( ext.ext_nbytes, ==, dp->d_len );
01425
01426 if( dp->d_flags & RT_DIR_INMEM ) {
01427 bcopy( (char *)ext.ext_buf, dp->d_un.ptr, ext.ext_nbytes );
01428 goto ok;
01429 }
01430
01431 if( db_write( dbip, (char *)ext.ext_buf, ext.ext_nbytes, dp->d_addr ) < 0 ) {
01432 goto fail;
01433 }
01434 ok:
01435 bu_free_external( &ext );
01436 rt_db_free_internal( ip, resp );
01437 return 0;
01438
01439 fail:
01440 bu_free_external( &ext );
01441 rt_db_free_internal( ip, resp );
01442 return -2;
01443 }
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455 int
01456 rt_db_external5_to_internal5(
01457 struct rt_db_internal *ip,
01458 const struct bu_external *ep,
01459 const char *name,
01460 const struct db_i *dbip,
01461 const mat_t mat,
01462 struct resource *resp)
01463 {
01464 register int id;
01465 struct db5_raw_internal raw;
01466
01467 BU_CK_EXTERNAL(ep);
01468 RT_CK_DB_INTERNAL(ip);
01469 RT_CK_DBI(dbip);
01470
01471 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
01472
01473 if (db5_get_raw_internal_ptr(&raw, ep->ext_buf) == NULL) {
01474 bu_log("rt_db_external5_to_internal5(%s): import failure\n",
01475 name );
01476 return -3;
01477 }
01478
01479 if(( raw.major_type == DB5_MAJORTYPE_BRLCAD )
01480 ||( raw.major_type == DB5_MAJORTYPE_BINARY_UNIF)) {
01481
01482 if( mat == NULL ) mat = bn_mat_identity;
01483 } else {
01484 bu_log("rt_db_external5_to_internal5(%s): unable to import non-BRL-CAD object, major=%d\n",
01485 name, raw.major_type );
01486 return -1;
01487 }
01488
01489 if (ip->idb_avs.magic != BU_AVS_MAGIC) {
01490 bu_avs_init_empty( &ip->idb_avs );
01491 }
01492
01493
01494
01495
01496 if( raw.attributes.ext_buf ) {
01497 if( db5_import_attributes( &ip->idb_avs, &raw.attributes ) < 0 ) {
01498 bu_log("rt_db_external5_to_internal5(%s): mal-formed attributes in database\n",
01499 name );
01500 return -8;
01501 }
01502 }
01503
01504 if( !raw.body.ext_buf ) {
01505 bu_log("rt_db_external5_to_internal5(%s): object has no body\n",
01506 name );
01507 return -4;
01508 }
01509
01510
01511
01512
01513 switch ( raw.major_type ) {
01514 case DB5_MAJORTYPE_BRLCAD:
01515 id = raw.minor_type; break;
01516 case DB5_MAJORTYPE_BINARY_UNIF:
01517 id = ID_BINUNIF; break;
01518 default:
01519 bu_log("rt_db_external5_to_internal5(%s): don't yet handle major_type %d\n", name, raw.major_type);
01520 return -1;
01521 }
01522
01523 if( rt_functab[id].ft_import5( ip, &raw.body, mat, dbip, resp, raw.minor_type ) < 0 ) {
01524 bu_log("rt_db_external5_to_internal5(%s): import failure\n",
01525 name );
01526 rt_db_free_internal( ip, resp );
01527 return -1;
01528 }
01529
01530
01531 RT_CK_DB_INTERNAL( ip );
01532 ip->idb_major_type = raw.major_type;
01533 ip->idb_minor_type = raw.minor_type;
01534 ip->idb_meth = &rt_functab[id];
01535
01536 return id;
01537 }
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552 int
01553 rt_db_get_internal5(
01554 struct rt_db_internal *ip,
01555 const struct directory *dp,
01556 const struct db_i *dbip,
01557 const mat_t mat,
01558 struct resource *resp)
01559 {
01560 struct bu_external ext;
01561 int ret;
01562
01563 BU_INIT_EXTERNAL(&ext);
01564 RT_INIT_DB_INTERNAL(ip);
01565
01566 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
01567
01568 if( db_get_external( &ext, dp, dbip ) < 0 )
01569 return -2;
01570
01571 ret = rt_db_external5_to_internal5( ip, &ext, dp->d_namep, dbip, mat, resp );
01572 bu_free_external(&ext);
01573 return ret;
01574 }
01575
01576
01577
01578
01579 void
01580 db5_export_color_table( struct bu_vls *ostr, struct db_i *dbip )
01581 {
01582 struct mater *mp;
01583
01584 BU_CK_VLS(ostr);
01585 RT_CK_DBI(dbip);
01586
01587 for( mp = rt_material_head; mp != MATER_NULL; mp = mp->mt_forw ) {
01588 bu_vls_printf(ostr,
01589 "{%d %d %d %d %d} ",
01590 mp->mt_low,
01591 mp->mt_high,
01592 mp->mt_r,
01593 mp->mt_g,
01594 mp->mt_b );
01595 }
01596 }
01597
01598
01599
01600
01601 void
01602 db5_import_color_table( char *cp )
01603 {
01604 char *sp = cp;
01605 int low, high, r, g, b;
01606
01607 while( (sp = strchr( sp, '{' )) != NULL ) {
01608 sp++;
01609 if( sscanf( sp, "%d %d %d %d %d", &low, &high, &r, &g, &b ) != 5 ) break;
01610 rt_color_addrec( low, high, r, g, b, -1L );
01611 }
01612 }
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 int
01625 db5_put_color_table( struct db_i *dbip )
01626 {
01627 struct bu_vls str;
01628 int ret;
01629
01630 RT_CK_DBI(dbip);
01631 BU_ASSERT_LONG( dbip->dbi_version, ==, 5 );
01632
01633 bu_vls_init(&str);
01634 db5_export_color_table( &str, dbip );
01635
01636 ret = db5_update_attribute( DB5_GLOBAL_OBJECT_NAME,
01637 "regionid_colortable", bu_vls_addr(&str), dbip );
01638
01639 bu_vls_free( &str );
01640 return ret;
01641 }
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651 int
01652 db5_get_attributes( const struct db_i *dbip, struct bu_attribute_value_set *avs, const struct directory *dp )
01653 {
01654 struct bu_external ext;
01655 struct db5_raw_internal raw;
01656
01657 RT_CK_DBI( dbip );
01658
01659 if( dbip->dbi_version < 5 )
01660 return 0;
01661
01662 RT_CK_DIR( dp );
01663
01664 BU_INIT_EXTERNAL(&ext);
01665
01666 if( db_get_external( &ext, dp, dbip ) < 0 )
01667 return -1;
01668
01669 if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
01670 bu_free_external( &ext );
01671 return -2;
01672 }
01673
01674 if( raw.attributes.ext_buf ) {
01675 if( db5_import_attributes( avs, &raw.attributes ) < 0 ) {
01676 bu_free_external( &ext );
01677 return -3;
01678 }
01679 }
01680
01681 bu_free_external( &ext );
01682 return 0;
01683 }
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694