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, Dwg_Data *restrict dwg) __nonnull_all;
33 EXPORT int dwg_read_dxfb (Bit_Chain *restrict dat, Dwg_Data *restrict dwg) __nonnull_all;
34 
35 // global array of [obj -> [fields], ...]
36 typedef struct _dxf_field
37 {
38   char *name;
39   char *type;
40   int dxf;
41 } Dxf_Field;
42 
43 // to search obj ptr in array
44 /*
45 typedef struct _dxf_objs
46 {
47   Dwg_Object *obj;
48   int num_fields;
49   int size_fields;
50   Dxf_Field *fields;
51 } Dxf_Objs;
52 */
53 
54 typedef struct _dxf_pair
55 {
56   short code;
57   enum RESBUF_VALUE_TYPE type;
58   union // must be big enough for setting BD
59   {
60     unsigned int u;
61     int i;
62     char *s;
63     long l;
64     uint64_t rll;
65     double d;
66   } value;
67 } Dxf_Pair;
68 
69 /* We need to postpone the HEADER handles from names,
70    when we didn't read the TABLES yet, which sets the handle values.
71    Also for EED appid handles, and some object names => handle.
72    Store all handle fieldnames and string values into this array,
73    which is prefixed with the number of stored items.
74  */
75 struct array_hdl
76 {
77   char *field;
78   char *name;
79   int code; // or objid
80 };
81 typedef struct _array_hdls
82 {
83   uint32_t nitems;
84   uint32_t size;            // in chunks of 16
85   struct array_hdl items[]; // Flexible array grows
86 } array_hdls;
87 
88 array_hdls *array_push (array_hdls *restrict hdls, const char *restrict field,
89                         const char *restrict name, const int code);
90 array_hdls *new_array_hdls (int size);
91 void free_array_hdls (array_hdls *hdls);
92 
93 void dxf_add_field (Dwg_Object *restrict obj, const char *restrict name,
94                     const char *restrict type, int dxf);
95 Dxf_Field *dxf_search_field (Dwg_Object *restrict obj,
96                              const char *restrict name,
97                              const char *restrict type, int dxf);
98 const Dwg_DYNAPI_field *find_numfield (const Dwg_DYNAPI_field *restrict fields,
99                                        const char *restrict key);
100 BITCODE_H find_tablehandle (Dwg_Data *restrict dwg, Dxf_Pair *restrict pair);
101 int is_table_name (const char *restrict name) __nonnull_all;
102 int is_textlike (Dwg_Object *restrict obj) __nonnull_all;
103 void in_postprocess_handles (Dwg_Object *restrict obj) __nonnull_all;
104 void in_postprocess_SEQEND (Dwg_Object *restrict obj, BITCODE_BL num_owned,
105                             BITCODE_H *owned) __nonnull ((1));
106 // for in_dxf and in_json
107 unsigned in_hex2bin (unsigned char *restrict dest, char *restrict src, unsigned destlen) __nonnull_all;
108 
109 BITCODE_RC dxf_find_lweight (const int lw);
110 
111 // for sscanf with BD we need to use %lf not %g
112 #undef FORMAT_BD
113 #define FORMAT_BD "%lf"
114 
115 #define DWG_OBJECT(token)
116 #define DWG_ENTITY(token)
117 
118 #define NEW_OBJECT(dwg, obj)                                                  \
119   {                                                                           \
120     BITCODE_BL idx = dwg->num_objects;                                        \
121     (void)dwg_add_object (dwg);                                               \
122     obj = &dwg->object[idx];                                                  \
123     obj->supertype = DWG_SUPERTYPE_OBJECT;                                    \
124     obj->tio.object                                                           \
125         = (Dwg_Object_Object *)calloc (1, sizeof (Dwg_Object_Object));        \
126     obj->tio.object->objid = obj->index;                                      \
127     obj->tio.object->dwg = dwg;                                               \
128   }
129 
130 #define NEW_ENTITY(dwg, obj)                                                  \
131   {                                                                           \
132     BITCODE_BL idx = dwg->num_objects;                                        \
133     (void)dwg_add_object (dwg);                                               \
134     obj = &dwg->object[idx];                                                  \
135     obj->supertype = DWG_SUPERTYPE_ENTITY;                                    \
136     obj->tio.entity                                                           \
137         = (Dwg_Object_Entity *)calloc (1, sizeof (Dwg_Object_Entity));        \
138     obj->tio.entity->objid = obj->index;                                      \
139     obj->tio.entity->dwg = dwg;                                               \
140   }
141 
142 #define ADD_OBJECT(token)                                                     \
143   obj->type = obj->fixedtype = DWG_TYPE_##token;                              \
144   obj->name = (char *)#token;                                                 \
145   obj->dxfname = dxfname;                                                     \
146   if (obj->type >= DWG_TYPE_GROUP)                                            \
147     (void)dwg_encode_get_class (obj->parent, obj);                            \
148   LOG_TRACE ("  ADD_OBJECT %s [%d]\n", obj->name, obj->index)                 \
149   _obj = calloc (1, sizeof (Dwg_Object_##token));                             \
150   obj->tio.object->tio.token = (Dwg_Object_##token *)_obj;                    \
151   obj->tio.object->tio.token->parent = obj->tio.object;                       \
152   obj->tio.object->objid = obj->index
153 
154 #define ADD_ENTITY(token)                                                     \
155   obj->type = obj->fixedtype = DWG_TYPE_##token;                              \
156   if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3))                      \
157     obj->name = (char *)&#token[1];                                           \
158   else                                                                        \
159     obj->name = (char *)#token;                                               \
160   obj->dxfname = dxfname;                                                     \
161   if (obj->type >= DWG_TYPE_GROUP)                                            \
162     (void)dwg_encode_get_class (obj->parent, obj);                            \
163   LOG_TRACE ("  ADD_ENTITY %s [%d]\n", obj->name, obj->index)                 \
164   _obj = calloc (1, sizeof (Dwg_Entity_##token));                             \
165   obj->tio.entity->tio.token = (Dwg_Entity_##token *)_obj;                    \
166   obj->tio.entity->tio.token->parent = obj->tio.entity;                       \
167   obj->tio.entity->objid = obj->index
168 
169 #define ADD_TABLE_IF(nam, token)                                              \
170   if (strEQc (name, #nam))                                                    \
171     {                                                                         \
172       ADD_OBJECT (token);                                                     \
173     }
174 
175 #define STRADD_TV(field, string)                                              \
176   if (string)                                                                 \
177     {                                                                         \
178       field = (char*)malloc (strlen (string) + 1);                            \
179       strcpy (field, string);                                                 \
180     }
181 #define STRADD_T(field, string)                                               \
182   if (string)                                                                 \
183     {                                                                         \
184       field = dwg_add_u8_input (dwg, string);                                 \
185     }
186 
187 #define UPGRADE_ENTITY(FROM, TO)                                              \
188   obj->type = obj->fixedtype = DWG_TYPE_##TO;                                 \
189   obj->name = (char *)#TO;                                                    \
190   obj->dxfname = strdup (obj->name);                                          \
191   strcpy (name, obj->name);                                                   \
192   LOG_TRACE ("change type to %s\n", name);                                    \
193   if (sizeof (Dwg_Entity_##TO) > sizeof (Dwg_Entity_##FROM))                  \
194     {                                                                         \
195       LOG_TRACE ("realloc to %s\n", name);                                    \
196       _obj = realloc (_obj, sizeof (Dwg_Entity_##TO));                        \
197       obj->tio.entity->tio.TO = (Dwg_Entity_##TO *)_obj;                      \
198     }
199 
200 #endif
201