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
00038
00039
00040
00041
00042
00043 #ifndef lint
00044 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db_io.c,v 14.19 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00045 #endif
00046
00047 #include "common.h"
00048
00049 #include <stdio.h>
00050 #ifdef HAVE_UNISTD_H
00051 # include <unistd.h>
00052 #endif
00053 #ifdef HAVE_SYS_TYPES_H
00054 # include <sys/types.h>
00055 #endif
00056 #ifdef HAVE_STRING_H
00057 # include <string.h>
00058 #else
00059 # include <strings.h>
00060 #endif
00061
00062 #include "machine.h"
00063 #include "vmath.h"
00064 #include "db.h"
00065 #include "raytrace.h"
00066
00067 #include "./debug.h"
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 int
00082 db_read(const struct db_i *dbip, genptr_t addr, long int count, long int offset)
00083
00084
00085 {
00086 register int got;
00087 #ifdef HAVE_UNIX_IO
00088 register long s;
00089 #endif
00090
00091 RT_CK_DBI(dbip);
00092 if(RT_G_DEBUG&DEBUG_DB) {
00093 bu_log("db_read(dbip=x%x, addr=x%x, count=%d., offset=x%x)\n",
00094 dbip, addr, count, offset );
00095 }
00096 if( count <= 0 || offset < 0 ) {
00097 return(-1);
00098 }
00099 if( offset+count > dbip->dbi_eof ) {
00100
00101 bu_log("db_read(%s) ERROR offset=%d, count=%d, dbi_eof=%d\n",
00102 dbip->dbi_filename,
00103 offset, count, dbip->dbi_eof );
00104 return -1;
00105 }
00106 if( dbip->dbi_inmem ) {
00107 memcpy( addr, ((char *)dbip->dbi_inmem) + offset, count );
00108 return(0);
00109 }
00110 bu_semaphore_acquire( BU_SEM_SYSCALL );
00111 #ifdef HAVE_LSEEK
00112 if ((s=(long)lseek( dbip->dbi_fd, (off_t)offset, 0 )) != offset) {
00113 bu_log("db_read: lseek returns %d not %d\n", s, offset);
00114 bu_bomb("db_read: Goodbye");
00115 }
00116 got = read( dbip->dbi_fd, addr, count );
00117 #else
00118 if (fseek( dbip->dbi_fp, offset, 0 ))
00119 bu_bomb("db_read: fseek error\n");
00120 got = fread( addr, 1, count, dbip->dbi_fp );
00121 #endif
00122 bu_semaphore_release( BU_SEM_SYSCALL );
00123
00124 if( got != count ) {
00125 if (got < 0) {
00126 perror(dbip->dbi_filename);
00127 }
00128 bu_log("db_read(%s): read error. Wanted %d, got %d bytes\n",
00129 dbip->dbi_filename, count, got );
00130 return(-1);
00131 }
00132 return(0);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 union record *
00150 db_getmrec(const struct db_i *dbip, const struct directory *dp)
00151 {
00152 union record *where;
00153
00154 RT_CK_DBI(dbip);
00155 RT_CK_DIR(dp);
00156
00157 if( dbip->dbi_version >= 5 ) {
00158
00159 return (union record *)NULL;
00160 }
00161
00162 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_getmrec(%s) x%x, x%x\n",
00163 dp->d_namep, dbip, dp );
00164
00165 if( dp->d_addr < 0 )
00166 return( (union record *)0 );
00167 where = (union record *)bu_malloc(
00168 dp->d_len * sizeof(union record),
00169 "db_getmrec record[]");
00170
00171 if( dp->d_flags & RT_DIR_INMEM ) {
00172 bcopy( dp->d_un.ptr, (char *)where, dp->d_len * sizeof(union record) );
00173 return where;
00174 }
00175
00176 if( db_read( dbip, (char *)where,
00177 (long)dp->d_len * sizeof(union record),
00178 dp->d_addr ) < 0 ) {
00179 bu_free( (genptr_t)where, "db_getmrec record[]" );
00180 return( (union record *)0 );
00181 }
00182 return( where );
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 int
00196 db_get(const struct db_i *dbip, const struct directory *dp, union record *where, int offset, int len)
00197 {
00198
00199 RT_CK_DBI(dbip);
00200 RT_CK_DIR(dp);
00201 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_get(%s) x%x, x%x x%x off=%d len=%d\n",
00202 dp->d_namep, dbip, dp, where, offset, len );
00203
00204 if( dp->d_addr < 0 ) {
00205 where->u_id = '\0';
00206 return(-1);
00207 }
00208 if( offset < 0 || offset+len > dp->d_len ) {
00209 bu_log("db_get(%s): xfer %d..%x exceeds 0..%d\n",
00210 dp->d_namep, offset, offset+len, dp->d_len );
00211 where->u_id = '\0';
00212 return(-1);
00213 }
00214
00215 if( dp->d_flags & RT_DIR_INMEM ) {
00216 bcopy( ((char *)dp->d_un.ptr) + offset * sizeof(union record),
00217 (char *)where,
00218 len * sizeof(union record) );
00219 return 0;
00220 }
00221
00222 if( db_read( dbip, (char *)where, (long)len * sizeof(union record),
00223 dp->d_addr + offset * sizeof(union record) ) < 0 ) {
00224 where->u_id = '\0';
00225 return(-1);
00226 }
00227 return(0);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 int
00243 db_write(struct db_i *dbip, const genptr_t addr, long int count, long int offset)
00244 {
00245 register int got;
00246
00247 RT_CK_DBI(dbip);
00248 if(RT_G_DEBUG&DEBUG_DB) {
00249 bu_log("db_write(dbip=x%x, addr=x%x, count=%d., offset=x%x)\n",
00250 dbip, addr, count, offset );
00251 }
00252 if( dbip->dbi_read_only ) {
00253 bu_log("db_write(%s): READ-ONLY file\n",
00254 dbip->dbi_filename);
00255 return(-1);
00256 }
00257 if( count <= 0 || offset < 0 ) {
00258 return(-1);
00259 }
00260 if( dbip->dbi_inmem ) {
00261 bu_log("db_write() in memory?\n");
00262 return(-1);
00263 }
00264 bu_semaphore_acquire( BU_SEM_SYSCALL );
00265 #ifdef HAVE_UNIX_IO
00266 (void)lseek( dbip->dbi_fd, offset, 0 );
00267 got = write( dbip->dbi_fd, addr, count );
00268 #else
00269 (void)fseek( dbip->dbi_fp, offset, 0 );
00270 got = fwrite( addr, 1, count, dbip->dbi_fp );
00271 fflush(dbip->dbi_fp);
00272 #endif
00273 bu_semaphore_release( BU_SEM_SYSCALL );
00274 if( got != count ) {
00275 perror("db_write");
00276 bu_log("db_write(%s): write error. Wanted %d, got %d bytes.\nFile forced read-only.\n",
00277 dbip->dbi_filename, count, got );
00278 dbip->dbi_read_only = 1;
00279 return(-1);
00280 }
00281 return(0);
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 int
00295 db_put(struct db_i *dbip, const struct directory *dp, union record *where, int offset, int len)
00296 {
00297
00298 RT_CK_DBI(dbip);
00299 RT_CK_DIR(dp);
00300 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_put(%s) x%x, x%x x%x off=%d len=%d\n",
00301 dp->d_namep, dbip, dp, where, offset, len );
00302
00303 if( offset < 0 || offset+len > dp->d_len ) {
00304 bu_log("db_put(%s): xfer %d..%x exceeds 0..%d\n",
00305 dp->d_namep, offset, offset+len, dp->d_len );
00306 return(-1);
00307 }
00308
00309 if( dp->d_flags & RT_DIR_INMEM ) {
00310 bcopy( (char *)where,
00311 ((char *)dp->d_un.ptr) + offset * sizeof(union record),
00312 len * sizeof(union record) );
00313 return 0;
00314 }
00315
00316 if( dbip->dbi_read_only ) {
00317 bu_log("db_put(%s): READ-ONLY file\n",
00318 dbip->dbi_filename);
00319 return(-1);
00320 }
00321
00322 if( db_write( dbip, (char *)where, (long)len * sizeof(union record),
00323 dp->d_addr + offset * sizeof(union record) ) < 0 ) {
00324 return(-1);
00325 }
00326 return(0);
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 int
00346 db_get_external(register struct bu_external *ep, const struct directory *dp, const struct db_i *dbip)
00347 {
00348 RT_CK_DBI(dbip);
00349 RT_CK_DIR(dp);
00350 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_get_external(%s) ep=x%x, dbip=x%x, dp=x%x\n",
00351 dp->d_namep, ep, dbip, dp );
00352
00353 if( (dp->d_flags & RT_DIR_INMEM) == 0 && dp->d_addr < 0 )
00354 return( -1 );
00355
00356 BU_INIT_EXTERNAL(ep);
00357 if( dbip->dbi_version <= 4 )
00358 ep->ext_nbytes = dp->d_len * sizeof(union record);
00359 else
00360 ep->ext_nbytes = dp->d_len;
00361 ep->ext_buf = (genptr_t)bu_malloc(ep->ext_nbytes, "db_get_ext ext_buf");
00362
00363 if( dp->d_flags & RT_DIR_INMEM ) {
00364 bcopy( dp->d_un.ptr, (char *)ep->ext_buf, ep->ext_nbytes );
00365 return 0;
00366 }
00367
00368 if( db_read( dbip, (char *)ep->ext_buf,
00369 (long)ep->ext_nbytes, dp->d_addr ) < 0 ) {
00370 bu_free( ep->ext_buf, "db_get_ext ext_buf" );
00371 ep->ext_buf = (genptr_t)NULL;
00372 ep->ext_nbytes = 0;
00373 return( -1 );
00374 }
00375 return(0);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 int
00399 db_put_external(struct bu_external *ep, struct directory *dp, struct db_i *dbip)
00400 {
00401
00402 RT_CK_DBI(dbip);
00403 RT_CK_DIR(dp);
00404 BU_CK_EXTERNAL(ep);
00405 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_put_external(%s) ep=x%x, dbip=x%x, dp=x%x\n",
00406 dp->d_namep, ep, dbip, dp );
00407
00408
00409 if( dbip->dbi_read_only ) {
00410 bu_log("db_put_external(%s): READ-ONLY file\n",
00411 dbip->dbi_filename);
00412 return(-1);
00413 }
00414
00415 if( dbip->dbi_version == 5 )
00416 return db_put_external5( ep, dp, dbip );
00417
00418 if( dbip->dbi_version <= 4 ) {
00419 int ngran;
00420
00421 ngran = (ep->ext_nbytes+sizeof(union record)-1)/sizeof(union record);
00422 if( ngran != dp->d_len ) {
00423 if( dp->d_addr != -1L ) {
00424 if( db_delete( dbip, dp ) < 0 )
00425 return -2;
00426 }
00427 if( db_alloc( dbip, dp, ngran ) < 0 ) {
00428 return -3;
00429 }
00430 }
00431
00432 if( ngran != dp->d_len ) {
00433 bu_log("db_put_external(%s) ngran=%d != dp->d_len %d\n",
00434 dp->d_namep, ngran, dp->d_len );
00435 bu_bomb("db_io.c: db_put_external()");
00436 }
00437
00438 db_wrap_v4_external( ep, dp->d_namep );
00439 } else
00440 bu_bomb("db_put_external(): unknown dbi_version\n");
00441
00442 if( dp->d_flags & RT_DIR_INMEM ) {
00443 bcopy( (char *)ep->ext_buf, dp->d_un.ptr, ep->ext_nbytes );
00444 return 0;
00445 }
00446
00447 if( db_write( dbip, (char *)ep->ext_buf, ep->ext_nbytes, dp->d_addr ) < 0 ) {
00448 return(-1);
00449 }
00450 return(0);
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 int
00474 db_fwrite_external(FILE *fp, const char *name, struct bu_external *ep)
00475
00476
00477
00478 {
00479
00480 if(RT_G_DEBUG&DEBUG_DB) bu_log("db_fwrite_external(%s) ep=x%x\n",
00481 name, ep);
00482
00483 BU_CK_EXTERNAL(ep);
00484
00485 db_wrap_v4_external( ep, name );
00486
00487 return bu_fwrite_external( fp, ep );
00488 }
00489
00490
00491
00492
00493
00494
00495 void
00496 db_free_external(register struct bu_external *ep)
00497 {
00498 BU_CK_EXTERNAL(ep);
00499 bu_free_external(ep);
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511