BRL-CAD
binunif.c
Go to the documentation of this file.
1 /* B I N U N I F . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2001-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup db5 */
21 /** @{ */
22 /** @file binunif.c
23  *
24  * Routines for writing binary objects to a BRL-CAD database
25  * Assumes that some of the structure of such databases are known
26  * by the calling routines.
27  *
28  * Return codes of 0 are OK, -1 signal an error.
29  *
30  */
31 /** @} */
32 
33 #include "common.h"
34 
35 #include <sys/stat.h>
36 #include <math.h>
37 #include <string.h>
38 #include <limits.h>
39 
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
42 #endif
43 
44 #include "bio.h"
45 
46 
47 #include "vmath.h"
48 #include "bn.h"
49 #include "rtgeom.h"
50 #include "raytrace.h"
51 #include "wdb.h"
52 
53 
54 int
55 rt_mk_binunif(struct rt_wdb *wdbp, const char *obj_name, const char *file_name, unsigned int minor_type, size_t max_count)
56 {
57  int ret;
58  struct stat st;
59  size_t num_items = 0;
60  size_t obj_length = 0;
61  size_t item_length = 0;
62  unsigned int major_type = DB5_MAJORTYPE_BINARY_UNIF;
63  struct directory *dp = NULL;
64  struct bu_mapped_file *bu_fd = NULL;
65  struct rt_binunif_internal *bip = NULL;
66  struct bu_external body;
67  struct bu_external bin_ext;
68  struct rt_db_internal intern;
69 
70  item_length = db5_type_sizeof_h_binu(minor_type);
71  if (item_length == 0) {
72  bu_log("Unrecognized minor type (%d)!\n", minor_type);
73  return -1;
74  }
75 
76  if (stat(file_name, &st)) {
77  bu_log("Cannot stat input file (%s)", file_name);
78  return -1;
79  }
80 
81  bu_fd = bu_open_mapped_file(file_name, NULL);
82  if (bu_fd == NULL) {
83  bu_log("Cannot open input file (%s) for reading", file_name);
84  return -1;
85  }
86 
87  /* create the rt_binunif internal form */
88  BU_ALLOC(bip, struct rt_binunif_internal);
90  bip->type = minor_type;
91 
92  num_items = (size_t)(st.st_size / item_length);
93 
94  /* maybe only a partial file read */
95  if (max_count > 0 && max_count < num_items) {
96  num_items = max_count;
97  }
98 
99  obj_length = num_items * item_length;
100  if (obj_length < 1) {
101  obj_length = 1;
102  }
103 
104  /* just copy the bytes */
105  bip->count = (long)num_items;
106  bip->u.int8 = (char *)bu_malloc(obj_length, "binary uniform object");
107  memcpy(bip->u.int8, bu_fd->buf, obj_length);
108 
109  bu_close_mapped_file(bu_fd);
110 
111  /* create the rt_internal form */
112  RT_DB_INTERNAL_INIT(&intern);
113  intern.idb_major_type = major_type;
114  intern.idb_minor_type = minor_type;
115  intern.idb_ptr = (void *)bip;
116  intern.idb_meth = &OBJ[ID_BINUNIF];
117 
118  /* create body portion of external form */
119  ret = -1;
120  if (intern.idb_meth->ft_export5) {
121  ret = intern.idb_meth->ft_export5(&body, &intern, 1.0, wdbp->dbip, wdbp->wdb_resp);
122  }
123  if (ret != 0) {
124  bu_log("Error while attempting to export %s\n", obj_name);
125  rt_db_free_internal(&intern);
126  return -1;
127  }
128 
129  /* create entire external form */
130  db5_export_object3(&bin_ext, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
131  obj_name, 0, NULL, &body,
132  intern.idb_major_type, intern.idb_minor_type,
133  DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED);
134 
135  rt_db_free_internal(&intern);
136  bu_free_external(&body);
137 
138  /* make sure the database directory is initialized */
139  if (wdbp->dbip->dbi_eof == RT_DIR_PHONY_ADDR) {
140  ret = db_dirbuild(wdbp->dbip);
141  if (ret) {
142  return -1;
143  }
144  }
145 
146  /* add this (phony until written) object to the directory */
147  if ((dp=db_diradd5(wdbp->dbip, obj_name, RT_DIR_PHONY_ADDR, major_type,
148  minor_type, 0, 0, NULL)) == RT_DIR_NULL) {
149  bu_log("Error while attempting to add new name (%s) to the database",
150  obj_name);
151  bu_free_external(&bin_ext);
152  return -1;
153  }
154 
155  /* and write it to the database */
156  if (db_put_external5(&bin_ext, dp, wdbp->dbip)) {
157  bu_log("Error while adding new binary object (%s) to the database",
158  obj_name);
159  bu_free_external(&bin_ext);
160  return -1;
161  }
162 
163  bu_free_external(&bin_ext);
164 
165  return 0;
166 }
167 
168 
169 /*
170  * Local Variables:
171  * mode: C
172  * tab-width: 8
173  * indent-tabs-mode: t
174  * c-file-style: "stroustrup"
175  * End:
176  * ex: shiftwidth=4 tabstop=8
177  */
#define RT_BINUNIF_INTERNAL_MAGIC
Definition: magic.h:84
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
struct db_i * dbip
Definition: raytrace.h:1266
void bu_free_external(struct bu_external *ep)
Header file for the BRL-CAD common definitions.
union rt_binunif_internal::@9 u
int db_put_external5(struct bu_external *ep, struct directory *dp, struct db_i *dbip)
Definition: db5_io.c:744
#define ID_BINUNIF
Uniform-array binary.
Definition: raytrace.h:501
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
int idb_major_type
Definition: raytrace.h:192
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
off_t dbi_eof
PRIVATE: End+1 pos after db_scan()
Definition: raytrace.h:816
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
struct directory * db_diradd5(struct db_i *dbip, const char *name, off_t laddr, unsigned char major_type, unsigned char minor_type, unsigned char name_hidden, size_t object_length, struct bu_attribute_value_set *avs)
Definition: db5_scan.c:115
struct bu_mapped_file * bu_open_mapped_file(const char *name, const char *appl)
Definition: mappedfile.c:56
void * idb_ptr
Definition: raytrace.h:195
size_t db5_type_sizeof_h_binu(const int minor)
Definition: db5_types.c:228
const struct rt_functab OBJ[]
Definition: table.c:159
#define RT_DIR_NULL
Definition: raytrace.h:875
void bu_close_mapped_file(struct bu_mapped_file *mp)
Definition: mappedfile.c:339
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
struct resource * wdb_resp
Definition: raytrace.h:1270
int db_dirbuild(struct db_i *dbip)
Definition: db5_scan.c:301
char * file_name
Definition: fb2pix.c:40
void db5_export_object3(struct bu_external *out, int dli, const char *name, const unsigned char hidden, const struct bu_external *attrib, const struct bu_external *body, int major, int minor, int a_zzz, int b_zzz)
Definition: db5_io.c:420
int(* ft_export5)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *)
Definition: raytrace.h:2138
int rt_mk_binunif(struct rt_wdb *wdbp, const char *obj_name, const char *file_name, unsigned int minor_type, size_t max_count)
Definition: binunif.c:55
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216