1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2018-2023 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 * free.c: helper functions to free all spec fields
15 * written by Reini Urban
16 * modified by Denis Pruchkovsky
17 */
18
19 #include "config.h"
20 #ifdef __STDC_ALLOC_LIB__
21 # define __STDC_WANT_LIB_EXT2__ 1 /* for strdup */
22 #else
23 # define _USE_BSD 1
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #include "common.h"
31 #include "bits.h"
32 #include "dwg.h"
33 #include "decode.h"
34 #include "free.h"
35 #include "classes.h"
36 #include "hash.h"
37 #include "free.h"
38
39 static unsigned int loglevel;
40 #ifdef USE_TRACING
41 static int env_var_checked_p;
42 #endif
43 #define DWG_LOGLEVEL loglevel
44 #include "logging.h"
45
46 /* the current version per spec block */
47 static unsigned int cur_ver = 0;
48 static Bit_Chain pdat = { 0 };
49 static BITCODE_BL rcount1, rcount2;
50
51 /*--------------------------------------------------------------------------------
52 * MACROS
53 */
54
55 #define ACTION free
56 #define IS_FREE
57
58 #define FREE_IF(ptr) \
59 { \
60 if (ptr) \
61 free (ptr); \
62 ptr = NULL; \
63 }
64
65 #undef UNTIL
66 #undef SINCE
67 #undef PRE
68 #undef VERSIONS
69 #undef VERSION
70 #define UNTIL(v) if (dat->from_version <= v)
71 #define SINCE(v) if (dat->from_version >= v)
72 #define PRE(v) if (dat->from_version < v)
73 #define VERSIONS(v1, v2) \
74 if (dat->from_version >= v1 && dat->from_version <= v2)
75 #define VERSION(v) if (dat->from_version == v)
76
77 #define VALUE(value, type, dxf)
78 #define VALUE_RC(value, dxf) VALUE (value, RC, dxf)
79 #define VALUE_RS(value, dxf) VALUE (value, RS, dxf)
80 #define VALUE_RL(value, dxf) VALUE (value, RL, dxf)
81 #define VALUE_RLx(value, dxf) VALUE (value, RL, dxf)
82 #define VALUE_RD(value, dxf) VALUE (value, RD, dxf)
83 #define VALUE_BD(value, dxf) VALUE (value, BD, dxf)
84
85 #define FIELD(name, type) \
86 { \
87 }
88 #define FIELD_TRACE(name, type) \
89 LOG_TRACE (#name ": " FORMAT_##type "\n", _obj->name)
90 #define FIELD_G_TRACE(name, type, dxfgroup) \
91 LOG_TRACE (#name ": " FORMAT_##type " [" #type " %d]\n", _obj->name, \
92 dxfgroup)
93 #define FIELD_CAST(name, type, cast, dxf) \
94 { \
95 }
96 #define SUB_FIELD_CAST(o, name, type, cast, dxf) \
97 { \
98 }
99 #define FIELD_VALUE(name) _obj->name
100 #define SUB_FIELD(o, nam, type, dxf) FIELD (_obj->o.nam, type)
101
102 #define ANYCODE -1
103 #define FIELD_HANDLE(nam, code, dxf) VALUE_HANDLE (_obj->nam, nam, code, dxf)
104 #define SUB_FIELD_HANDLE(o, nam, code, dxf) \
105 if (obj->fixedtype == DWG_TYPE_TABLESTYLE) \
106 LOG_HANDLE ("free TABLESTYLE.%s.%s\n", #o, #nam); \
107 VALUE_HANDLE (_obj->o.nam, nam, code, dxf)
108 // compare to dwg_decode_handleref_with_code: not all refs are stored in the
109 // object_ref vector, like relative ptrs and NULL.
110 // But with INDXF skip the NULL HDL, it is global and shared there.
111 // obj is the relative base object here and there.
112 #define VALUE_HANDLE(ref, nam, _code, dxf) \
113 if (ref && !ref->handleref.is_global) \
114 { \
115 free (ref); \
116 ref = NULL; \
117 } /* else freed globally */
118 #define FIELD_DATAHANDLE(name, code, dxf) FIELD_HANDLE (name, code, dxf)
119 #define FIELD_HANDLE_N(name, vcount, code, dxf) FIELD_HANDLE (name, code, dxf)
120 #define FIELD_VECTOR_INL(nam, type, size, dxf)
121 #define VALUE_H(hdl, dxf)
122
123 #define FIELD_B(name, dxf) FIELD (name, B)
124 #define FIELD_BB(name, dxf) FIELD (name, BB)
125 #define FIELD_3B(name, dxf) FIELD (name, 3B)
126 #define FIELD_BS(name, dxf) FIELD (name, BS)
127 #define FIELD_BL(name, dxf) FIELD (name, BL)
128 #define FIELD_BLL(name, dxf) FIELD (name, BLL)
129 #define FIELD_BD(name, dxf) FIELD (name, BD)
130 #define FIELD_RC(name, dxf) FIELD (name, RC)
131 #define FIELD_RS(name, dxf) FIELD (name, RS)
132 #define FIELD_RD(name, dxf) FIELD (name, RD)
133 #define FIELD_RL(name, dxf) FIELD (name, RL)
134 #define FIELD_RLL(name, dxf) FIELD (name, RLL)
135 #define FIELD_MC(name, dxf) FIELD (name, MC)
136 #define FIELD_MS(name, dxf) FIELD (name, MS)
137 #define FIELD_TV(name, dxf) FREE_IF (FIELD_VALUE (name))
138 #define VALUE_TV(value, dxf) FREE_IF (value)
139 #define VALUE_TF(value, dxf) FREE_IF (value)
140 #define VALUE_TFF(value, dxf)
141 #define FIELD_TU(name, dxf) FIELD_TV (name, dxf)
142 #define FIELD_TF(name, len, dxf) FIELD_TV (name, dxf)
143 #define FIELD_TFv(name, len, dxf) FIELD_TV (name, dxf)
144 #define FIELD_TFF(name, len, dxf) \
145 { \
146 }
147 #define FIELD_T(name, dxf) FIELD_TV (name, dxf)
148 #define FIELD_BINARY(name, len, dxf) FIELD_TV (name, dxf)
149 #define FIELD_T16(name, dxf) FIELD_TV (name, dxf)
150 #define FIELD_TU16(name, dxf) FIELD_TV (name, dxf)
151 #define FIELD_T32(name, dxf) FIELD_TV (name, dxf)
152 #define FIELD_BT(name, dxf) FIELD (name, BT);
153 #define FIELD_4BITS(name, dxf) \
154 { \
155 }
156 #define FIELD_BE(name, dxf) \
157 { \
158 }
159 #define FIELD_DD(name, _default, dxf) \
160 { \
161 }
162 #define FIELD_2DD(name, def, dxf) \
163 { \
164 }
165 #define FIELD_3DD(name, def, dxf) \
166 { \
167 }
168 #define FIELD_2RD(name, dxf) \
169 { \
170 }
171 #define FIELD_2BD(name, dxf) \
172 { \
173 }
174 #define FIELD_2BD_1(name, dxf) \
175 { \
176 }
177 #define FIELD_3RD(name, dxf) \
178 { \
179 }
180 #define FIELD_3BD(name, dxf) \
181 { \
182 }
183 #define FIELD_3BD_1(name, dxf) \
184 { \
185 }
186 #define FIELD_3DPOINT(name, dxf) \
187 { \
188 }
189 #define FIELD_2PT_TRACE(name, type, dxf) \
190 { \
191 }
192 #define FIELD_3PT_TRACE(name, type, dxf) \
193 { \
194 }
195 #define FIELD_TIMEBLL(name, dxf)
196 #define FIELD_TIMERLL(name, dxf)
197 #define FIELD_CMC(color, dxf) \
198 SINCE (R_2004) \
199 { \
200 FIELD_T (color.name, 0); \
201 FIELD_T (color.book_name, 0); \
202 }
203 #define SUB_FIELD_CMC(o, color, dxf) \
204 SINCE (R_2004) \
205 { \
206 VALUE_TV (_obj->o.color.name, 0); \
207 VALUE_TV (_obj->o.color.book_name, 0); \
208 }
209
210 // FIELD_VECTOR_N(name, type, size):
211 // reads data of the type indicated by 'type' 'size' times and stores
212 // it all in the vector called 'name'.
213 #define FIELD_VECTOR_N(nam, type, size, dxf) \
214 if ((size) && _obj->nam) \
215 { \
216 for (vcount = 0; vcount < (BITCODE_BL)(size); vcount++) \
217 FIELD_##type (nam[vcount], dxf); \
218 } \
219 FIELD_TV (nam, dxf);
220 #define FIELD_VECTOR_T(name, type, size, dxf) \
221 FIELD_VECTOR_N (name, TV, _obj->size, dxf)
222 #define FIELD_VECTOR(name, type, size, dxf) \
223 FIELD_VECTOR_N (name, type, _obj->size, dxf)
224 #define FIELD_2RD_VECTOR(name, size, dxf) FIELD_TV (name, dxf)
225 #define FIELD_2DD_VECTOR(name, size, dxf) FIELD_TV (name, dxf)
226 #define FIELD_3DPOINT_VECTOR(name, size, dxf) FIELD_TV (name, dxf)
227 #define HANDLE_VECTOR_N(name, size, code, dxf) \
228 if (_obj->name) \
229 { \
230 for (vcount = 0; vcount < (BITCODE_BL)size; vcount++) \
231 { \
232 FIELD_HANDLE_N (name[vcount], vcount, code, dxf); \
233 } \
234 FIELD_TV (name, dxf) \
235 }
236 #define HANDLE_VECTOR(name, sizefield, code, dxf) \
237 HANDLE_VECTOR_N (name, FIELD_VALUE (sizefield), code, dxf)
238 #define SUB_HANDLE_VECTOR(o, name, sizefield, code, dxf) \
239 if (_obj->o.name && _obj->o.sizefield) \
240 { \
241 for (vcount = 0; vcount < (BITCODE_BL)_obj->o.sizefield; vcount++) \
242 { \
243 SUB_FIELD_HANDLE (o, name[vcount], code, dxf); \
244 } \
245 FREE_IF (_obj->o.name) \
246 }
247 #define SUB_FIELD_VECTOR(o, nam, type, sizefield, dxf) \
248 if (_obj->o.sizefield && _obj->o.nam) \
249 { \
250 for (vcount = 0; vcount < (BITCODE_BL)(_obj->o.sizefield); vcount++) \
251 SUB_FIELD_##type (o, nam[vcount], dxf); \
252 } \
253 FREE_IF (_obj->o.nam)
254
255 #define FIELD_NUM_INSERTS(num_inserts, type, dxf)
256 #define FIELD_XDATA(name, size) dwg_free_xdata (_obj, _obj->size)
257
258 #define REACTORS(code) \
259 if (obj->tio.object->reactors) \
260 { \
261 for (vcount = 0; vcount < obj->tio.object->num_reactors; vcount++) \
262 VALUE_HANDLE (obj->tio.object->reactors[vcount], reactors, code, \
263 330); \
264 VALUE_TV (obj->tio.object->reactors, 0); \
265 }
266 #define ENT_REACTORS(code) \
267 if (_ent->reactors) \
268 { \
269 for (vcount = 0; vcount < _ent->num_reactors; vcount++) \
270 VALUE_HANDLE (_ent->reactors[vcount], reactors, code, 330); \
271 VALUE_TV (_ent->reactors, 0); \
272 }
273 #define XDICOBJHANDLE(code) \
274 SINCE (R_2004) \
275 { \
276 if (!obj->tio.object->is_xdic_missing) \
277 { \
278 VALUE_HANDLE (obj->tio.object->xdicobjhandle, xdicobjhandle, code, \
279 0); \
280 } \
281 } \
282 PRIOR_VERSIONS \
283 { \
284 VALUE_HANDLE (obj->tio.object->xdicobjhandle, xdicobjhandle, code, 0); \
285 }
286 #define ENT_XDICOBJHANDLE(code) \
287 SINCE (R_2004) \
288 { \
289 if (!_ent->is_xdic_missing) \
290 { \
291 VALUE_HANDLE (_ent->xdicobjhandle, xdicobjhandle, code, 0); \
292 } \
293 } \
294 PRIOR_VERSIONS \
295 { \
296 VALUE_HANDLE (_ent->xdicobjhandle, xdicobjhandle, code, 0); \
297 }
298
299 #define END_REPEAT(field) FIELD_TV (field, 0)
300
301 #define COMMON_ENTITY_HANDLE_DATA
302 #define SECTION_STRING_STREAM
303 #define START_STRING_STREAM
304 #define END_STRING_STREAM
305 #define START_HANDLE_STREAM
306
307 #include "spec.h"
308
309 #define DWG_ENTITY(token) \
310 static int dwg_free_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
311 Bit_Chain *str_dat, \
312 Dwg_Object *restrict obj); \
313 \
314 static int dwg_free_##token (Bit_Chain *restrict dat, \
315 Dwg_Object *restrict obj) \
316 { \
317 int error = 0; \
318 if (obj->tio.entity) \
319 { \
320 LOG_HANDLE ("Free entity " #token " [%d]\n", obj->index) \
321 if (obj->tio.entity->tio.token) \
322 error = dwg_free_##token##_private (dat, dat, dat, obj); \
323 \
324 dwg_free_common_entity_data (obj); \
325 dwg_free_eed (obj); \
326 if (obj->tio.entity) \
327 { \
328 FREE_IF (obj->tio.entity->tio.token); \
329 FREE_IF (obj->tio.entity); \
330 } \
331 } \
332 obj->parent = NULL; \
333 return error; \
334 } \
335 static int dwg_free_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
336 Bit_Chain *str_dat, \
337 Dwg_Object *restrict obj) \
338 { \
339 BITCODE_BL vcount, rcount3, rcount4; \
340 Dwg_Entity_##token *ent, *_obj; \
341 Dwg_Object_Entity *_ent; \
342 Dwg_Data *dwg = obj->parent; \
343 int error = 0; \
344 _ent = obj->tio.entity; \
345 if (!_ent) \
346 return 0; \
347 _obj = ent = _ent->tio.token;
348
349 #define DWG_ENTITY_END \
350 FREE_IF (obj->unknown_rest); \
351 return error; \
352 }
353
354 #define DWG_OBJECT(token) \
355 static int dwg_free_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
356 Bit_Chain *str_dat, \
357 Dwg_Object *restrict obj); \
358 \
359 static int dwg_free_##token (Bit_Chain *restrict dat, \
360 Dwg_Object *restrict obj) \
361 { \
362 int error = 0; \
363 Dwg_Object_##token *_obj = NULL; \
364 if (obj->tio.object) \
365 { \
366 _obj = obj->tio.object->tio.token; \
367 LOG_HANDLE ("Free object " #token " [%d]\n", obj->index) \
368 error = dwg_free_##token##_private (dat, dat, dat, obj); \
369 dwg_free_common_object_data (obj); \
370 dwg_free_eed (obj); \
371 FREE_IF (_obj); \
372 FREE_IF (obj->tio.object); \
373 } \
374 obj->parent = NULL; \
375 return error; \
376 } \
377 \
378 static int dwg_free_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
379 Bit_Chain *str_dat, \
380 Dwg_Object *restrict obj) \
381 { \
382 BITCODE_BL vcount, rcount3, rcount4; \
383 Dwg_Object_##token *_obj; \
384 Dwg_Data *dwg = obj->parent; \
385 int error = 0; \
386 if (!obj->tio.object) \
387 return 0; \
388 _obj = obj->tio.object->tio.token;
389
390 /* obj itself is allocated via dwg->object[], dxfname is klass->dxfname or
391 * static */
392 #define DWG_OBJECT_END \
393 FREE_IF (obj->unknown_rest); \
394 return error; \
395 }
396
397 static void
398 dwg_free_common_entity_data (Dwg_Object *obj)
399 {
400
401 Dwg_Data *dwg = obj->parent;
402 Bit_Chain *dat = &pdat;
403 Bit_Chain *hdl_dat = &pdat;
404 Dwg_Object_Entity *_obj;
405 Dwg_Object_Entity *_ent;
406 BITCODE_BL vcount;
407 int error = 0;
408
409 _ent = obj->tio.entity;
410 if (!_ent)
411 return;
412 _obj = _ent;
413
414 FREE_IF (_ent->preview);
415
416 // clang-format off
417 #include "common_entity_data.spec"
418 if (dat->from_version >= R_2007 && _ent->color.flag & 0x40)
419 FIELD_HANDLE (color.handle, 0, 430);
420 SINCE (R_13b1) {
421 #include "common_entity_handle_data.spec"
422 }
423 // clang-format on
424 }
425
426 static void
427 dwg_free_common_object_data (Dwg_Object *obj)
428 {
429
430 Dwg_Data *dwg = obj->parent;
431 Bit_Chain *dat = &pdat;
432 Bit_Chain *hdl_dat = &pdat;
433 Dwg_Object_Object *_obj = obj->tio.object;
434 BITCODE_BL vcount;
435 int error = 0;
436
437 // clang-format off
438 #include "common_object_handle_data.spec"
439 // clang-format on
440 }
441
442 static void
443 dwg_free_xdata (Dwg_Object_XRECORD *obj, int size)
444 {
445 dwg_free_xdata_resbuf (obj->xdata);
446 obj->xdata = NULL;
447 }
448
449 EXPORT void
450 dwg_free_eed (Dwg_Object *obj)
451 {
452 BITCODE_BL i;
453 if (obj->supertype == DWG_SUPERTYPE_ENTITY)
454 {
455 Dwg_Object_Entity *_obj = obj->tio.entity;
456 for (i = 0; i < _obj->num_eed; i++)
457 {
458 FREE_IF (_obj->eed[i].raw);
459 FREE_IF (_obj->eed[i].data);
460 }
461 FREE_IF (_obj->eed);
462 _obj->num_eed = 0;
463 }
464 else
465 {
466 Dwg_Object_Object *_obj = obj->tio.object;
467 if (!_obj || !_obj->eed)
468 return;
469 for (i = 0; i < _obj->num_eed; i++)
470 {
471 FREE_IF (_obj->eed[i].raw);
472 FREE_IF (_obj->eed[i].data);
473 }
474 FREE_IF (_obj->eed);
475 _obj->num_eed = 0;
476 }
477 }
478
479 #include "dwg.spec"
480
481 // could be a hash or switch, but there are not that many DEBUGGING classes.
482 // but a switch is fine, as we get all missing types in objects.inc, generated
483 // by regen-dynapi
484 int
485 dwg_free_variable_no_class (Dwg_Data *restrict dwg, Dwg_Object *restrict obj)
486 {
487 Bit_Chain *dat = &pdat;
488
489 #undef DWG_ENTITY
490 #undef DWG_OBJECT
491 #define FREE_NOCLASS(name) \
492 case DWG_TYPE_##name: \
493 return dwg_free_##name (dat, obj);
494 #define DWG_ENTITY(name) FREE_NOCLASS (name)
495 #define DWG_OBJECT(name) FREE_NOCLASS (name)
496
497 switch (obj->fixedtype)
498 {
499 #include "objects.inc"
500
501 case DWG_TYPE_FREED:
502 break; // already freed
503
504 case DWG_TYPE_ACDSRECORD:
505 case DWG_TYPE_ACDSSCHEMA:
506 case DWG_TYPE_NPOCOLLECTION:
507 case DWG_TYPE_XREFPANELOBJECT:
508 default:
509 LOG_ERROR ("Unhandled class %s, fixedtype %d in objects.inc",
510 dwg_type_name (obj->fixedtype), (int)obj->fixedtype);
511 }
512
513 #undef DWG_ENTITY
514 #undef DWG_OBJECT
515 #undef FREE_NOCLASS
516
517 return DWG_ERR_UNHANDLEDCLASS;
518 }
519
520 /* returns error.
521 */
522 int
523 dwg_free_variable_type (Dwg_Data *restrict dwg, Dwg_Object *restrict obj)
524 {
525 const int i = obj->type - 500;
526 Dwg_Class *klass;
527 Bit_Chain *dat = &pdat;
528
529 // no matching class
530 if (i < 0 || i >= (int)dwg->num_classes)
531 {
532 LOG_WARN ("No class for %s type %d found", obj->name, obj->type);
533 return dwg_free_variable_no_class (dwg, obj);
534 }
535
536 klass = &dwg->dwg_class[i];
537 if (!klass || !klass->dxfname || !obj->dxfname)
538 {
539 LOG_WARN ("No class for %s type %d found", obj->name, obj->type);
540 return dwg_free_variable_no_class (dwg, obj);
541 }
542
543 if (strNE (obj->dxfname, klass->dxfname))
544 {
545 // But we know how to handle the UNKNOWN_* types
546 if (obj->fixedtype == DWG_TYPE_UNKNOWN_OBJ
547 || obj->fixedtype == DWG_TYPE_UNKNOWN_ENT)
548 return DWG_ERR_UNHANDLEDCLASS;
549 else
550 {
551 LOG_ERROR ("Wrong %s.type %d for obj [%d]: != %s", obj->dxfname,
552 obj->type, obj->index, klass->dxfname);
553 return dwg_free_variable_no_class (dwg, obj);
554 }
555 }
556
557 // global class dispatcher:
558 // with indxf even DEBUGGING objects, such as TABLE are created.
559 // usually not written/encoded though.
560
561 // clang-format off
562 #include "classes.inc"
563
564 #undef WARN_UNHANDLED_CLASS
565 #undef WARN_UNSTABLE_CLASS
566 // clang-format on
567
568 LOG_WARN ("No class for %s type %d found", obj->name, obj->type);
569 return dwg_free_variable_no_class (dwg, obj);
570 }
571
572 /* returns error */
573 int
574 dwg_free_variable_type_private (Dwg_Object *restrict obj)
575 {
576 Dwg_Data *restrict dwg = obj->parent;
577 Bit_Chain *dat = &pdat;
578
579 #undef DWG_ENTITY
580 #undef DWG_OBJECT
581 #define FREE_NOCLASS(name) \
582 case DWG_TYPE_##name: \
583 return dwg_free_##name##_private (dat, dat, dat, obj);
584 #define DWG_ENTITY(name) FREE_NOCLASS (name)
585 #define DWG_OBJECT(name) FREE_NOCLASS (name)
586
587 switch (obj->fixedtype)
588 {
589 #include "objects.inc"
590
591 case DWG_TYPE_FREED:
592 break; // already freed
593
594 case DWG_TYPE_ACDSRECORD:
595 case DWG_TYPE_ACDSSCHEMA:
596 case DWG_TYPE_NPOCOLLECTION:
597 case DWG_TYPE_XREFPANELOBJECT:
598 default:
599 LOG_ERROR ("Unhandled class %s, fixedtype %d in objects.inc",
600 dwg_type_name (obj->fixedtype), (int)obj->fixedtype);
601 }
602
603 #undef DWG_ENTITY
604 #undef DWG_OBJECT
605 #undef FREE_NOCLASS
606
607 return DWG_ERR_UNHANDLEDCLASS;
608 }
609
610 // after downconvert_TABLESTYLE()
611 // we need to pass through the old code, as the new code is handled in the spec
612 // free() following from_version, not version.
613 static void
614 free_TABLESTYLE_r2010 (Bit_Chain *restrict dat, Dwg_Object *restrict obj)
615 {
616 Dwg_Object_TABLESTYLE *_obj
617 = obj->tio.object ? obj->tio.object->tio.TABLESTYLE : NULL;
618 if (!obj || obj->fixedtype != DWG_TYPE_TABLESTYLE)
619 {
620 LOG_ERROR ("Invalid fixedtype %u for free_TABLESTYLE_r2010",
621 obj ? obj->fixedtype : 0);
622 return;
623 }
624 LOG_HANDLE ("free_TABLESTYLE_r2010\n");
625 if (_obj->rowstyles)
626 for (unsigned i = 0; i < 3; i++)
627 {
628 for (unsigned j = 0; j < 6; j++)
629 {
630 SUB_FIELD_CMTC (rowstyles[i].borders[j], color, 0);
631 }
632 FREE_IF (_obj->rowstyles[i].borders);
633 SUB_FIELD_HANDLE (rowstyles[i], text_style, 5, 7);
634 SUB_FIELD_CMTC (rowstyles[i], text_color, 0);
635 SUB_FIELD_CMTC (rowstyles[i], fill_color, 0);
636 }
637 FREE_IF (_obj->rowstyles);
638 _obj->num_rowstyles = 0;
639 for (unsigned j = 0; j < _obj->sty.cellstyle.num_borders; j++)
640 {
641 SUB_FIELD_HANDLE (sty.cellstyle.borders[j], ltype, 3, 340);
642 SUB_FIELD_CMTC (sty.cellstyle.borders[j], color, 0);
643 }
644 FIELD_CMTC (sty.cellstyle.bg_color, 62);
645 FIELD_T (sty.cellstyle.content_format.value_format_string, 300);
646 if (_obj->numoverrides)
647 {
648 for (unsigned j = 0; j < _obj->ovr.cellstyle.num_borders; j++)
649 {
650 SUB_FIELD_HANDLE (ovr.cellstyle.borders[j], ltype, 3, 340);
651 SUB_FIELD_CMTC (ovr.cellstyle.borders[j], color, 0);
652 }
653 FIELD_CMTC (ovr.cellstyle.bg_color, 62);
654 FIELD_T (ovr.cellstyle.content_format.value_format_string, 300);
655 }
656 FIELD_TV (name, 3);
657 FIELD_TV (sty.name, 300);
658 FIELD_TV (ovr.name, 300);
659 }
660
661 static void
662 free_preR13_object (Dwg_Object *obj)
663 {
664 int error = 0;
665 long unsigned int j;
666 Dwg_Data *dwg;
667 Bit_Chain *dat = &pdat;
668
669 // if (obj->name)
670 // LOG_HANDLE ("free_preR13_object: %s %d\n", obj->name, obj->index)
671 if (obj && obj->parent)
672 {
673 dwg = obj->parent;
674 dat->version = dwg->header.version;
675 dat->from_version = dwg->header.from_version;
676 }
677 else
678 return;
679 if (obj->type == DWG_TYPE_FREED || obj->tio.object == NULL)
680 return;
681
682 if (obj->supertype == DWG_SUPERTYPE_ENTITY)
683 {
684 Dwg_Object_Entity *_obj = obj->tio.entity;
685 FIELD_HANDLE (layer, 2, 8);
686 if (_obj->flag_r11 & FLAG_R11_HAS_LTYPE) // 2
687 FIELD_HANDLE (ltype, 1, 6);
688 if (_obj->flag_r11 & FLAG_R11_HAS_HANDLING)
689 { // 32
690 ; // obj->handle is static
691 }
692 }
693
694 if (obj->fixedtype == DWG_TYPE_UNUSED // deleted
695 && dwg->header.version < R_2_0b && obj->type > 64)
696 {
697 obj->type = -(int8_t)obj->type;
698 // handle only entities with extra vectors specially
699 switch (obj->type)
700 {
701 case DWG_TYPE_TEXT_r11:
702 dwg_free_TEXT (dat, obj);
703 break;
704 case DWG_TYPE_ATTRIB_r11:
705 dwg_free_ATTRIB (dat, obj);
706 break;
707 case DWG_TYPE_ATTDEF_r11:
708 dwg_free_ATTDEF (dat, obj);
709 break;
710 case DWG_TYPE_BLOCK_r11:
711 dwg_free_BLOCK (dat, obj);
712 break;
713 case DWG_TYPE_INSERT_r11:
714 dwg_free_INSERT (dat, obj);
715 break;
716 case DWG_TYPE_DIMENSION_r11:
717 switch (obj->tio.entity->flag_r11)
718 {
719 case 64:
720 dwg_free_DIMENSION_LINEAR (dat, obj);
721 break;
722 case 65:
723 dwg_free_DIMENSION_ALIGNED (dat, obj);
724 break;
725 case 66:
726 dwg_free_DIMENSION_ANG2LN (dat, obj);
727 break;
728 case 68:
729 dwg_free_DIMENSION_DIAMETER (dat, obj);
730 break;
731 case 72:
732 dwg_free_DIMENSION_RADIUS (dat, obj);
733 break;
734 case 80:
735 dwg_free_DIMENSION_ANG3PT (dat, obj);
736 break;
737 case 96:
738 dwg_free_DIMENSION_ORDINATE (dat, obj);
739 break;
740 default:
741 LOG_ERROR ("Unknown preR11 %s.flag_r11 %d", obj->name,
742 obj->tio.entity->flag_r11)
743 }
744 break;
745 // now the rest
746 default:
747 dwg_free_POINT (dat, obj);
748 break;
749 }
750 }
751
752 // we could also use (Dwg_Object_Type_r11)obj->type
753 switch (obj->fixedtype)
754 {
755 case DWG_TYPE_TEXT:
756 dwg_free_TEXT (dat, obj);
757 break;
758 case DWG_TYPE_ATTRIB:
759 dwg_free_ATTRIB (dat, obj);
760 break;
761 case DWG_TYPE_ATTDEF:
762 dwg_free_ATTDEF (dat, obj);
763 break;
764 case DWG_TYPE_BLOCK:
765 dwg_free_BLOCK (dat, obj);
766 break;
767 case DWG_TYPE_ENDBLK:
768 dwg_free_ENDBLK (dat, obj);
769 break;
770 case DWG_TYPE_SEQEND:
771 dwg_free_SEQEND (dat, obj);
772 break;
773 case DWG_TYPE_REPEAT:
774 dwg_free_REPEAT (dat, obj);
775 break;
776 case DWG_TYPE_ENDREP:
777 dwg_free_ENDREP (dat, obj);
778 break;
779 case DWG_TYPE_INSERT:
780 dwg_free_INSERT (dat, obj);
781 break;
782 case DWG_TYPE_VERTEX_2D:
783 dwg_free_VERTEX_2D (dat, obj);
784 break;
785 case DWG_TYPE_VERTEX_3D:
786 dwg_free_VERTEX_3D (dat, obj);
787 break;
788 case DWG_TYPE_VERTEX_MESH:
789 dwg_free_VERTEX_MESH (dat, obj);
790 break;
791 case DWG_TYPE_VERTEX_PFACE:
792 dwg_free_VERTEX_PFACE (dat, obj);
793 break;
794 case DWG_TYPE_VERTEX_PFACE_FACE:
795 dwg_free_VERTEX_PFACE_FACE (dat, obj);
796 break;
797 case DWG_TYPE_POLYLINE_2D:
798 dwg_free_POLYLINE_2D (dat, obj);
799 break;
800 case DWG_TYPE_POLYLINE_3D:
801 dwg_free_POLYLINE_3D (dat, obj);
802 break;
803 case DWG_TYPE_POLYLINE_PFACE:
804 dwg_free_POLYLINE_PFACE (dat, obj);
805 break;
806 case DWG_TYPE_POLYLINE_MESH:
807 dwg_free_POLYLINE_MESH (dat, obj);
808 break;
809 case DWG_TYPE_ARC:
810 dwg_free_ARC (dat, obj);
811 break;
812 case DWG_TYPE_CIRCLE:
813 dwg_free_CIRCLE (dat, obj);
814 break;
815 case DWG_TYPE_LINE:
816 dwg_free_LINE (dat, obj);
817 break;
818 case DWG_TYPE_DIMENSION_ORDINATE:
819 dwg_free_DIMENSION_ORDINATE (dat, obj);
820 break;
821 case DWG_TYPE_DIMENSION_LINEAR:
822 dwg_free_DIMENSION_LINEAR (dat, obj);
823 break;
824 case DWG_TYPE_DIMENSION_ALIGNED:
825 dwg_free_DIMENSION_ALIGNED (dat, obj);
826 break;
827 case DWG_TYPE_DIMENSION_ANG3PT:
828 dwg_free_DIMENSION_ANG3PT (dat, obj);
829 break;
830 case DWG_TYPE_DIMENSION_ANG2LN:
831 dwg_free_DIMENSION_ANG2LN (dat, obj);
832 break;
833 case DWG_TYPE_DIMENSION_RADIUS:
834 dwg_free_DIMENSION_RADIUS (dat, obj);
835 break;
836 case DWG_TYPE_DIMENSION_DIAMETER:
837 dwg_free_DIMENSION_DIAMETER (dat, obj);
838 break;
839 case DWG_TYPE_POINT:
840 dwg_free_POINT (dat, obj);
841 break;
842 case DWG_TYPE__3DFACE:
843 dwg_free__3DFACE (dat, obj);
844 break;
845 case DWG_TYPE__3DLINE:
846 dwg_free__3DLINE (dat, obj);
847 break;
848 case DWG_TYPE_SOLID:
849 dwg_free_SOLID (dat, obj);
850 break;
851 case DWG_TYPE_TRACE:
852 dwg_free_TRACE (dat, obj);
853 break;
854 case DWG_TYPE_SHAPE:
855 dwg_free_SHAPE (dat, obj);
856 break;
857 case DWG_TYPE_VIEWPORT:
858 dwg_free_VIEWPORT (dat, obj);
859 break;
860 case DWG_TYPE_BLOCK_CONTROL:
861 // _ctrl->entries
862 dwg_free_BLOCK_CONTROL (dat, obj);
863 break;
864 case DWG_TYPE_BLOCK_HEADER:
865 dwg_free_BLOCK_HEADER (dat, obj);
866 break;
867 case DWG_TYPE_LAYER_CONTROL:
868 dwg_free_LAYER_CONTROL (dat, obj);
869 break;
870 case DWG_TYPE_LAYER:
871 dwg_free_LAYER (dat, obj);
872 break;
873 case DWG_TYPE_STYLE_CONTROL:
874 dwg_free_STYLE_CONTROL (dat, obj);
875 break;
876 case DWG_TYPE_STYLE:
877 dwg_free_STYLE (dat, obj);
878 break;
879 case DWG_TYPE_LTYPE_CONTROL:
880 dwg_free_LTYPE_CONTROL (dat, obj);
881 break;
882 case DWG_TYPE_LTYPE:
883 dwg_free_LTYPE (dat, obj);
884 break;
885 case DWG_TYPE_VIEW_CONTROL:
886 dwg_free_VIEW_CONTROL (dat, obj);
887 break;
888 case DWG_TYPE_VIEW:
889 dwg_free_VIEW (dat, obj);
890 break;
891 case DWG_TYPE_UCS_CONTROL:
892 dwg_free_UCS_CONTROL (dat, obj);
893 break;
894 case DWG_TYPE_UCS:
895 dwg_free_UCS (dat, obj);
896 break;
897 case DWG_TYPE_VPORT_CONTROL:
898 dwg_free_VPORT_CONTROL (dat, obj);
899 break;
900 case DWG_TYPE_VPORT:
901 dwg_free_VPORT (dat, obj);
902 break;
903 case DWG_TYPE_APPID_CONTROL:
904 dwg_free_APPID_CONTROL (dat, obj);
905 break;
906 case DWG_TYPE_APPID:
907 dwg_free_APPID (dat, obj);
908 break;
909 case DWG_TYPE_DIMSTYLE_CONTROL:
910 dwg_free_DIMSTYLE_CONTROL (dat, obj);
911 break;
912 case DWG_TYPE_DIMSTYLE:
913 dwg_free_DIMSTYLE (dat, obj);
914 break;
915 case DWG_TYPE_VX_CONTROL:
916 dwg_free_VX_CONTROL (dat, obj);
917 break;
918 case DWG_TYPE_VX_TABLE_RECORD:
919 dwg_free_VX_TABLE_RECORD (dat, obj);
920 break;
921 case DWG_TYPE_LOAD:
922 dwg_free_LOAD (dat, obj);
923 break;
924 case DWG_TYPE_JUMP:
925 dwg_free_JUMP (dat, obj);
926 break;
927 case DWG_TYPE_DICTIONARY:
928 dwg_free_DICTIONARY (dat, obj);
929 break;
930 case DWG_TYPE_UNUSED:
931 // deleted entity. leak? see above
932 break;
933 default:
934 LOG_ERROR (
935 "Unhandled preR13 class %s, fixedtype %d in free_preR13_object()",
936 dwg_type_name (obj->fixedtype), (int)obj->fixedtype);
937 }
938
939 /* With indxf and injson the dxfname is dynamic, just the name is const */
940 if (dwg->opts & DWG_OPTS_IN)
941 FREE_IF (obj->dxfname);
942 /* With injson even the name is dynamic */
943 if (dwg->opts & DWG_OPTS_INJSON)
944 FREE_IF (obj->name);
945 obj->type = DWG_TYPE_FREED;
946 }
947
948 // using the global dat
949 EXPORT void
950 dwg_free_object (Dwg_Object *obj)
951 {
952 int error = 0;
953 long unsigned int j;
954 Dwg_Data *dwg;
955 Bit_Chain *dat = &pdat;
956
957 if (obj && obj->parent)
958 {
959 dwg = obj->parent;
960 dat->version = dwg->header.version;
961 dat->from_version = dwg->header.from_version;
962 }
963 else
964 return;
965 if (obj->type == DWG_TYPE_FREED || obj->tio.object == NULL)
966 return;
967
968 PRE (R_13b1)
969 {
970 free_preR13_object (obj);
971 return;
972 }
973 if (obj->fixedtype == DWG_TYPE_TABLESTYLE
974 && dwg->header.from_version > R_2007)
975 {
976 free_TABLESTYLE_r2010 (dat, obj);
977 }
978 switch (obj->type)
979 {
980 case DWG_TYPE_TEXT:
981 dwg_free_TEXT (dat, obj);
982 break;
983 case DWG_TYPE_ATTRIB:
984 dwg_free_ATTRIB (dat, obj);
985 break;
986 case DWG_TYPE_ATTDEF:
987 dwg_free_ATTDEF (dat, obj);
988 break;
989 case DWG_TYPE_BLOCK:
990 dwg_free_BLOCK (dat, obj);
991 break;
992 case DWG_TYPE_ENDBLK:
993 dwg_free_ENDBLK (dat, obj);
994 break;
995 case DWG_TYPE_SEQEND:
996 dwg_free_SEQEND (dat, obj);
997 break;
998 case DWG_TYPE_INSERT:
999 dwg_free_INSERT (dat, obj);
1000 break;
1001 case DWG_TYPE_MINSERT:
1002 dwg_free_MINSERT (dat, obj);
1003 break;
1004 case DWG_TYPE_VERTEX_2D:
1005 dwg_free_VERTEX_2D (dat, obj);
1006 break;
1007 case DWG_TYPE_VERTEX_3D:
1008 dwg_free_VERTEX_3D (dat, obj);
1009 break;
1010 case DWG_TYPE_VERTEX_MESH:
1011 dwg_free_VERTEX_MESH (dat, obj);
1012 break;
1013 case DWG_TYPE_VERTEX_PFACE:
1014 dwg_free_VERTEX_PFACE (dat, obj);
1015 break;
1016 case DWG_TYPE_VERTEX_PFACE_FACE:
1017 dwg_free_VERTEX_PFACE_FACE (dat, obj);
1018 break;
1019 case DWG_TYPE_POLYLINE_2D:
1020 dwg_free_POLYLINE_2D (dat, obj);
1021 break;
1022 case DWG_TYPE_POLYLINE_3D:
1023 dwg_free_POLYLINE_3D (dat, obj);
1024 break;
1025 case DWG_TYPE_ARC:
1026 dwg_free_ARC (dat, obj);
1027 break;
1028 case DWG_TYPE_CIRCLE:
1029 dwg_free_CIRCLE (dat, obj);
1030 break;
1031 case DWG_TYPE_LINE:
1032 dwg_free_LINE (dat, obj);
1033 break;
1034 case DWG_TYPE_DIMENSION_ORDINATE:
1035 dwg_free_DIMENSION_ORDINATE (dat, obj);
1036 break;
1037 case DWG_TYPE_DIMENSION_LINEAR:
1038 dwg_free_DIMENSION_LINEAR (dat, obj);
1039 break;
1040 case DWG_TYPE_DIMENSION_ALIGNED:
1041 dwg_free_DIMENSION_ALIGNED (dat, obj);
1042 break;
1043 case DWG_TYPE_DIMENSION_ANG3PT:
1044 dwg_free_DIMENSION_ANG3PT (dat, obj);
1045 break;
1046 case DWG_TYPE_DIMENSION_ANG2LN:
1047 dwg_free_DIMENSION_ANG2LN (dat, obj);
1048 break;
1049 case DWG_TYPE_DIMENSION_RADIUS:
1050 dwg_free_DIMENSION_RADIUS (dat, obj);
1051 break;
1052 case DWG_TYPE_DIMENSION_DIAMETER:
1053 dwg_free_DIMENSION_DIAMETER (dat, obj);
1054 break;
1055 case DWG_TYPE_POINT:
1056 dwg_free_POINT (dat, obj);
1057 break;
1058 case DWG_TYPE__3DFACE:
1059 dwg_free__3DFACE (dat, obj);
1060 break;
1061 case DWG_TYPE_POLYLINE_PFACE:
1062 dwg_free_POLYLINE_PFACE (dat, obj);
1063 break;
1064 case DWG_TYPE_POLYLINE_MESH:
1065 dwg_free_POLYLINE_MESH (dat, obj);
1066 break;
1067 case DWG_TYPE_SOLID:
1068 dwg_free_SOLID (dat, obj);
1069 break;
1070 case DWG_TYPE_TRACE:
1071 dwg_free_TRACE (dat, obj);
1072 break;
1073 case DWG_TYPE_SHAPE:
1074 dwg_free_SHAPE (dat, obj);
1075 break;
1076 case DWG_TYPE_VIEWPORT:
1077 dwg_free_VIEWPORT (dat, obj);
1078 break;
1079 case DWG_TYPE_ELLIPSE:
1080 dwg_free_ELLIPSE (dat, obj);
1081 break;
1082 case DWG_TYPE_SPLINE:
1083 dwg_free_SPLINE (dat, obj);
1084 break;
1085 case DWG_TYPE_REGION:
1086 dwg_free_REGION (dat, obj);
1087 break;
1088 case DWG_TYPE__3DSOLID:
1089 dwg_free__3DSOLID (dat, obj);
1090 break; /* Check the type of the object */
1091 case DWG_TYPE_BODY:
1092 dwg_free_BODY (dat, obj);
1093 break;
1094 case DWG_TYPE_RAY:
1095 dwg_free_RAY (dat, obj);
1096 break;
1097 case DWG_TYPE_XLINE:
1098 dwg_free_XLINE (dat, obj);
1099 break;
1100 case DWG_TYPE_DICTIONARY:
1101 dwg_free_DICTIONARY (dat, obj);
1102 break;
1103 case DWG_TYPE_MTEXT:
1104 dwg_free_MTEXT (dat, obj);
1105 break;
1106 case DWG_TYPE_LEADER:
1107 dwg_free_LEADER (dat, obj);
1108 break;
1109 case DWG_TYPE_TOLERANCE:
1110 dwg_free_TOLERANCE (dat, obj);
1111 break;
1112 case DWG_TYPE_MLINE:
1113 dwg_free_MLINE (dat, obj);
1114 break;
1115 case DWG_TYPE_BLOCK_CONTROL:
1116 dwg_free_BLOCK_CONTROL (dat, obj);
1117 break;
1118 case DWG_TYPE_BLOCK_HEADER:
1119 dwg_free_BLOCK_HEADER (dat, obj);
1120 break;
1121 case DWG_TYPE_LAYER_CONTROL:
1122 dwg_free_LAYER_CONTROL (dat, obj);
1123 break;
1124 case DWG_TYPE_LAYER:
1125 dwg_free_LAYER (dat, obj);
1126 break;
1127 case DWG_TYPE_STYLE_CONTROL:
1128 dwg_free_STYLE_CONTROL (dat, obj);
1129 break;
1130 case DWG_TYPE_STYLE:
1131 dwg_free_STYLE (dat, obj);
1132 break;
1133 case DWG_TYPE_LTYPE_CONTROL:
1134 dwg_free_LTYPE_CONTROL (dat, obj);
1135 break;
1136 case DWG_TYPE_LTYPE:
1137 dwg_free_LTYPE (dat, obj);
1138 break;
1139 case DWG_TYPE_VIEW_CONTROL:
1140 dwg_free_VIEW_CONTROL (dat, obj);
1141 break;
1142 case DWG_TYPE_VIEW:
1143 dwg_free_VIEW (dat, obj);
1144 break;
1145 case DWG_TYPE_UCS_CONTROL:
1146 dwg_free_UCS_CONTROL (dat, obj);
1147 break;
1148 case DWG_TYPE_UCS:
1149 dwg_free_UCS (dat, obj);
1150 break;
1151 case DWG_TYPE_VPORT_CONTROL:
1152 dwg_free_VPORT_CONTROL (dat, obj);
1153 break;
1154 case DWG_TYPE_VPORT:
1155 dwg_free_VPORT (dat, obj);
1156 break;
1157 case DWG_TYPE_APPID_CONTROL:
1158 dwg_free_APPID_CONTROL (dat, obj);
1159 break;
1160 case DWG_TYPE_APPID:
1161 dwg_free_APPID (dat, obj);
1162 break;
1163 case DWG_TYPE_DIMSTYLE_CONTROL:
1164 dwg_free_DIMSTYLE_CONTROL (dat, obj);
1165 break;
1166 case DWG_TYPE_DIMSTYLE:
1167 dwg_free_DIMSTYLE (dat, obj);
1168 break;
1169 case DWG_TYPE_VX_CONTROL:
1170 dwg_free_VX_CONTROL (dat, obj);
1171 break;
1172 case DWG_TYPE_VX_TABLE_RECORD:
1173 dwg_free_VX_TABLE_RECORD (dat, obj);
1174 break;
1175 case DWG_TYPE_GROUP:
1176 dwg_free_GROUP (dat, obj);
1177 break;
1178 case DWG_TYPE_MLINESTYLE:
1179 dwg_free_MLINESTYLE (dat, obj);
1180 break;
1181 case DWG_TYPE_OLE2FRAME:
1182 dwg_free_OLE2FRAME (dat, obj);
1183 break;
1184 case DWG_TYPE_DUMMY:
1185 dwg_free_DUMMY (dat, obj);
1186 break;
1187 case DWG_TYPE_LONG_TRANSACTION:
1188 dwg_free_LONG_TRANSACTION (dat, obj);
1189 break;
1190 case DWG_TYPE_LWPOLYLINE:
1191 dwg_free_LWPOLYLINE (dat, obj);
1192 break;
1193 case DWG_TYPE_HATCH:
1194 dwg_free_HATCH (dat, obj);
1195 break;
1196 case DWG_TYPE_XRECORD:
1197 dwg_free_XRECORD (dat, obj);
1198 break;
1199 case DWG_TYPE_PLACEHOLDER:
1200 dwg_free_PLACEHOLDER (dat, obj);
1201 break;
1202 case DWG_TYPE_OLEFRAME:
1203 dwg_free_OLEFRAME (dat, obj);
1204 break;
1205 #ifdef DEBUG_VBA_PROJECT
1206 case DWG_TYPE_VBA_PROJECT:
1207 dwg_free_VBA_PROJECT (dat, obj);
1208 break;
1209 #endif
1210 case DWG_TYPE_LAYOUT:
1211 dwg_free_LAYOUT (dat, obj);
1212 break;
1213 case DWG_TYPE_PROXY_ENTITY:
1214 dwg_free_PROXY_ENTITY (dat, obj);
1215 break;
1216 case DWG_TYPE_PROXY_OBJECT:
1217 dwg_free_PROXY_OBJECT (dat, obj);
1218 break;
1219 default:
1220 if (obj->type == obj->parent->layout_type
1221 && obj->fixedtype == DWG_TYPE_LAYOUT)
1222 {
1223 SINCE (R_13b1)
1224 {
1225 dwg_free_LAYOUT (dat, obj); // XXX avoid double-free, esp. in eed
1226 }
1227 }
1228 else if ((error = dwg_free_variable_type (obj->parent, obj))
1229 & DWG_ERR_UNHANDLEDCLASS)
1230 {
1231 if (obj->fixedtype == DWG_TYPE_UNKNOWN_ENT)
1232 dwg_free_UNKNOWN_ENT (dat, obj);
1233 else if (obj->fixedtype == DWG_TYPE_UNKNOWN_OBJ)
1234 dwg_free_UNKNOWN_OBJ (dat, obj);
1235 }
1236 }
1237 /* With indxf the dxfname is dynamic, just the name is const */
1238 if ((dwg->opts & DWG_OPTS_INDXF) || (dwg->opts & DWG_OPTS_INJSON))
1239 FREE_IF (obj->dxfname);
1240 /* With injson even the name is dynamic */
1241 if (dwg->opts & DWG_OPTS_INJSON)
1242 FREE_IF (obj->name);
1243 obj->type = DWG_TYPE_FREED;
1244 }
1245
1246 /* Needed when we cast types.
1247 By fixedtype, not dxfname.
1248 */
1249 EXPORT void
1250 dwg_free_object_private (Dwg_Object *obj)
1251 {
1252 int error = 0;
1253 long unsigned int j;
1254 Dwg_Data *dwg;
1255 Bit_Chain *dat = &pdat;
1256
1257 if (obj && obj->parent)
1258 {
1259 dwg = obj->parent;
1260 dat->version = dwg->header.version;
1261 dat->from_version = dwg->header.from_version;
1262 }
1263 else
1264 return;
1265 if (obj->type == DWG_TYPE_FREED || obj->tio.object == NULL)
1266 return;
1267
1268 switch (obj->type)
1269 {
1270 case DWG_TYPE_TEXT:
1271 dwg_free_TEXT_private (dat, dat, dat, obj);
1272 break;
1273 case DWG_TYPE_ATTRIB:
1274 dwg_free_ATTRIB_private (dat, dat, dat, obj);
1275 break;
1276 case DWG_TYPE_ATTDEF:
1277 dwg_free_ATTDEF_private (dat, dat, dat, obj);
1278 break;
1279 case DWG_TYPE_BLOCK:
1280 dwg_free_BLOCK_private (dat, dat, dat, obj);
1281 break;
1282 case DWG_TYPE_ENDBLK:
1283 dwg_free_ENDBLK_private (dat, dat, dat, obj);
1284 break;
1285 case DWG_TYPE_SEQEND:
1286 dwg_free_SEQEND_private (dat, dat, dat, obj);
1287 break;
1288 case DWG_TYPE_INSERT:
1289 dwg_free_INSERT_private (dat, dat, dat, obj);
1290 break;
1291 case DWG_TYPE_MINSERT:
1292 dwg_free_MINSERT_private (dat, dat, dat, obj);
1293 break;
1294 case DWG_TYPE_VERTEX_2D:
1295 dwg_free_VERTEX_2D_private (dat, dat, dat, obj);
1296 break;
1297 case DWG_TYPE_VERTEX_3D:
1298 dwg_free_VERTEX_3D_private (dat, dat, dat, obj);
1299 break;
1300 case DWG_TYPE_VERTEX_MESH:
1301 dwg_free_VERTEX_MESH_private (dat, dat, dat, obj);
1302 break;
1303 case DWG_TYPE_VERTEX_PFACE:
1304 dwg_free_VERTEX_PFACE_private (dat, dat, dat, obj);
1305 break;
1306 case DWG_TYPE_VERTEX_PFACE_FACE:
1307 dwg_free_VERTEX_PFACE_FACE_private (dat, dat, dat, obj);
1308 break;
1309 case DWG_TYPE_POLYLINE_2D:
1310 dwg_free_POLYLINE_2D_private (dat, dat, dat, obj);
1311 break;
1312 case DWG_TYPE_POLYLINE_3D:
1313 dwg_free_POLYLINE_3D_private (dat, dat, dat, obj);
1314 break;
1315 case DWG_TYPE_ARC:
1316 dwg_free_ARC_private (dat, dat, dat, obj);
1317 break;
1318 case DWG_TYPE_CIRCLE:
1319 dwg_free_CIRCLE_private (dat, dat, dat, obj);
1320 break;
1321 case DWG_TYPE_LINE:
1322 dwg_free_LINE_private (dat, dat, dat, obj);
1323 break;
1324 case DWG_TYPE_DIMENSION_ORDINATE:
1325 dwg_free_DIMENSION_ORDINATE_private (dat, dat, dat, obj);
1326 break;
1327 case DWG_TYPE_DIMENSION_LINEAR:
1328 dwg_free_DIMENSION_LINEAR_private (dat, dat, dat, obj);
1329 break;
1330 case DWG_TYPE_DIMENSION_ALIGNED:
1331 dwg_free_DIMENSION_ALIGNED_private (dat, dat, dat, obj);
1332 break;
1333 case DWG_TYPE_DIMENSION_ANG3PT:
1334 dwg_free_DIMENSION_ANG3PT_private (dat, dat, dat, obj);
1335 break;
1336 case DWG_TYPE_DIMENSION_ANG2LN:
1337 dwg_free_DIMENSION_ANG2LN_private (dat, dat, dat, obj);
1338 break;
1339 case DWG_TYPE_DIMENSION_RADIUS:
1340 dwg_free_DIMENSION_RADIUS_private (dat, dat, dat, obj);
1341 break;
1342 case DWG_TYPE_DIMENSION_DIAMETER:
1343 dwg_free_DIMENSION_DIAMETER_private (dat, dat, dat, obj);
1344 break;
1345 case DWG_TYPE_POINT:
1346 dwg_free_POINT_private (dat, dat, dat, obj);
1347 break;
1348 case DWG_TYPE__3DFACE:
1349 dwg_free__3DFACE_private (dat, dat, dat, obj);
1350 break;
1351 case DWG_TYPE_POLYLINE_PFACE:
1352 dwg_free_POLYLINE_PFACE_private (dat, dat, dat, obj);
1353 break;
1354 case DWG_TYPE_POLYLINE_MESH:
1355 dwg_free_POLYLINE_MESH_private (dat, dat, dat, obj);
1356 break;
1357 case DWG_TYPE_SOLID:
1358 dwg_free_SOLID_private (dat, dat, dat, obj);
1359 break;
1360 case DWG_TYPE_TRACE:
1361 dwg_free_TRACE_private (dat, dat, dat, obj);
1362 break;
1363 case DWG_TYPE_SHAPE:
1364 dwg_free_SHAPE_private (dat, dat, dat, obj);
1365 break;
1366 case DWG_TYPE_VIEWPORT:
1367 dwg_free_VIEWPORT_private (dat, dat, dat, obj);
1368 break;
1369 case DWG_TYPE_ELLIPSE:
1370 dwg_free_ELLIPSE_private (dat, dat, dat, obj);
1371 break;
1372 case DWG_TYPE_SPLINE:
1373 dwg_free_SPLINE_private (dat, dat, dat, obj);
1374 break;
1375 case DWG_TYPE_REGION:
1376 dwg_free_REGION_private (dat, dat, dat, obj);
1377 break;
1378 case DWG_TYPE__3DSOLID:
1379 dwg_free__3DSOLID_private (dat, dat, dat, obj);
1380 break; /* Check the type of the object */
1381 case DWG_TYPE_BODY:
1382 dwg_free_BODY_private (dat, dat, dat, obj);
1383 break;
1384 case DWG_TYPE_RAY:
1385 dwg_free_RAY_private (dat, dat, dat, obj);
1386 break;
1387 case DWG_TYPE_XLINE:
1388 dwg_free_XLINE_private (dat, dat, dat, obj);
1389 break;
1390 case DWG_TYPE_DICTIONARY:
1391 dwg_free_DICTIONARY_private (dat, dat, dat, obj);
1392 break;
1393 case DWG_TYPE_MTEXT:
1394 dwg_free_MTEXT_private (dat, dat, dat, obj);
1395 break;
1396 case DWG_TYPE_LEADER:
1397 dwg_free_LEADER_private (dat, dat, dat, obj);
1398 break;
1399 case DWG_TYPE_TOLERANCE:
1400 dwg_free_TOLERANCE_private (dat, dat, dat, obj);
1401 break;
1402 case DWG_TYPE_MLINE:
1403 dwg_free_MLINE_private (dat, dat, dat, obj);
1404 break;
1405 case DWG_TYPE_BLOCK_CONTROL:
1406 dwg_free_BLOCK_CONTROL_private (dat, dat, dat, obj);
1407 break;
1408 case DWG_TYPE_BLOCK_HEADER:
1409 dwg_free_BLOCK_HEADER_private (dat, dat, dat, obj);
1410 break;
1411 case DWG_TYPE_LAYER_CONTROL:
1412 dwg_free_LAYER_CONTROL_private (dat, dat, dat, obj);
1413 break;
1414 case DWG_TYPE_LAYER:
1415 dwg_free_LAYER_private (dat, dat, dat, obj);
1416 break;
1417 case DWG_TYPE_STYLE_CONTROL:
1418 dwg_free_STYLE_CONTROL_private (dat, dat, dat, obj);
1419 break;
1420 case DWG_TYPE_STYLE:
1421 dwg_free_STYLE_private (dat, dat, dat, obj);
1422 break;
1423 case DWG_TYPE_LTYPE_CONTROL:
1424 dwg_free_LTYPE_CONTROL_private (dat, dat, dat, obj);
1425 break;
1426 case DWG_TYPE_LTYPE:
1427 dwg_free_LTYPE_private (dat, dat, dat, obj);
1428 break;
1429 case DWG_TYPE_VIEW_CONTROL:
1430 dwg_free_VIEW_CONTROL_private (dat, dat, dat, obj);
1431 break;
1432 case DWG_TYPE_VIEW:
1433 dwg_free_VIEW_private (dat, dat, dat, obj);
1434 break;
1435 case DWG_TYPE_UCS_CONTROL:
1436 dwg_free_UCS_CONTROL_private (dat, dat, dat, obj);
1437 break;
1438 case DWG_TYPE_UCS:
1439 dwg_free_UCS_private (dat, dat, dat, obj);
1440 break;
1441 case DWG_TYPE_VPORT_CONTROL:
1442 dwg_free_VPORT_CONTROL_private (dat, dat, dat, obj);
1443 break;
1444 case DWG_TYPE_VPORT:
1445 dwg_free_VPORT_private (dat, dat, dat, obj);
1446 break;
1447 case DWG_TYPE_APPID_CONTROL:
1448 dwg_free_APPID_CONTROL_private (dat, dat, dat, obj);
1449 break;
1450 case DWG_TYPE_APPID:
1451 dwg_free_APPID_private (dat, dat, dat, obj);
1452 break;
1453 case DWG_TYPE_DIMSTYLE_CONTROL:
1454 dwg_free_DIMSTYLE_CONTROL_private (dat, dat, dat, obj);
1455 break;
1456 case DWG_TYPE_DIMSTYLE:
1457 dwg_free_DIMSTYLE_private (dat, dat, dat, obj);
1458 break;
1459 case DWG_TYPE_VX_CONTROL:
1460 dwg_free_VX_CONTROL_private (dat, dat, dat, obj);
1461 break;
1462 case DWG_TYPE_VX_TABLE_RECORD:
1463 dwg_free_VX_TABLE_RECORD_private (dat, dat, dat, obj);
1464 break;
1465 case DWG_TYPE_GROUP:
1466 dwg_free_GROUP_private (dat, dat, dat, obj);
1467 break;
1468 case DWG_TYPE_MLINESTYLE:
1469 dwg_free_MLINESTYLE_private (dat, dat, dat, obj);
1470 break;
1471 case DWG_TYPE_OLE2FRAME:
1472 dwg_free_OLE2FRAME_private (dat, dat, dat, obj);
1473 break;
1474 case DWG_TYPE_DUMMY:
1475 dwg_free_DUMMY_private (dat, dat, dat, obj);
1476 break;
1477 case DWG_TYPE_LONG_TRANSACTION:
1478 dwg_free_LONG_TRANSACTION_private (dat, dat, dat, obj);
1479 break;
1480 case DWG_TYPE_LWPOLYLINE:
1481 dwg_free_LWPOLYLINE_private (dat, dat, dat, obj);
1482 break;
1483 case DWG_TYPE_HATCH:
1484 dwg_free_HATCH_private (dat, dat, dat, obj);
1485 break;
1486 case DWG_TYPE_XRECORD:
1487 dwg_free_XRECORD_private (dat, dat, dat, obj);
1488 break;
1489 case DWG_TYPE_PLACEHOLDER:
1490 dwg_free_PLACEHOLDER_private (dat, dat, dat, obj);
1491 break;
1492 case DWG_TYPE_OLEFRAME:
1493 dwg_free_OLEFRAME_private (dat, dat, dat, obj);
1494 break;
1495 #ifdef DEBUG_VBA_PROJECT
1496 case DWG_TYPE_VBA_PROJECT:
1497 dwg_free_VBA_PROJECT_private (dat, dat, dat, obj);
1498 break;
1499 #endif
1500 case DWG_TYPE_LAYOUT:
1501 dwg_free_LAYOUT_private (dat, dat, dat, obj);
1502 break;
1503 case DWG_TYPE_PROXY_ENTITY:
1504 dwg_free_PROXY_ENTITY_private (dat, dat, dat, obj);
1505 break;
1506 case DWG_TYPE_PROXY_OBJECT:
1507 dwg_free_PROXY_OBJECT_private (dat, dat, dat, obj);
1508 break;
1509 default:
1510 if (obj->type == obj->parent->layout_type
1511 && obj->fixedtype == DWG_TYPE_LAYOUT)
1512 {
1513 SINCE (R_13b1)
1514 {
1515 dwg_free_LAYOUT_private (
1516 dat, dat, dat, obj); // XXX avoid double-free, esp. in eed
1517 }
1518 }
1519 else
1520 dwg_free_variable_type_private (obj);
1521 }
1522 }
1523
1524 static int
1525 dwg_free_preR13_header_vars (Dwg_Data *dwg)
1526 {
1527 Dwg_Header_Variables *_obj = &dwg->header_vars;
1528 Dwg_Object *obj = NULL;
1529 Bit_Chain *dat = &pdat;
1530 int error = 0;
1531
1532 // fields added by dwg_add_Document:
1533 FIELD_TV (MENU, 0);
1534
1535 // clang-format off
1536 #include "header_variables_r11.spec"
1537 // clang-format on
1538
1539 return 0;
1540 }
1541
1542 static int
1543 dwg_free_header_vars (Dwg_Data *dwg)
1544 {
1545 Dwg_Header_Variables *_obj = &dwg->header_vars;
1546 Dwg_Object *obj = NULL;
1547 Bit_Chain *dat = &pdat;
1548
1549 // clang-format off
1550 #include "header_variables.spec"
1551 // clang-format on
1552
1553 FIELD_TV (DWGCODEPAGE, 0);
1554 return 0;
1555 }
1556
1557 static int
1558 dwg_free_summaryinfo (Dwg_Data *dwg)
1559 {
1560 Dwg_SummaryInfo *_obj = &dwg->summaryinfo;
1561 Dwg_Object *obj = NULL;
1562 Bit_Chain *dat = &pdat;
1563
1564 // clang-format off
1565 #include "summaryinfo.spec"
1566 // clang-format on
1567 return 0;
1568 }
1569
1570 static int
1571 dwg_free_appinfo (Dwg_Data *dwg)
1572 {
1573 Dwg_AppInfo *_obj = &dwg->appinfo;
1574 Dwg_Object *obj = NULL;
1575 Bit_Chain *dat = &pdat;
1576
1577 // clang-format off
1578 #include "appinfo.spec"
1579 // clang-format on
1580 return 0;
1581 }
1582 static int
1583 dwg_free_filedeplist (Dwg_Data *dwg)
1584 {
1585 Dwg_FileDepList *_obj = &dwg->filedeplist;
1586 Dwg_Object *obj = NULL;
1587 Bit_Chain *dat = &pdat;
1588 BITCODE_RL vcount;
1589
1590 // clang-format off
1591 #include "filedeplist.spec"
1592 // clang-format on
1593 return 0;
1594 }
1595 static int
1596 dwg_free_security (Dwg_Data *dwg)
1597 {
1598 Dwg_Security *_obj = &dwg->security;
1599 Dwg_Object *obj = NULL;
1600 Bit_Chain *dat = &pdat;
1601
1602 // clang-format off
1603 #include "security.spec"
1604 // clang-format on
1605 return 0;
1606 }
1607
1608 static int
1609 dwg_free_acds (Dwg_Data *dwg)
1610 {
1611 Dwg_AcDs *_obj = &dwg->acds;
1612 Dwg_Object *obj = NULL;
1613 Bit_Chain *dat = &pdat;
1614 BITCODE_RL rcount3 = 0, rcount4, vcount;
1615 int error = 0;
1616
1617 // clang-format off
1618 #include "acds.spec"
1619 // clang-format on
1620 return 0;
1621 }
1622
1623 void
1624 dwg_free (Dwg_Data *dwg)
1625 {
1626 BITCODE_BL i;
1627 if (dwg)
1628 {
1629 pdat.version = dwg->header.version;
1630 pdat.from_version = dwg->header.from_version;
1631 if (dwg->opts)
1632 {
1633 loglevel = dwg->opts & DWG_OPTS_LOGLEVEL;
1634 pdat.opts = dwg->opts;
1635 }
1636 #ifdef USE_TRACING
1637 /* Before starting, set the logging level, but only do so once. */
1638 if (!env_var_checked_p)
1639 {
1640 char *probe = getenv ("LIBREDWG_TRACE");
1641 if (probe)
1642 loglevel = atoi (probe);
1643 env_var_checked_p = 1;
1644 }
1645 #endif /* USE_TRACING */
1646 LOG_INFO ("\n============\ndwg_free\n")
1647 // copied table fields have duplicate pointers, but are freed only once
1648 for (i = 0; i < dwg->num_objects; ++i)
1649 {
1650 if (!dwg_obj_is_control (&dwg->object[i]))
1651 dwg_free_object (&dwg->object[i]);
1652 }
1653 if (dwg->header.version < R_13b1)
1654 dwg_free_preR13_header_vars (dwg);
1655 else
1656 dwg_free_header_vars (dwg);
1657 dwg_free_summaryinfo (dwg);
1658 if (dwg->header.section_infohdr.num_desc)
1659 {
1660 for (i = 0; i < dwg->header.section_infohdr.num_desc; ++i)
1661 FREE_IF (dwg->header.section_info[i].sections);
1662 FREE_IF (dwg->header.section_info);
1663 }
1664 dwg_free_appinfo (dwg);
1665 dwg_free_filedeplist (dwg);
1666 dwg_free_security (dwg);
1667 dwg_free_acds (dwg);
1668
1669 FREE_IF (dwg->thumbnail.chain);
1670 FREE_IF (dwg->vbaproject.unknown_bits);
1671 FREE_IF (dwg->revhistory.histories);
1672 FREE_IF (dwg->appinfohistory.unknown_bits);
1673 // FREE_IF (dwg->objfreespace...);
1674 FREE_IF (dwg->Template.description);
1675 FREE_IF (dwg->header.section);
1676 FREE_IF (dwg->auxheader.R11_HANDSEED);
1677
1678 for (i = 0; i < dwg->num_objects; ++i)
1679 {
1680 if (dwg_obj_is_control (&dwg->object[i]))
1681 dwg_free_object (&dwg->object[i]);
1682 }
1683 if (dwg->num_classes && dwg->dwg_class)
1684 {
1685 for (i = 0; i < dwg->num_classes; ++i)
1686 {
1687 FREE_IF (dwg->dwg_class[i].appname);
1688 FREE_IF (dwg->dwg_class[i].cppname);
1689 FREE_IF (dwg->dwg_class[i].dxfname);
1690 if (dwg->header.from_version >= R_2007)
1691 FREE_IF (dwg->dwg_class[i].dxfname_u);
1692 }
1693 }
1694 FREE_IF (dwg->dwg_class);
1695 if (dwg->object_ref)
1696 {
1697 LOG_HANDLE ("free %d global refs\n", dwg->num_object_refs)
1698 for (i = 0; i < dwg->num_object_refs; ++i)
1699 {
1700 LOG_INSANE ("free ref %d\n", i)
1701 FREE_IF (dwg->object_ref[i]);
1702 }
1703 }
1704 FREE_IF (dwg->object_ref);
1705 for (i = 0; i < dwg->num_acis_sab_hdl; ++i)
1706 {
1707 FREE_IF (dwg->acis_sab_hdl[i]);
1708 }
1709 FREE_IF (dwg->acis_sab_hdl);
1710 FREE_IF (dwg->object);
1711 if (dwg->object_map)
1712 {
1713 hash_free (dwg->object_map);
1714 dwg->object_map = NULL;
1715 }
1716 dwg->num_objects = dwg->num_classes = dwg->num_object_refs = 0;
1717 #undef FREE_IF
1718 }
1719 }
1720
1721 #undef IS_FREE