1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2018-2020 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 /*
14 * in_dxf.h: read ASCII DXF to dwg
15 * written by Reini Urban
16 */
17
18 #ifndef IN_DXF_H
19 #define IN_DXF_H
20
21 #include "dwg.h"
22 #include "bits.h"
23 #include "decode.h"
24 #include "dynapi.h"
25
26 // from dwg_api
27 #ifndef _DWG_API_H_
28 BITCODE_T dwg_add_u8_input (Dwg_Data *restrict dwg,
29 const char *restrict u8str) __nonnull_all;
30 #endif
31
32 EXPORT int dwg_read_dxf (Bit_Chain *restrict dat,
33 Dwg_Data *restrict dwg) __nonnull_all;
34 EXPORT int dwg_read_dxfb (Bit_Chain *restrict dat,
35 Dwg_Data *restrict dwg) __nonnull_all;
36
37 // global array of [obj -> [fields], ...]
38 typedef struct _dxf_field
39 {
40 char *name;
41 char *type;
42 int dxf;
43 } Dxf_Field;
44
45 // to search obj ptr in array
46 /*
47 typedef struct _dxf_objs
48 {
49 Dwg_Object *obj;
50 int num_fields;
51 int size_fields;
52 Dxf_Field *fields;
53 } Dxf_Objs;
54 */
55
56 typedef struct _dxf_pair
57 {
58 short code;
59 enum RESBUF_VALUE_TYPE type;
60 union // must be big enough for setting BD
61 {
62 unsigned int u;
63 int i;
64 char *s;
65 long l;
66 uint64_t rll;
67 double d;
68 } value;
69 } Dxf_Pair;
70
71 /* We need to postpone the HEADER handles from names,
72 when we didn't read the TABLES yet, which sets the handle values.
73 Also for EED appid handles, and some object names => handle.
74 Store all handle fieldnames and string values into this array,
75 which is prefixed with the number of stored items.
76 */
77 struct array_hdl
78 {
79 char *field;
80 char *name;
81 int code; // or objid
82 };
83 typedef struct _array_hdls
84 {
85 uint32_t nitems;
86 uint32_t size; // in chunks of 16
87 struct array_hdl items[]; // Flexible array grows
88 } array_hdls;
89
90 array_hdls *array_push (array_hdls *restrict hdls, const char *restrict field,
91 const char *restrict name, const int code);
92 array_hdls *new_array_hdls (uint32_t size);
93 void free_array_hdls (array_hdls *hdls);
94
95 void dxf_add_field (Dwg_Object *restrict obj, const char *restrict name,
96 const char *restrict type, int dxf);
97 Dxf_Field *dxf_search_field (Dwg_Object *restrict obj,
98 const char *restrict name,
99 const char *restrict type, int dxf);
100 const Dwg_DYNAPI_field *find_numfield (const Dwg_DYNAPI_field *restrict fields,
101 const char *restrict key);
102 BITCODE_H find_tablehandle (Dwg_Data *restrict dwg, Dxf_Pair *restrict pair);
103 int is_table_name (const char *restrict name) __nonnull_all;
104 int is_textlike (Dwg_Object *restrict obj) __nonnull_all;
105
106 BITCODE_RC dxf_find_lweight (const int lw);
107
108 // for sscanf with BD we need to use %lf not %g
109 #undef FORMAT_BD
110 #define FORMAT_BD "%lf"
111
112 #define DWG_OBJECT(token)
113 #define DWG_ENTITY(token)
114
115 #define NEW_OBJECT(dwg, obj) \
116 { \
117 BITCODE_BL idx = dwg->num_objects; \
118 (void)dwg_add_object (dwg); \
119 obj = &dwg->object[idx]; \
120 obj->supertype = DWG_SUPERTYPE_OBJECT; \
121 obj->tio.object \
122 = (Dwg_Object_Object *)calloc (1, sizeof (Dwg_Object_Object)); \
123 obj->tio.object->objid = obj->index; \
124 obj->tio.object->dwg = dwg; \
125 }
126
127 #define NEW_ENTITY(dwg, obj) \
128 { \
129 BITCODE_BL idx = dwg->num_objects; \
130 (void)dwg_add_object (dwg); \
131 obj = &dwg->object[idx]; \
132 obj->supertype = DWG_SUPERTYPE_ENTITY; \
133 obj->tio.entity \
134 = (Dwg_Object_Entity *)calloc (1, sizeof (Dwg_Object_Entity)); \
135 obj->tio.entity->objid = obj->index; \
136 obj->tio.entity->dwg = dwg; \
137 }
138
139 #ifndef __cplusplus
140
141 # define ADD_OBJECT(token) \
142 obj->type = obj->fixedtype = DWG_TYPE_##token; \
143 obj->name = (char *)#token; \
144 obj->dxfname = dxfname; \
145 if (obj->type >= DWG_TYPE_GROUP) \
146 (void)dwg_encode_get_class (obj->parent, obj); \
147 LOG_TRACE (" ADD_OBJECT %s [%d]\n", obj->name, obj->index) \
148 _obj = calloc (1, sizeof (Dwg_Object_##token)); \
149 obj->tio.object->tio.token = (Dwg_Object_##token *)_obj; \
150 obj->tio.object->tio.token->parent = obj->tio.object; \
151 obj->tio.object->objid = obj->index
152
153 # define ADD_OBJECT1(token, tgt) ADD_OBJECT (token)
154
155 # define ADD_ENTITY(token) \
156 obj->type = obj->fixedtype = DWG_TYPE_##token; \
157 if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3)) \
158 obj->name = (char *)&#token[1]; \
159 else \
160 obj->name = (char *)#token; \
161 obj->dxfname = dxfname; \
162 if (obj->type >= DWG_TYPE_GROUP) \
163 (void)dwg_encode_get_class (obj->parent, obj); \
164 LOG_TRACE (" ADD_ENTITY %s [%d]\n", obj->name, obj->index) \
165 GCC14_DIAG_IGNORE (-Wanalyzer-allocation-size) \
166 _obj = calloc (1, sizeof (Dwg_Entity_##token)); \
167 GCC14_DIAG_RESTORE \
168 obj->tio.entity->tio.token = (Dwg_Entity_##token *)_obj; \
169 obj->tio.entity->tio.token->parent = obj->tio.entity; \
170 obj->tio.entity->objid = obj->index
171
172 #else // __cplusplus
173
174 # define ADD_OBJECT(token) \
175 obj->type = obj->fixedtype = DWG_TYPE_##token; \
176 obj->name = (char *)#token; \
177 obj->dxfname = dxfname; \
178 if (obj->type >= DWG_TYPE_GROUP) \
179 (void)dwg_encode_get_class (obj->parent, obj); \
180 LOG_TRACE (" ADD_OBJECT %s [%d]\n", obj->name, obj->index) \
181 _obj = reinterpret_cast<Dwg_Object_APPID *> ( \
182 calloc (1, sizeof (Dwg_Object_##token))); \
183 obj->tio.object->tio.token = (Dwg_Object_##token *)_obj; \
184 obj->tio.object->tio.token->parent = obj->tio.object; \
185 obj->tio.object->objid = obj->index
186
187 # define ADD_OBJECT1(token, tgt) \
188 obj->type = obj->fixedtype = DWG_TYPE_##token; \
189 obj->name = (char *)#token; \
190 obj->dxfname = dxfname; \
191 if (obj->type >= DWG_TYPE_GROUP) \
192 (void)dwg_encode_get_class (obj->parent, obj); \
193 LOG_TRACE (" ADD_OBJECT %s [%d]\n", obj->name, obj->index) \
194 _obj = reinterpret_cast<Dwg_Object_##tgt *> ( \
195 calloc (1, sizeof (Dwg_Object_##token))); \
196 obj->tio.object->tio.token = (Dwg_Object_##token *)_obj; \
197 obj->tio.object->tio.token->parent = obj->tio.object; \
198 obj->tio.object->objid = obj->index
199
200 # define ADD_ENTITY(token) \
201 obj->type = obj->fixedtype = DWG_TYPE_##token; \
202 if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3)) \
203 obj->name = (char *)&#token[1]; \
204 else \
205 obj->name = (char *)#token; \
206 obj->dxfname = dxfname; \
207 if (obj->type >= DWG_TYPE_GROUP) \
208 (void)dwg_encode_get_class (obj->parent, obj); \
209 LOG_TRACE (" ADD_ENTITY %s [%d]\n", obj->name, obj->index) \
210 _obj = reinterpret_cast<Dwg_Object_APPID *> ( \
211 (char *)calloc (1, sizeof (Dwg_Entity_##token))); \
212 obj->tio.entity->tio.token = (Dwg_Entity_##token *)_obj; \
213 obj->tio.entity->tio.token->parent = obj->tio.entity; \
214 obj->tio.entity->objid = obj->index
215
216 #endif // __cplusplus
217
218 #define ADD_TABLE_IF(nam, token) \
219 if (strEQc (name, #nam)) \
220 { \
221 ADD_OBJECT (token); \
222 }
223 #define ADD_TABLE_IF1(nam, token) \
224 if (strEQc (name, #nam)) \
225 { \
226 ADD_OBJECT1 (token, LTYPE_CONTROL); \
227 }
228
229 #define STRADD_TV(field, string) \
230 if (string) \
231 { \
232 field = (char *)malloc (strlen (string) + 1); \
233 strcpy (field, string); \
234 }
235 #define STRADD_T(field, string) \
236 if (string) \
237 { \
238 field = dwg_add_u8_input (dwg, string); \
239 }
240
241 #ifndef __cplusplus
242
243 # define UPGRADE_ENTITY(FROM, TO) \
244 obj->type = obj->fixedtype = DWG_TYPE_##TO; \
245 obj->name = (char *)#TO; \
246 free (obj->dxfname); \
247 obj->dxfname = strdup (obj->name); \
248 strcpy (name, obj->name); \
249 LOG_TRACE ("change type to %s\n", name); \
250 if (sizeof (Dwg_Entity_##TO) > sizeof (Dwg_Entity_##FROM)) \
251 { \
252 LOG_TRACE ("realloc to %s\n", name); \
253 _obj = realloc (_obj, sizeof (Dwg_Entity_##TO)); \
254 obj->tio.entity->tio.TO = (Dwg_Entity_##TO *)_obj; \
255 }
256
257 #else
258
259 # define UPGRADE_ENTITY(FROM, TO) \
260 obj->type = obj->fixedtype = DWG_TYPE_##TO; \
261 obj->name = (char *)#TO; \
262 free (obj->dxfname); \
263 obj->dxfname = strdup (obj->name); \
264 strcpy (name, obj->name); \
265 LOG_TRACE ("change type to %s\n", name); \
266 if (sizeof (Dwg_Entity_##TO) > sizeof (Dwg_Entity_##FROM)) \
267 { \
268 LOG_TRACE ("realloc to %s\n", name); \
269 _obj = reinterpret_cast<Dwg_Object_APPID *> ( \
270 (char *)realloc (_obj, sizeof (Dwg_Entity_##TO))); \
271 obj->tio.entity->tio.TO = (Dwg_Entity_##TO *)_obj; \
272 }
273
274 #endif // cplusplus
275
276 #endif