1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 * DNA handling
19 */
20
21 /** \file
22 * \ingroup DNA
23 *
24 * Lowest-level functions for decoding the parts of a saved .blend
25 * file, including interpretation of its SDNA block and conversion of
26 * contents of other parts according to the differences between that
27 * SDNA and the SDNA of the current (running) version of Blender.
28 */
29
30 #include <limits.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "MEM_guardedalloc.h" /* for MEM_freeN MEM_mallocN MEM_callocN */
36
37 #include "BLI_endian_switch.h"
38 #include "BLI_memarena.h"
39 #include "BLI_string.h"
40 #include "BLI_utildefines.h"
41
42 #include "BLI_ghash.h"
43
44 #include "DNA_genfile.h"
45 #include "DNA_sdna_types.h" /* for SDNA ;-) */
46
47 /**
48 * \section dna_genfile Overview
49 *
50 * - please note: no builtin security to detect input of double structs
51 * - if you want a struct not to be in DNA file: add two hash marks above it `(#<enter>#<enter>)`.
52 *
53 * Structure DNA data is added to each blender file and to each executable, this to detect
54 * in .blend files new variables in structs, changed array sizes, etc. It's also used for
55 * converting endian and pointer size (32-64 bits)
56 * As an extra, Python uses a call to detect run-time the contents of a blender struct.
57 *
58 * Create a structDNA: only needed when one of the input include (.h) files change.
59 * File Syntax:
60 * \code{.unparsed}
61 * SDNA (4 bytes) (magic number)
62 * NAME (4 bytes)
63 * <nr> (4 bytes) amount of names (int)
64 * <string>
65 * <string>
66 * ...
67 * ...
68 * TYPE (4 bytes)
69 * <nr> amount of types (int)
70 * <string>
71 * <string>
72 * ...
73 * ...
74 * TLEN (4 bytes)
75 * <len> (short) the lengths of types
76 * <len>
77 * ...
78 * ...
79 * STRC (4 bytes)
80 * <nr> amount of structs (int)
81 * <typenr><nr_of_elems> <typenr><namenr> <typenr><namenr> ...
82 * \endcode
83 *
84 * **Remember to read/write integer and short aligned!**
85 *
86 * While writing a file, the names of a struct is indicated with a type number,
87 * to be found with: ``type = DNA_struct_find_nr(SDNA *, const char *)``
88 * The value of ``type`` corresponds with the index within the structs array
89 *
90 * For the moment: the complete DNA file is included in a .blend file. For
91 * the future we can think of smarter methods, like only included the used
92 * structs. Only needed to keep a file short though...
93 *
94 * ALLOWED AND TESTED CHANGES IN STRUCTS:
95 * - Type change (a char to float will be divided by 255).
96 * - Location within a struct (everything can be randomly mixed up).
97 * - Struct within struct (within struct etc), this is recursive.
98 * - Adding new elements, will be default initialized zero.
99 * - Removing elements.
100 * - Change of array sizes.
101 * - Change of a pointer type: when the name doesn't change the contents is copied.
102 *
103 * NOT YET:
104 * - array (``vec[3]``) to float struct (``vec3f``).
105 *
106 * DONE:
107 * - Endian compatibility.
108 * - Pointer conversion (32-64 bits).
109 *
110 * IMPORTANT:
111 * - Do not use #defines in structs for array lengths, this cannot be read by the dna functions.
112 * - Do not use `uint`, but unsigned int instead, `ushort` and `ulong` are allowed.
113 * - Only use a long in Blender if you want this to be the size of a pointer. so it is
114 * 32 bits or 64 bits, dependent at the cpu architecture.
115 * - Chars are always unsigned
116 * - Alignment of variables has to be done in such a way, that any system does
117 * not create 'padding' (gaps) in structures. So make sure that:
118 * - short: 2 aligned.
119 * - int: 4 aligned.
120 * - float: 4 aligned.
121 * - double: 8 aligned.
122 * - long: 8 aligned.
123 * - int64: 8 aligned.
124 * - struct: 8 aligned.
125 * - the sdna functions have several error prints builtin,
126 * always check blender running from a console.
127 */
128
129 #ifdef __BIG_ENDIAN__
130 /* Big Endian */
131 # define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
132 #else
133 /* Little Endian */
134 # define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
135 #endif
136
137 /* ************************* DIV ********************** */
138
DNA_sdna_free(SDNA * sdna)139 void DNA_sdna_free(SDNA *sdna)
140 {
141 if (sdna->data_alloc) {
142 MEM_freeN((void *)sdna->data);
143 }
144
145 MEM_freeN((void *)sdna->names);
146 MEM_freeN((void *)sdna->names_array_len);
147 MEM_freeN((void *)sdna->types);
148 MEM_freeN(sdna->structs);
149
150 #ifdef WITH_DNA_GHASH
151 if (sdna->structs_map) {
152 BLI_ghash_free(sdna->structs_map, NULL, NULL);
153 }
154 #endif
155
156 if (sdna->mem_arena) {
157 BLI_memarena_free(sdna->mem_arena);
158 }
159
160 MEM_SAFE_FREE(sdna->alias.names);
161 MEM_SAFE_FREE(sdna->alias.types);
162 #ifdef WITH_DNA_GHASH
163 if (sdna->alias.structs_map) {
164 BLI_ghash_free(sdna->alias.structs_map, NULL, NULL);
165 }
166 #endif
167
168 MEM_freeN(sdna);
169 }
170
171 /**
172 * Return true if the name indicates a pointer of some kind.
173 */
ispointer(const char * name)174 static bool ispointer(const char *name)
175 {
176 /* check if pointer or function pointer */
177 return (name[0] == '*' || (name[0] == '(' && name[1] == '*'));
178 }
179
180 /**
181 * Returns the size of struct fields of the specified type and name.
182 *
183 * \param type: Index into sdna->types/types_size
184 * \param name: Index into sdna->names,
185 * needed to extract possible pointer/array information.
186 */
DNA_elem_size_nr(const SDNA * sdna,short type,short name)187 int DNA_elem_size_nr(const SDNA *sdna, short type, short name)
188 {
189 const char *cp = sdna->names[name];
190 int len = 0;
191
192 /* is it a pointer or function pointer? */
193 if (ispointer(cp)) {
194 /* has the name an extra length? (array) */
195 len = sdna->pointer_size * sdna->names_array_len[name];
196 }
197 else if (sdna->types_size[type]) {
198 /* has the name an extra length? (array) */
199 len = (int)sdna->types_size[type] * sdna->names_array_len[name];
200 }
201
202 return len;
203 }
204
205 #if 0
206 static void printstruct(SDNA *sdna, short strnr)
207 {
208 /* is for debug */
209
210 SDNA_Struct *struct_info = sdna->structs[strnr];
211 printf("struct %s\n", sdna->types[struct_info->type]);
212
213 for (int b = 0; b < struct_info->members_len; b++) {
214 SDNA_StructMember *struct_member = &struct_info->members[b];
215 printf(" %s %s\n",
216 sdna->types[struct_member->type],
217 sdna->names[struct_member->name]);
218 }
219 }
220 #endif
221
222 /**
223 * Returns the index of the struct info for the struct with the specified name.
224 */
dna_struct_find_nr_ex_impl(const char ** types,const int UNUSED (types_len),SDNA_Struct ** const structs,const int structs_len,GHash * structs_map,const char * str,unsigned int * index_last)225 static int dna_struct_find_nr_ex_impl(
226 /* From SDNA struct. */
227 const char **types,
228 const int UNUSED(types_len),
229 SDNA_Struct **const structs,
230 const int structs_len,
231 #ifdef WITH_DNA_GHASH
232 GHash *structs_map,
233 #endif
234 /* Regular args. */
235 const char *str,
236 unsigned int *index_last)
237 {
238 if (*index_last < structs_len) {
239 const SDNA_Struct *struct_info = structs[*index_last];
240 if (STREQ(types[struct_info->type], str)) {
241 return *index_last;
242 }
243 }
244
245 #ifdef WITH_DNA_GHASH
246 {
247 void **index_p = BLI_ghash_lookup_p(structs_map, str);
248 if (index_p) {
249 const int index = POINTER_AS_INT(*index_p);
250 *index_last = index;
251 return index;
252 }
253 }
254 #else
255 {
256 for (int index = 0; index < structs_len; index++) {
257 const SDNA_Struct *struct_info = structs[index];
258 if (STREQ(types[struct_info->type], str)) {
259 *index_last = index;
260 return index;
261 }
262 }
263 }
264 #endif
265 return -1;
266 }
267
268 /**
269 * Returns the index of the struct info for the struct with the specified name.
270 */
DNA_struct_find_nr_ex(const SDNA * sdna,const char * str,unsigned int * index_last)271 int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
272 {
273 return dna_struct_find_nr_ex_impl(
274 /* Expand SDNA. */
275 sdna->types,
276 sdna->types_len,
277 sdna->structs,
278 sdna->structs_len,
279 #ifdef WITH_DNA_GHASH
280 sdna->structs_map,
281 #endif
282 /* Regular args. */
283 str,
284 index_last);
285 }
286
287 /** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
DNA_struct_alias_find_nr_ex(const SDNA * sdna,const char * str,unsigned int * index_last)288 int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
289 {
290 #ifdef WITH_DNA_GHASH
291 BLI_assert(sdna->alias.structs_map != NULL);
292 #endif
293 return dna_struct_find_nr_ex_impl(
294 /* Expand SDNA. */
295 sdna->alias.types,
296 sdna->types_len,
297 sdna->structs,
298 sdna->structs_len,
299 #ifdef WITH_DNA_GHASH
300 sdna->alias.structs_map,
301 #endif
302 /* Regular args. */
303 str,
304 index_last);
305 }
306
DNA_struct_find_nr(const SDNA * sdna,const char * str)307 int DNA_struct_find_nr(const SDNA *sdna, const char *str)
308 {
309 unsigned int index_last_dummy = UINT_MAX;
310 return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy);
311 }
312
313 /** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
DNA_struct_alias_find_nr(const SDNA * sdna,const char * str)314 int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
315 {
316 unsigned int index_last_dummy = UINT_MAX;
317 return DNA_struct_alias_find_nr_ex(sdna, str, &index_last_dummy);
318 }
319
320 /* ************************* END DIV ********************** */
321
322 /* ************************* READ DNA ********************** */
323
pad_up_4(const char * ptr)324 BLI_INLINE const char *pad_up_4(const char *ptr)
325 {
326 return (const char *)((((uintptr_t)ptr) + 3) & ~3);
327 }
328
329 /**
330 * In sdna->data the data, now we convert that to something understandable
331 */
init_structDNA(SDNA * sdna,bool do_endian_swap,const char ** r_error_message)332 static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
333 {
334 int gravity_fix = -1;
335
336 int *data = (int *)sdna->data;
337
338 /* Clear pointers in case of error. */
339 sdna->names = NULL;
340 sdna->types = NULL;
341 sdna->structs = NULL;
342 #ifdef WITH_DNA_GHASH
343 sdna->structs_map = NULL;
344 #endif
345 sdna->mem_arena = NULL;
346
347 /* Lazy initialize. */
348 memset(&sdna->alias, 0, sizeof(sdna->alias));
349
350 /* Struct DNA ('SDNA') */
351 if (*data != MAKE_ID('S', 'D', 'N', 'A')) {
352 *r_error_message = "SDNA error in SDNA file";
353 return false;
354 }
355
356 const char *cp;
357
358 data++;
359 /* Names array ('NAME') */
360 if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
361 data++;
362
363 sdna->names_len = *data;
364 if (do_endian_swap) {
365 BLI_endian_switch_int32(&sdna->names_len);
366 }
367 sdna->names_len_alloc = sdna->names_len;
368
369 data++;
370 sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames");
371 }
372 else {
373 *r_error_message = "NAME error in SDNA file";
374 return false;
375 }
376
377 cp = (char *)data;
378 for (int nr = 0; nr < sdna->names_len; nr++) {
379 sdna->names[nr] = cp;
380
381 /* "float gravity [3]" was parsed wrong giving both "gravity" and
382 * "[3]" members. we rename "[3]", and later set the type of
383 * "gravity" to "void" so the offsets work out correct */
384 if (*cp == '[' && STREQ(cp, "[3]")) {
385 if (nr && STREQ(sdna->names[nr - 1], "Cvi")) {
386 sdna->names[nr] = "gravity[3]";
387 gravity_fix = nr;
388 }
389 }
390 while (*cp) {
391 cp++;
392 }
393 cp++;
394 }
395
396 cp = pad_up_4(cp);
397
398 /* Type names array ('TYPE') */
399 data = (int *)cp;
400 if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
401 data++;
402
403 sdna->types_len = *data;
404 if (do_endian_swap) {
405 BLI_endian_switch_int32(&sdna->types_len);
406 }
407
408 data++;
409 sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes");
410 }
411 else {
412 *r_error_message = "TYPE error in SDNA file";
413 return false;
414 }
415
416 cp = (char *)data;
417 for (int nr = 0; nr < sdna->types_len; nr++) {
418 /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */
419 sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp);
420 while (*cp) {
421 cp++;
422 }
423 cp++;
424 }
425
426 cp = pad_up_4(cp);
427
428 /* Type lengths array ('TLEN') */
429 data = (int *)cp;
430 short *sp;
431 if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
432 data++;
433 sp = (short *)data;
434 sdna->types_size = sp;
435
436 if (do_endian_swap) {
437 BLI_endian_switch_int16_array(sp, sdna->types_len);
438 }
439
440 sp += sdna->types_len;
441 }
442 else {
443 *r_error_message = "TLEN error in SDNA file";
444 return false;
445 }
446 /* prevent BUS error */
447 if (sdna->types_len & 1) {
448 sp++;
449 }
450
451 /* Struct array ('STRC') */
452 data = (int *)sp;
453 if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
454 data++;
455
456 sdna->structs_len = *data;
457 if (do_endian_swap) {
458 BLI_endian_switch_int32(&sdna->structs_len);
459 }
460
461 data++;
462 sdna->structs = MEM_callocN(sizeof(SDNA_Struct *) * sdna->structs_len, "sdnastrcs");
463 }
464 else {
465 *r_error_message = "STRC error in SDNA file";
466 return false;
467 }
468
469 sp = (short *)data;
470 for (int nr = 0; nr < sdna->structs_len; nr++) {
471 SDNA_Struct *struct_info = (SDNA_Struct *)sp;
472 sdna->structs[nr] = struct_info;
473
474 if (do_endian_swap) {
475 BLI_endian_switch_int16(&struct_info->type);
476 BLI_endian_switch_int16(&struct_info->members_len);
477
478 for (short a = 0; a < struct_info->members_len; a++) {
479 SDNA_StructMember *member = &struct_info->members[a];
480 BLI_endian_switch_int16(&member->type);
481 BLI_endian_switch_int16(&member->name);
482 }
483 }
484 sp += 2 + (sizeof(SDNA_StructMember) / sizeof(short)) * struct_info->members_len;
485 }
486
487 {
488 /* second part of gravity problem, setting "gravity" type to void */
489 if (gravity_fix > -1) {
490 for (int nr = 0; nr < sdna->structs_len; nr++) {
491 sp = (short *)sdna->structs[nr];
492 if (STREQ(sdna->types[sp[0]], "ClothSimSettings")) {
493 sp[10] = SDNA_TYPE_VOID;
494 }
495 }
496 }
497 }
498
499 #ifdef WITH_DNA_GHASH
500 {
501 /* create a ghash lookup to speed up */
502 sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->structs_len);
503
504 for (intptr_t nr = 0; nr < sdna->structs_len; nr++) {
505 SDNA_Struct *struct_info = sdna->structs[nr];
506 BLI_ghash_insert(
507 sdna->structs_map, (void *)sdna->types[struct_info->type], POINTER_FROM_INT(nr));
508 }
509 }
510 #endif
511
512 /* Calculate 'sdna->pointer_size' */
513 {
514 const int nr = DNA_struct_find_nr(sdna, "ListBase");
515
516 /* should never happen, only with corrupt file for example */
517 if (UNLIKELY(nr == -1)) {
518 *r_error_message = "ListBase struct error! Not found.";
519 return false;
520 }
521
522 /* finally pointer_size: use struct ListBase to test it, never change the size of it! */
523 SDNA_Struct *struct_info = sdna->structs[nr];
524 /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */
525
526 sdna->pointer_size = sdna->types_size[struct_info->type] / 2;
527
528 if (struct_info->members_len != 2 || (sdna->pointer_size != 4 && sdna->pointer_size != 8)) {
529 *r_error_message = "ListBase struct error! Needs it to calculate pointerize.";
530 /* well, at least sizeof(ListBase) is error proof! (ton) */
531 return false;
532 }
533 }
534
535 /* Cache name size. */
536 {
537 short *names_array_len = MEM_mallocN(sizeof(*names_array_len) * sdna->names_len, __func__);
538 for (int i = 0; i < sdna->names_len; i++) {
539 names_array_len[i] = DNA_elem_array_size(sdna->names[i]);
540 }
541 sdna->names_array_len = names_array_len;
542 }
543
544 return true;
545 }
546
547 /**
548 * Constructs and returns a decoded SDNA structure from the given encoded SDNA data block.
549 */
DNA_sdna_from_data(const void * data,const int data_len,bool do_endian_swap,bool data_alloc,const char ** r_error_message)550 SDNA *DNA_sdna_from_data(const void *data,
551 const int data_len,
552 bool do_endian_swap,
553 bool data_alloc,
554 const char **r_error_message)
555 {
556 SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
557 const char *error_message = NULL;
558
559 sdna->data_len = data_len;
560 if (data_alloc) {
561 char *data_copy = MEM_mallocN(data_len, "sdna_data");
562 memcpy(data_copy, data, data_len);
563 sdna->data = data_copy;
564 }
565 else {
566 sdna->data = data;
567 }
568 sdna->data_alloc = data_alloc;
569
570 if (init_structDNA(sdna, do_endian_swap, &error_message)) {
571 return sdna;
572 }
573
574 if (r_error_message == NULL) {
575 fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message);
576 }
577 else {
578 *r_error_message = error_message;
579 }
580 DNA_sdna_free(sdna);
581 return NULL;
582 }
583
584 /**
585 * Using a global is acceptable here,
586 * the data is read-only and only changes between Blender versions.
587 *
588 * So it is safe to create once and reuse.
589 */
590 static SDNA *g_sdna = NULL;
591
DNA_sdna_current_init(void)592 void DNA_sdna_current_init(void)
593 {
594 g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
595 }
596
DNA_sdna_current_get(void)597 const struct SDNA *DNA_sdna_current_get(void)
598 {
599 BLI_assert(g_sdna != NULL);
600 return g_sdna;
601 }
602
DNA_sdna_current_free(void)603 void DNA_sdna_current_free(void)
604 {
605 DNA_sdna_free(g_sdna);
606 g_sdna = NULL;
607 }
608
609 /* ******************** END READ DNA ********************** */
610
611 /* ******************* HANDLE DNA ***************** */
612
613 /**
614 * This function changes compare_flags[old_struct_index] from SDNA_CMP_UNKNOWN to something else.
615 * It might call itself recursively.
616 */
set_compare_flags_for_struct(const SDNA * oldsdna,const SDNA * newsdna,char * compare_flags,const int old_struct_index)617 static void set_compare_flags_for_struct(const SDNA *oldsdna,
618 const SDNA *newsdna,
619 char *compare_flags,
620 const int old_struct_index)
621 {
622 if (compare_flags[old_struct_index] != SDNA_CMP_UNKNOWN) {
623 /* This flag has been initialized already. */
624 return;
625 }
626
627 SDNA_Struct *old_struct = oldsdna->structs[old_struct_index];
628 const char *struct_name = oldsdna->types[old_struct->type];
629
630 const int new_struct_index = DNA_struct_find_nr(newsdna, struct_name);
631 if (new_struct_index == -1) {
632 /* Didn't find a matching new struct, so it has been removed. */
633 compare_flags[old_struct_index] = SDNA_CMP_REMOVED;
634 return;
635 }
636
637 SDNA_Struct *new_struct = newsdna->structs[new_struct_index];
638 if (old_struct->members_len != new_struct->members_len) {
639 /* Structs with a different amount of members are not equal. */
640 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
641 return;
642 }
643 if (oldsdna->types_size[old_struct->type] != newsdna->types_size[new_struct->type]) {
644 /* Structs that don't have the same size are not equal. */
645 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
646 return;
647 }
648
649 /* Compare each member individually. */
650 for (int member_index = 0; member_index < old_struct->members_len; member_index++) {
651 SDNA_StructMember *old_member = &old_struct->members[member_index];
652 SDNA_StructMember *new_member = &new_struct->members[member_index];
653
654 const char *old_type_name = oldsdna->types[old_member->type];
655 const char *new_type_name = newsdna->types[new_member->type];
656 if (!STREQ(old_type_name, new_type_name)) {
657 /* If two members have a different type in the same place, the structs are not equal. */
658 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
659 return;
660 }
661
662 const char *old_member_name = oldsdna->names[old_member->name];
663 const char *new_member_name = newsdna->names[new_member->name];
664 if (!STREQ(old_member_name, new_member_name)) {
665 /* If two members have a different name in the same place, the structs are not equal. */
666 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
667 return;
668 }
669
670 if (ispointer(old_member_name)) {
671 if (oldsdna->pointer_size != newsdna->pointer_size) {
672 /* When the struct contains a pointer, and the pointer sizes differ, the structs are not
673 * equal. */
674 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
675 return;
676 }
677 }
678 else {
679 const int old_member_struct_index = DNA_struct_find_nr(oldsdna, old_type_name);
680 if (old_member_struct_index >= 0) {
681 set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, old_member_struct_index);
682 if (compare_flags[old_member_struct_index] != SDNA_CMP_EQUAL) {
683 /* If an embedded struct is not equal, the parent struct cannot be equal either. */
684 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
685 return;
686 }
687 }
688 }
689 }
690
691 compare_flags[old_struct_index] = SDNA_CMP_EQUAL;
692 }
693
694 /**
695 * Constructs and returns an array of byte flags with one element for each struct in oldsdna,
696 * indicating how it compares to newsdna.
697 */
DNA_struct_get_compareflags(const SDNA * oldsdna,const SDNA * newsdna)698 const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
699 {
700 if (oldsdna->structs_len == 0) {
701 printf("error: file without SDNA\n");
702 return NULL;
703 }
704
705 char *compare_flags = MEM_mallocN(oldsdna->structs_len, "compare flags");
706 memset(compare_flags, SDNA_CMP_UNKNOWN, oldsdna->structs_len);
707
708 /* Set correct flag for every struct. */
709 for (int a = 0; a < oldsdna->structs_len; a++) {
710 set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, a);
711 BLI_assert(compare_flags[a] != SDNA_CMP_UNKNOWN);
712 }
713
714 /* first struct in util.h is struct Link, this is skipped in compare_flags (als # 0).
715 * was a bug, and this way dirty patched! Solve this later....
716 */
717 compare_flags[0] = SDNA_CMP_EQUAL;
718
719 /* This code can be enabled to see which structs have changed. */
720 #if 0
721 for (int a = 0; a < oldsdna->structs_len; a++) {
722 if (compare_flags[a] == SDNA_CMP_NOT_EQUAL) {
723 SDNA_Struct *struct_info = oldsdna->structs[a];
724 printf("changed: %s\n", oldsdna->types[struct_info->type]);
725 }
726 }
727 #endif
728
729 return compare_flags;
730 }
731
732 /**
733 * Converts a value of one primitive type to another.
734 *
735 * \note there is no optimization for the case where \a otype and \a ctype are the same:
736 * assumption is that caller will handle this case.
737 *
738 * \param old_type: Type to convert from.
739 * \param new_type: Type to convert to.
740 * \param array_len: Number of elements to convert.
741 * \param old_data: Buffer containing the old values.
742 * \param new_data: Buffer the converted values will be written to.
743 */
cast_primitive_type(const eSDNA_Type old_type,const eSDNA_Type new_type,const int array_len,const char * old_data,char * new_data)744 static void cast_primitive_type(const eSDNA_Type old_type,
745 const eSDNA_Type new_type,
746 const int array_len,
747 const char *old_data,
748 char *new_data)
749 {
750 /* define lengths */
751 const int oldlen = DNA_elem_type_size(old_type);
752 const int curlen = DNA_elem_type_size(new_type);
753
754 double old_value_f = 0.0;
755 uint64_t old_value_i = 0;
756
757 for (int a = 0; a < array_len; a++) {
758 switch (old_type) {
759 case SDNA_TYPE_CHAR:
760 old_value_i = *old_data;
761 old_value_f = (double)old_value_i;
762 break;
763 case SDNA_TYPE_UCHAR:
764 old_value_i = *((unsigned char *)old_data);
765 old_value_f = (double)old_value_i;
766 break;
767 case SDNA_TYPE_SHORT:
768 old_value_i = *((short *)old_data);
769 old_value_f = (double)old_value_i;
770 break;
771 case SDNA_TYPE_USHORT:
772 old_value_i = *((unsigned short *)old_data);
773 old_value_f = (double)old_value_i;
774 break;
775 case SDNA_TYPE_INT:
776 old_value_i = *((int *)old_data);
777 old_value_f = (double)old_value_i;
778 break;
779 case SDNA_TYPE_FLOAT:
780 old_value_f = *((float *)old_data);
781 old_value_i = (uint64_t)(int64_t)old_value_f;
782 break;
783 case SDNA_TYPE_DOUBLE:
784 old_value_f = *((double *)old_data);
785 old_value_i = (uint64_t)(int64_t)old_value_f;
786 break;
787 case SDNA_TYPE_INT64:
788 old_value_i = (uint64_t) * ((int64_t *)old_data);
789 old_value_f = (double)old_value_i;
790 break;
791 case SDNA_TYPE_UINT64:
792 old_value_i = *((uint64_t *)old_data);
793 old_value_f = (double)old_value_i;
794 break;
795 }
796
797 switch (new_type) {
798 case SDNA_TYPE_CHAR:
799 *new_data = (char)old_value_i;
800 break;
801 case SDNA_TYPE_UCHAR:
802 *((unsigned char *)new_data) = (unsigned char)old_value_i;
803 break;
804 case SDNA_TYPE_SHORT:
805 *((short *)new_data) = (short)old_value_i;
806 break;
807 case SDNA_TYPE_USHORT:
808 *((unsigned short *)new_data) = (unsigned short)old_value_i;
809 break;
810 case SDNA_TYPE_INT:
811 *((int *)new_data) = (int)old_value_i;
812 break;
813 case SDNA_TYPE_FLOAT:
814 if (old_type < 2) {
815 old_value_f /= 255.0;
816 }
817 *((float *)new_data) = old_value_f;
818 break;
819 case SDNA_TYPE_DOUBLE:
820 if (old_type < 2) {
821 old_value_f /= 255.0;
822 }
823 *((double *)new_data) = old_value_f;
824 break;
825 case SDNA_TYPE_INT64:
826 *((int64_t *)new_data) = (int64_t)old_value_i;
827 break;
828 case SDNA_TYPE_UINT64:
829 *((uint64_t *)new_data) = old_value_i;
830 break;
831 }
832
833 old_data += oldlen;
834 new_data += curlen;
835 }
836 }
837
cast_pointer_32_to_64(const int array_len,const uint32_t * old_data,uint64_t * new_data)838 static void cast_pointer_32_to_64(const int array_len,
839 const uint32_t *old_data,
840 uint64_t *new_data)
841 {
842 for (int a = 0; a < array_len; a++) {
843 new_data[a] = old_data[a];
844 }
845 }
846
cast_pointer_64_to_32(const int array_len,const uint64_t * old_data,uint32_t * new_data)847 static void cast_pointer_64_to_32(const int array_len,
848 const uint64_t *old_data,
849 uint32_t *new_data)
850 {
851 /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
852 * pointers may lose uniqueness on truncation! (Hopefully this wont
853 * happen unless/until we ever get to multi-gigabyte .blend files...) */
854 for (int a = 0; a < array_len; a++) {
855 new_data[a] = old_data[a] >> 3;
856 }
857 }
858
859 /**
860 * Equality test on name and oname excluding any array-size suffix.
861 */
elem_streq(const char * name,const char * oname)862 static bool elem_streq(const char *name, const char *oname)
863 {
864 int a = 0;
865
866 while (1) {
867 if (name[a] != oname[a]) {
868 return false;
869 }
870 if (name[a] == '[' || oname[a] == '[') {
871 break;
872 }
873 if (name[a] == 0 || oname[a] == 0) {
874 break;
875 }
876 a++;
877 }
878 return true;
879 }
880
881 /**
882 * Returns whether the specified field exists according to the struct format
883 * pointed to by old.
884 *
885 * \param type: Current field type name.
886 * \param name: Current field name.
887 * \param old: Pointer to struct information in sdna.
888 * \return true when existing, false otherwise..
889 */
elem_exists_impl(const char ** types,const char ** names,const char * type,const char * name,const SDNA_Struct * old)890 static bool elem_exists_impl(
891 /* Expand SDNA. */
892 const char **types,
893 const char **names,
894 /* Regular args. */
895 const char *type,
896 const char *name,
897 const SDNA_Struct *old)
898 {
899 /* in old is the old struct */
900 for (int a = 0; a < old->members_len; a++) {
901 const SDNA_StructMember *member = &old->members[a];
902 const char *otype = types[member->type];
903 const char *oname = names[member->name];
904
905 if (elem_streq(name, oname)) { /* name equal */
906 return STREQ(type, otype); /* type equal */
907 }
908 }
909 return false;
910 }
911
912 /**
913 * \param sdna: Old SDNA.
914 */
elem_exists(const SDNA * sdna,const char * type,const char * name,const SDNA_Struct * old)915 static bool elem_exists(const SDNA *sdna,
916 const char *type,
917 const char *name,
918 const SDNA_Struct *old)
919 {
920 return elem_exists_impl(
921 /* Expand SDNA. */
922 sdna->types,
923 sdna->names,
924 /* Regular args. */
925 type,
926 name,
927 old);
928 }
929
elem_exists_alias(const SDNA * sdna,const char * type,const char * name,const SDNA_Struct * old)930 static bool elem_exists_alias(const SDNA *sdna,
931 const char *type,
932 const char *name,
933 const SDNA_Struct *old)
934 {
935 return elem_exists_impl(
936 /* Expand SDNA. */
937 sdna->alias.types,
938 sdna->alias.names,
939 /* Regular args. */
940 type,
941 name,
942 old);
943 }
944
945 /**
946 * Return the offset in bytes or -1 on failure to find the struct member with its expected type.
947 *
948 * \param sdna: Old #SDNA.
949 * \param type: Current field type name.
950 * \param name: Current field name.
951 * \param old: Pointer to struct information in #SDNA.
952 * \return The offset or -1 on failure.
953 *
954 * \note Use #elem_exists if additional information provided by this function is not needed.
955 *
956 * \note We could have a version of this function that
957 * returns the #SDNA_StructMember currently it's not needed.
958 */
elem_offset(const SDNA * sdna,const char * type,const char * name,const SDNA_Struct * old)959 static int elem_offset(const SDNA *sdna,
960 const char *type,
961 const char *name,
962 const SDNA_Struct *old)
963 {
964 /* without arraypart, so names can differ: return old namenr and type */
965
966 /* in old is the old struct */
967 int offset = 0;
968 for (int a = 0; a < old->members_len; a++) {
969 const SDNA_StructMember *member = &old->members[a];
970 const char *otype = sdna->types[member->type];
971 const char *oname = sdna->names[member->name];
972 if (elem_streq(name, oname)) { /* name equal */
973 if (STREQ(type, otype)) { /* type equal */
974 return offset;
975 }
976 break; /* Fail below. */
977 }
978 offset += DNA_elem_size_nr(sdna, member->type, member->name);
979 }
980 return -1;
981 }
982
983 /* Each struct member belongs to one of the categories below. */
984 typedef enum eStructMemberCategory {
985 STRUCT_MEMBER_CATEGORY_STRUCT,
986 STRUCT_MEMBER_CATEGORY_PRIMITIVE,
987 STRUCT_MEMBER_CATEGORY_POINTER,
988 } eStructMemberCategory;
989
get_struct_member_category(const SDNA * sdna,const SDNA_StructMember * member)990 static eStructMemberCategory get_struct_member_category(const SDNA *sdna,
991 const SDNA_StructMember *member)
992 {
993 const char *member_name = sdna->names[member->name];
994 if (ispointer(member_name)) {
995 return STRUCT_MEMBER_CATEGORY_POINTER;
996 }
997 const char *member_type_name = sdna->types[member->type];
998 if (DNA_struct_find(sdna, member_type_name)) {
999 return STRUCT_MEMBER_CATEGORY_STRUCT;
1000 }
1001 return STRUCT_MEMBER_CATEGORY_PRIMITIVE;
1002 }
1003
get_member_size_in_bytes(const SDNA * sdna,const SDNA_StructMember * member)1004 static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
1005 {
1006 const char *name = sdna->names[member->name];
1007 const int array_length = sdna->names_array_len[member->name];
1008 if (ispointer(name)) {
1009 return sdna->pointer_size * array_length;
1010 }
1011 const int type_size = sdna->types_size[member->type];
1012 return type_size * array_length;
1013 }
1014
1015 /**
1016 * Does endian swapping on the fields of a struct value.
1017 *
1018 * \param sdna: SDNA of the struct_nr belongs to
1019 * \param struct_nr: Index of struct info within sdna
1020 * \param data: Struct data that is to be converted
1021 */
DNA_struct_switch_endian(const SDNA * sdna,int struct_nr,char * data)1022 void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
1023 {
1024 if (struct_nr == -1) {
1025 return;
1026 }
1027
1028 const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1029
1030 int offset_in_bytes = 0;
1031 for (int member_index = 0; member_index < struct_info->members_len; member_index++) {
1032 const SDNA_StructMember *member = &struct_info->members[member_index];
1033 const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
1034 char *member_data = data + offset_in_bytes;
1035 const char *member_type_name = sdna->types[member->type];
1036 const int member_array_length = sdna->names_array_len[member->name];
1037
1038 switch (member_category) {
1039 case STRUCT_MEMBER_CATEGORY_STRUCT: {
1040 const int substruct_size = sdna->types_size[member->type];
1041 const int substruct_nr = DNA_struct_find_nr(sdna, member_type_name);
1042 BLI_assert(substruct_nr != -1);
1043 for (int a = 0; a < member_array_length; a++) {
1044 DNA_struct_switch_endian(sdna, substruct_nr, member_data + a * substruct_size);
1045 }
1046 break;
1047 }
1048 case STRUCT_MEMBER_CATEGORY_PRIMITIVE: {
1049 switch (member->type) {
1050 case SDNA_TYPE_SHORT:
1051 case SDNA_TYPE_USHORT: {
1052 BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
1053 break;
1054 }
1055 case SDNA_TYPE_INT:
1056 case SDNA_TYPE_FLOAT: {
1057 /* Note, intentionally ignore long/ulong, because these could be 4 or 8 bytes.
1058 * Fortunately, we only use these types for runtime variables and only once for a
1059 * struct type that is no longer used. */
1060 BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
1061 break;
1062 }
1063 case SDNA_TYPE_INT64:
1064 case SDNA_TYPE_UINT64:
1065 case SDNA_TYPE_DOUBLE: {
1066 BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
1067 break;
1068 }
1069 default: {
1070 break;
1071 }
1072 }
1073 break;
1074 }
1075 case STRUCT_MEMBER_CATEGORY_POINTER: {
1076 /* See readfile.c (#bh4_from_bh8 swap endian argument),
1077 * this is only done when reducing the size of a pointer from 4 to 8. */
1078 if (sizeof(void *) < 8) {
1079 if (sdna->pointer_size == 8) {
1080 BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
1081 }
1082 }
1083 break;
1084 }
1085 }
1086 offset_in_bytes += get_member_size_in_bytes(sdna, member);
1087 }
1088 }
1089
1090 typedef enum eReconstructStepType {
1091 RECONSTRUCT_STEP_MEMCPY,
1092 RECONSTRUCT_STEP_CAST_PRIMITIVE,
1093 RECONSTRUCT_STEP_CAST_POINTER_TO_32,
1094 RECONSTRUCT_STEP_CAST_POINTER_TO_64,
1095 RECONSTRUCT_STEP_SUBSTRUCT,
1096 RECONSTRUCT_STEP_INIT_ZERO,
1097 } eReconstructStepType;
1098
1099 typedef struct ReconstructStep {
1100 eReconstructStepType type;
1101 union {
1102 struct {
1103 int old_offset;
1104 int new_offset;
1105 int size;
1106 } memcpy;
1107 struct {
1108 int old_offset;
1109 int new_offset;
1110 int array_len;
1111 eSDNA_Type old_type;
1112 eSDNA_Type new_type;
1113 } cast_primitive;
1114 struct {
1115 int old_offset;
1116 int new_offset;
1117 int array_len;
1118 } cast_pointer;
1119 struct {
1120 int old_offset;
1121 int new_offset;
1122 int array_len;
1123 short old_struct_nr;
1124 short new_struct_nr;
1125 } substruct;
1126 } data;
1127 } ReconstructStep;
1128
1129 typedef struct DNA_ReconstructInfo {
1130 const SDNA *oldsdna;
1131 const SDNA *newsdna;
1132 const char *compare_flags;
1133
1134 int *step_counts;
1135 ReconstructStep **steps;
1136 } DNA_ReconstructInfo;
1137
1138 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1139 const int blocks,
1140 const int old_struct_nr,
1141 const int new_struct_nr,
1142 const char *old_blocks,
1143 char *new_blocks);
1144
1145 /**
1146 * Converts the contents of an entire struct from oldsdna to newsdna format.
1147 *
1148 * \param reconstruct_info: Preprocessed reconstruct information generated by
1149 * #DNA_reconstruct_info_create.
1150 * \param new_struct_nr: Index in newsdna->structs of the struct that is being reconstructed.
1151 * \param old_block: Memory buffer containing the old struct.
1152 * \param new_block: Where to put converted struct contents.
1153 */
reconstruct_struct(const DNA_ReconstructInfo * reconstruct_info,const int new_struct_nr,const char * old_block,char * new_block)1154 static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info,
1155 const int new_struct_nr,
1156 const char *old_block,
1157 char *new_block)
1158 {
1159 const ReconstructStep *steps = reconstruct_info->steps[new_struct_nr];
1160 const int step_count = reconstruct_info->step_counts[new_struct_nr];
1161
1162 /* Execute all preprocessed steps. */
1163 for (int a = 0; a < step_count; a++) {
1164 const ReconstructStep *step = &steps[a];
1165 switch (step->type) {
1166 case RECONSTRUCT_STEP_MEMCPY:
1167 memcpy(new_block + step->data.memcpy.new_offset,
1168 old_block + step->data.memcpy.old_offset,
1169 step->data.memcpy.size);
1170 break;
1171 case RECONSTRUCT_STEP_CAST_PRIMITIVE:
1172 cast_primitive_type(step->data.cast_primitive.old_type,
1173 step->data.cast_primitive.new_type,
1174 step->data.cast_primitive.array_len,
1175 old_block + step->data.cast_primitive.old_offset,
1176 new_block + step->data.cast_primitive.new_offset);
1177 break;
1178 case RECONSTRUCT_STEP_CAST_POINTER_TO_32:
1179 cast_pointer_64_to_32(step->data.cast_pointer.array_len,
1180 (const uint64_t *)(old_block + step->data.cast_pointer.old_offset),
1181 (uint32_t *)(new_block + step->data.cast_pointer.new_offset));
1182 break;
1183 case RECONSTRUCT_STEP_CAST_POINTER_TO_64:
1184 cast_pointer_32_to_64(step->data.cast_pointer.array_len,
1185 (const uint32_t *)(old_block + step->data.cast_pointer.old_offset),
1186 (uint64_t *)(new_block + step->data.cast_pointer.new_offset));
1187 break;
1188 case RECONSTRUCT_STEP_SUBSTRUCT:
1189 reconstruct_structs(reconstruct_info,
1190 step->data.substruct.array_len,
1191 step->data.substruct.old_struct_nr,
1192 step->data.substruct.new_struct_nr,
1193 old_block + step->data.substruct.old_offset,
1194 new_block + step->data.substruct.new_offset);
1195 break;
1196 case RECONSTRUCT_STEP_INIT_ZERO:
1197 /* Do nothing, because the memory block has been calloced. */
1198 break;
1199 }
1200 }
1201 }
1202
1203 /** Reconstructs an array of structs. */
reconstruct_structs(const DNA_ReconstructInfo * reconstruct_info,const int blocks,const int old_struct_nr,const int new_struct_nr,const char * old_blocks,char * new_blocks)1204 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1205 const int blocks,
1206 const int old_struct_nr,
1207 const int new_struct_nr,
1208 const char *old_blocks,
1209 char *new_blocks)
1210 {
1211 const SDNA_Struct *old_struct = reconstruct_info->oldsdna->structs[old_struct_nr];
1212 const SDNA_Struct *new_struct = reconstruct_info->newsdna->structs[new_struct_nr];
1213
1214 const int old_block_size = reconstruct_info->oldsdna->types_size[old_struct->type];
1215 const int new_block_size = reconstruct_info->newsdna->types_size[new_struct->type];
1216
1217 for (int a = 0; a < blocks; a++) {
1218 const char *old_block = old_blocks + a * old_block_size;
1219 char *new_block = new_blocks + a * new_block_size;
1220 reconstruct_struct(reconstruct_info, new_struct_nr, old_block, new_block);
1221 }
1222 }
1223
1224 /**
1225 * \param reconstruct_info: Information preprocessed by #DNA_reconstruct_info_create.
1226 * \param old_struct_nr: Index of struct info within oldsdna.
1227 * \param blocks: The number of array elements.
1228 * \param old_blocks: Array of struct data.
1229 * \return An allocated reconstructed struct.
1230 */
DNA_struct_reconstruct(const DNA_ReconstructInfo * reconstruct_info,int old_struct_nr,int blocks,const void * old_blocks)1231 void *DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info,
1232 int old_struct_nr,
1233 int blocks,
1234 const void *old_blocks)
1235 {
1236 const SDNA *oldsdna = reconstruct_info->oldsdna;
1237 const SDNA *newsdna = reconstruct_info->newsdna;
1238
1239 const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1240 const char *type_name = oldsdna->types[old_struct->type];
1241 const int new_struct_nr = DNA_struct_find_nr(newsdna, type_name);
1242
1243 if (new_struct_nr == -1) {
1244 return NULL;
1245 }
1246
1247 const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1248 const int new_block_size = newsdna->types_size[new_struct->type];
1249
1250 char *new_blocks = MEM_callocN(blocks * new_block_size, "reconstruct");
1251 reconstruct_structs(
1252 reconstruct_info, blocks, old_struct_nr, new_struct_nr, old_blocks, new_blocks);
1253 return new_blocks;
1254 }
1255
1256 /** Finds a member in the given struct with the given name. */
find_member_with_matching_name(const SDNA * sdna,const SDNA_Struct * struct_info,const char * name,int * r_offset)1257 static const SDNA_StructMember *find_member_with_matching_name(const SDNA *sdna,
1258 const SDNA_Struct *struct_info,
1259 const char *name,
1260 int *r_offset)
1261 {
1262 int offset = 0;
1263 for (int a = 0; a < struct_info->members_len; a++) {
1264 const SDNA_StructMember *member = &struct_info->members[a];
1265 const char *member_name = sdna->names[member->name];
1266 if (elem_streq(name, member_name)) {
1267 *r_offset = offset;
1268 return member;
1269 }
1270 offset += get_member_size_in_bytes(sdna, member);
1271 }
1272 return NULL;
1273 }
1274
1275 /** Initializes a single reconstruct step for a member in the new struct. */
init_reconstruct_step_for_member(const SDNA * oldsdna,const SDNA * newsdna,const char * compare_flags,const SDNA_Struct * old_struct,const SDNA_StructMember * new_member,const int new_member_offset,ReconstructStep * r_step)1276 static void init_reconstruct_step_for_member(const SDNA *oldsdna,
1277 const SDNA *newsdna,
1278 const char *compare_flags,
1279 const SDNA_Struct *old_struct,
1280 const SDNA_StructMember *new_member,
1281 const int new_member_offset,
1282 ReconstructStep *r_step)
1283 {
1284
1285 /* Find the matching old member. */
1286 int old_member_offset;
1287 const char *new_name = newsdna->names[new_member->name];
1288 const SDNA_StructMember *old_member = find_member_with_matching_name(
1289 oldsdna, old_struct, new_name, &old_member_offset);
1290
1291 if (old_member == NULL) {
1292 /* No matching member has been found in the old struct. */
1293 r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1294 return;
1295 }
1296
1297 /* Determine the member category of the old an new members. */
1298 const eStructMemberCategory new_category = get_struct_member_category(newsdna, new_member);
1299 const eStructMemberCategory old_category = get_struct_member_category(oldsdna, old_member);
1300
1301 if (new_category != old_category) {
1302 /* Can only reconstruct the new member based on the old member, when the belong to the same
1303 * category. */
1304 r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1305 return;
1306 }
1307
1308 const int new_array_length = newsdna->names_array_len[new_member->name];
1309 const int old_array_length = oldsdna->names_array_len[old_member->name];
1310 const int shared_array_length = MIN2(new_array_length, old_array_length);
1311
1312 const char *new_type_name = newsdna->types[new_member->type];
1313 const char *old_type_name = oldsdna->types[old_member->type];
1314
1315 switch (new_category) {
1316 case STRUCT_MEMBER_CATEGORY_STRUCT: {
1317 if (STREQ(new_type_name, old_type_name)) {
1318 const int old_struct_nr = DNA_struct_find_nr(oldsdna, old_type_name);
1319 BLI_assert(old_struct_nr != -1);
1320 enum eSDNA_StructCompare compare_flag = compare_flags[old_struct_nr];
1321 BLI_assert(compare_flag != SDNA_CMP_REMOVED);
1322 if (compare_flag == SDNA_CMP_EQUAL) {
1323 /* The old and new members are identical, just do a memcpy. */
1324 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1325 r_step->data.memcpy.new_offset = new_member_offset;
1326 r_step->data.memcpy.old_offset = old_member_offset;
1327 r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1328 }
1329 else {
1330 const int new_struct_nr = DNA_struct_find_nr(newsdna, new_type_name);
1331 BLI_assert(new_struct_nr != -1);
1332
1333 /* The old and new members are different, use recursion to reconstruct the
1334 * nested struct. */
1335 BLI_assert(compare_flag == SDNA_CMP_NOT_EQUAL);
1336 r_step->type = RECONSTRUCT_STEP_SUBSTRUCT;
1337 r_step->data.substruct.new_offset = new_member_offset;
1338 r_step->data.substruct.old_offset = old_member_offset;
1339 r_step->data.substruct.array_len = shared_array_length;
1340 r_step->data.substruct.new_struct_nr = new_struct_nr;
1341 r_step->data.substruct.old_struct_nr = old_struct_nr;
1342 }
1343 }
1344 else {
1345 /* Cannot match structs that have different names. */
1346 r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1347 }
1348 break;
1349 }
1350 case STRUCT_MEMBER_CATEGORY_PRIMITIVE: {
1351 if (STREQ(new_type_name, old_type_name)) {
1352 /* Primitives with the same name cannot be different, so just do a memcpy. */
1353 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1354 r_step->data.memcpy.new_offset = new_member_offset;
1355 r_step->data.memcpy.old_offset = old_member_offset;
1356 r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1357 }
1358 else {
1359 /* The old and new primitive types are different, cast from the old to new type. */
1360 r_step->type = RECONSTRUCT_STEP_CAST_PRIMITIVE;
1361 r_step->data.cast_primitive.array_len = shared_array_length;
1362 r_step->data.cast_primitive.new_offset = new_member_offset;
1363 r_step->data.cast_primitive.old_offset = old_member_offset;
1364 r_step->data.cast_primitive.new_type = new_member->type;
1365 r_step->data.cast_primitive.old_type = old_member->type;
1366 }
1367 break;
1368 }
1369 case STRUCT_MEMBER_CATEGORY_POINTER: {
1370 if (newsdna->pointer_size == oldsdna->pointer_size) {
1371 /* The pointer size is the same, so just do a memcpy. */
1372 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1373 r_step->data.memcpy.new_offset = new_member_offset;
1374 r_step->data.memcpy.old_offset = old_member_offset;
1375 r_step->data.memcpy.size = newsdna->pointer_size * shared_array_length;
1376 }
1377 else if (newsdna->pointer_size == 8 && oldsdna->pointer_size == 4) {
1378 /* Need to convert from 32 bit to 64 bit pointers. */
1379 r_step->type = RECONSTRUCT_STEP_CAST_POINTER_TO_64;
1380 r_step->data.cast_pointer.new_offset = new_member_offset;
1381 r_step->data.cast_pointer.old_offset = old_member_offset;
1382 r_step->data.cast_pointer.array_len = shared_array_length;
1383 }
1384 else if (newsdna->pointer_size == 4 && oldsdna->pointer_size == 8) {
1385 /* Need to convert from 64 bit to 32 bit pointers. */
1386 r_step->type = RECONSTRUCT_STEP_CAST_POINTER_TO_32;
1387 r_step->data.cast_pointer.new_offset = new_member_offset;
1388 r_step->data.cast_pointer.old_offset = old_member_offset;
1389 r_step->data.cast_pointer.array_len = shared_array_length;
1390 }
1391 else {
1392 BLI_assert(!"invalid pointer size");
1393 r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1394 }
1395 break;
1396 }
1397 }
1398 }
1399
1400 /** Useful function when debugging the reconstruct steps. */
print_reconstruct_step(ReconstructStep * step,const SDNA * oldsdna,const SDNA * newsdna)1401 static void print_reconstruct_step(ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
1402 {
1403 switch (step->type) {
1404 case RECONSTRUCT_STEP_INIT_ZERO: {
1405 printf("init zero");
1406 break;
1407 }
1408 case RECONSTRUCT_STEP_MEMCPY: {
1409 printf("memcpy, size: %d, old offset: %d, new offset: %d",
1410 step->data.memcpy.size,
1411 step->data.memcpy.old_offset,
1412 step->data.memcpy.new_offset);
1413 break;
1414 }
1415 case RECONSTRUCT_STEP_CAST_PRIMITIVE: {
1416 printf(
1417 "cast element, old type: %d ('%s'), new type: %d ('%s'), old offset: %d, new offset: "
1418 "%d, length: %d",
1419 (int)step->data.cast_primitive.old_type,
1420 oldsdna->types[step->data.cast_primitive.old_type],
1421 (int)step->data.cast_primitive.new_type,
1422 newsdna->types[step->data.cast_primitive.new_type],
1423 step->data.cast_primitive.old_offset,
1424 step->data.cast_primitive.new_offset,
1425 step->data.cast_primitive.array_len);
1426 break;
1427 }
1428 case RECONSTRUCT_STEP_CAST_POINTER_TO_32: {
1429 printf("pointer to 32, old offset: %d, new offset: %d, length: %d",
1430 step->data.cast_pointer.old_offset,
1431 step->data.cast_pointer.new_offset,
1432 step->data.cast_pointer.array_len);
1433 break;
1434 }
1435 case RECONSTRUCT_STEP_CAST_POINTER_TO_64: {
1436 printf("pointer to 64, old offset: %d, new offset: %d, length: %d",
1437 step->data.cast_pointer.old_offset,
1438 step->data.cast_pointer.new_offset,
1439 step->data.cast_pointer.array_len);
1440 break;
1441 }
1442 case RECONSTRUCT_STEP_SUBSTRUCT: {
1443 printf(
1444 "substruct, old offset: %d, new offset: %d, new struct: %d ('%s', size per struct: %d), "
1445 "length: %d",
1446 step->data.substruct.old_offset,
1447 step->data.substruct.new_offset,
1448 step->data.substruct.new_struct_nr,
1449 newsdna->types[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1450 newsdna->types_size[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1451 step->data.substruct.array_len);
1452 break;
1453 }
1454 }
1455 }
1456
1457 /**
1458 * Generate an array of reconstruct steps for the given #new_struct. There will be one
1459 * reconstruct step for every member.
1460 */
create_reconstruct_steps_for_struct(const SDNA * oldsdna,const SDNA * newsdna,const char * compare_flags,const SDNA_Struct * old_struct,const SDNA_Struct * new_struct)1461 static ReconstructStep *create_reconstruct_steps_for_struct(const SDNA *oldsdna,
1462 const SDNA *newsdna,
1463 const char *compare_flags,
1464 const SDNA_Struct *old_struct,
1465 const SDNA_Struct *new_struct)
1466 {
1467 ReconstructStep *steps = MEM_calloc_arrayN(
1468 new_struct->members_len, sizeof(ReconstructStep), __func__);
1469
1470 int new_member_offset = 0;
1471 for (int new_member_index = 0; new_member_index < new_struct->members_len; new_member_index++) {
1472 const SDNA_StructMember *new_member = &new_struct->members[new_member_index];
1473 init_reconstruct_step_for_member(oldsdna,
1474 newsdna,
1475 compare_flags,
1476 old_struct,
1477 new_member,
1478 new_member_offset,
1479 &steps[new_member_index]);
1480 new_member_offset += get_member_size_in_bytes(newsdna, new_member);
1481 }
1482
1483 return steps;
1484 }
1485
1486 /** Compresses an array of reconstruct steps in-place and returns the new step count. */
compress_reconstruct_steps(ReconstructStep * steps,const int old_step_count)1487 static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
1488 {
1489 int new_step_count = 0;
1490 for (int a = 0; a < old_step_count; a++) {
1491 ReconstructStep *step = &steps[a];
1492 switch (step->type) {
1493 case RECONSTRUCT_STEP_INIT_ZERO:
1494 /* These steps are simply removed. */
1495 break;
1496 case RECONSTRUCT_STEP_MEMCPY:
1497 if (new_step_count > 0) {
1498 /* Try to merge this memcpy step with the previous one. */
1499 ReconstructStep *prev_step = &steps[new_step_count - 1];
1500 if (prev_step->type == RECONSTRUCT_STEP_MEMCPY) {
1501 /* Check if there are no bytes between the blocks to copy. */
1502 if (prev_step->data.memcpy.old_offset + prev_step->data.memcpy.size ==
1503 step->data.memcpy.old_offset &&
1504 prev_step->data.memcpy.new_offset + prev_step->data.memcpy.size ==
1505 step->data.memcpy.new_offset) {
1506 prev_step->data.memcpy.size += step->data.memcpy.size;
1507 break;
1508 }
1509 }
1510 }
1511 steps[new_step_count] = *step;
1512 new_step_count++;
1513 break;
1514 case RECONSTRUCT_STEP_CAST_PRIMITIVE:
1515 case RECONSTRUCT_STEP_CAST_POINTER_TO_32:
1516 case RECONSTRUCT_STEP_CAST_POINTER_TO_64:
1517 case RECONSTRUCT_STEP_SUBSTRUCT:
1518 /* These steps are not changed at all for now. It should be possible to merge consecutive
1519 * steps of the same type, but it is not really worth it. */
1520 steps[new_step_count] = *step;
1521 new_step_count++;
1522 break;
1523 }
1524 }
1525 return new_step_count;
1526 }
1527
1528 /**
1529 * Pre-process information about how structs in \a newsdna can be reconstructed from structs in
1530 * \a oldsdna. This information is then used to speedup #DNA_struct_reconstruct.
1531 */
DNA_reconstruct_info_create(const SDNA * oldsdna,const SDNA * newsdna,const char * compare_flags)1532 DNA_ReconstructInfo *DNA_reconstruct_info_create(const SDNA *oldsdna,
1533 const SDNA *newsdna,
1534 const char *compare_flags)
1535 {
1536 DNA_ReconstructInfo *reconstruct_info = MEM_callocN(sizeof(DNA_ReconstructInfo), __func__);
1537 reconstruct_info->oldsdna = oldsdna;
1538 reconstruct_info->newsdna = newsdna;
1539 reconstruct_info->compare_flags = compare_flags;
1540 reconstruct_info->step_counts = MEM_malloc_arrayN(sizeof(int), newsdna->structs_len, __func__);
1541 reconstruct_info->steps = MEM_malloc_arrayN(
1542 sizeof(ReconstructStep *), newsdna->structs_len, __func__);
1543
1544 /* Generate reconstruct steps for all structs. */
1545 for (int new_struct_nr = 0; new_struct_nr < newsdna->structs_len; new_struct_nr++) {
1546 const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1547 const char *new_struct_name = newsdna->types[new_struct->type];
1548 const int old_struct_nr = DNA_struct_find_nr(oldsdna, new_struct_name);
1549 if (old_struct_nr < 0) {
1550 reconstruct_info->steps[new_struct_nr] = NULL;
1551 reconstruct_info->step_counts[new_struct_nr] = 0;
1552 continue;
1553 }
1554 const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1555 ReconstructStep *steps = create_reconstruct_steps_for_struct(
1556 oldsdna, newsdna, compare_flags, old_struct, new_struct);
1557
1558 int steps_len = new_struct->members_len;
1559 /* Comment the line below to skip the compression for debugging purposes. */
1560 steps_len = compress_reconstruct_steps(steps, new_struct->members_len);
1561
1562 reconstruct_info->steps[new_struct_nr] = steps;
1563 reconstruct_info->step_counts[new_struct_nr] = steps_len;
1564
1565 /* This is useful when debugging the reconstruct steps. */
1566 #if 0
1567 printf("%s: \n", new_struct_name);
1568 for (int a = 0; a < steps_len; a++) {
1569 printf(" ");
1570 print_reconstruct_step(&steps[a], oldsdna, newsdna);
1571 printf("\n");
1572 }
1573 #endif
1574 UNUSED_VARS(print_reconstruct_step);
1575 }
1576
1577 return reconstruct_info;
1578 }
1579
DNA_reconstruct_info_free(DNA_ReconstructInfo * reconstruct_info)1580 void DNA_reconstruct_info_free(DNA_ReconstructInfo *reconstruct_info)
1581 {
1582 for (int a = 0; a < reconstruct_info->newsdna->structs_len; a++) {
1583 if (reconstruct_info->steps[a] != NULL) {
1584 MEM_freeN(reconstruct_info->steps[a]);
1585 }
1586 }
1587 MEM_freeN(reconstruct_info->steps);
1588 MEM_freeN(reconstruct_info->step_counts);
1589 MEM_freeN(reconstruct_info);
1590 }
1591
1592 /**
1593 * Returns the offset of the field with the specified name and type within the specified
1594 * struct type in #SDNA, -1 on failure.
1595 */
DNA_elem_offset(SDNA * sdna,const char * stype,const char * vartype,const char * name)1596 int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
1597 {
1598 const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1599 BLI_assert(SDNAnr != -1);
1600 const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1601 return elem_offset(sdna, vartype, name, spo);
1602 }
1603
DNA_struct_find(const SDNA * sdna,const char * stype)1604 bool DNA_struct_find(const SDNA *sdna, const char *stype)
1605 {
1606 return DNA_struct_find_nr(sdna, stype) != -1;
1607 }
1608
DNA_struct_elem_find(const SDNA * sdna,const char * stype,const char * vartype,const char * name)1609 bool DNA_struct_elem_find(const SDNA *sdna,
1610 const char *stype,
1611 const char *vartype,
1612 const char *name)
1613 {
1614 const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1615
1616 if (SDNAnr != -1) {
1617 const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1618 const bool found = elem_exists(sdna, vartype, name, spo);
1619
1620 if (found) {
1621 return true;
1622 }
1623 }
1624 return false;
1625 }
1626
1627 /** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
DNA_struct_alias_elem_find(const SDNA * sdna,const char * stype,const char * vartype,const char * name)1628 bool DNA_struct_alias_elem_find(const SDNA *sdna,
1629 const char *stype,
1630 const char *vartype,
1631 const char *name)
1632 {
1633 const int SDNAnr = DNA_struct_alias_find_nr(sdna, stype);
1634
1635 if (SDNAnr != -1) {
1636 const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1637 const bool found = elem_exists_alias(sdna, vartype, name, spo);
1638
1639 if (found) {
1640 return true;
1641 }
1642 }
1643 return false;
1644 }
1645
1646 /**
1647 * Returns the size in bytes of a primitive type.
1648 */
DNA_elem_type_size(const eSDNA_Type elem_nr)1649 int DNA_elem_type_size(const eSDNA_Type elem_nr)
1650 {
1651 /* should contain all enum types */
1652 switch (elem_nr) {
1653 case SDNA_TYPE_CHAR:
1654 case SDNA_TYPE_UCHAR:
1655 return 1;
1656 case SDNA_TYPE_SHORT:
1657 case SDNA_TYPE_USHORT:
1658 return 2;
1659 case SDNA_TYPE_INT:
1660 case SDNA_TYPE_FLOAT:
1661 return 4;
1662 case SDNA_TYPE_DOUBLE:
1663 case SDNA_TYPE_INT64:
1664 case SDNA_TYPE_UINT64:
1665 return 8;
1666 }
1667
1668 /* weak */
1669 return 8;
1670 }
1671
1672 /* -------------------------------------------------------------------- */
1673 /** \name Version Patch DNA
1674 * \{ */
1675
DNA_sdna_patch_struct_nr(SDNA * sdna,const int struct_name_old_nr,const char * struct_name_new)1676 static bool DNA_sdna_patch_struct_nr(SDNA *sdna,
1677 const int struct_name_old_nr,
1678 const char *struct_name_new)
1679 {
1680 BLI_assert(DNA_struct_find_nr(DNA_sdna_current_get(), struct_name_new) != -1);
1681 const SDNA_Struct *struct_info = sdna->structs[struct_name_old_nr];
1682 #ifdef WITH_DNA_GHASH
1683 BLI_ghash_remove(sdna->structs_map, (void *)sdna->types[struct_info->type], NULL, NULL);
1684 BLI_ghash_insert(
1685 sdna->structs_map, (void *)struct_name_new, POINTER_FROM_INT(struct_name_old_nr));
1686 #endif
1687 sdna->types[struct_info->type] = struct_name_new;
1688 return true;
1689 }
1690 /**
1691 * Rename a struct
1692 */
DNA_sdna_patch_struct(SDNA * sdna,const char * struct_name_old,const char * struct_name_new)1693 bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new)
1694 {
1695 const int struct_name_old_nr = DNA_struct_find_nr(sdna, struct_name_old);
1696 if (struct_name_old_nr != -1) {
1697 return DNA_sdna_patch_struct_nr(sdna, struct_name_old_nr, struct_name_new);
1698 }
1699 return false;
1700 }
1701
1702 /* Make public if called often with same struct (avoid duplicate look-ups). */
DNA_sdna_patch_struct_member_nr(SDNA * sdna,const int struct_name_nr,const char * elem_old,const char * elem_new)1703 static bool DNA_sdna_patch_struct_member_nr(SDNA *sdna,
1704 const int struct_name_nr,
1705 const char *elem_old,
1706 const char *elem_new)
1707 {
1708 /* These names aren't handled here (it's not used).
1709 * Ensure they are never used or we get out of sync arrays. */
1710 BLI_assert(sdna->alias.names == NULL);
1711 const int elem_old_len = strlen(elem_old);
1712 const int elem_new_len = strlen(elem_new);
1713 BLI_assert(elem_new != NULL);
1714 SDNA_Struct *sp = sdna->structs[struct_name_nr];
1715 for (int elem_index = sp->members_len; elem_index > 0; elem_index--) {
1716 SDNA_StructMember *member = &sp->members[elem_index];
1717 const char *elem_old_full = sdna->names[member->name];
1718 /* Start & end offsets in 'elem_old_full'. */
1719 uint elem_old_full_offset_start;
1720 if (DNA_elem_id_match(elem_old, elem_old_len, elem_old_full, &elem_old_full_offset_start)) {
1721 if (sdna->mem_arena == NULL) {
1722 sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
1723 }
1724 const char *elem_new_full = DNA_elem_id_rename(sdna->mem_arena,
1725 elem_old,
1726 elem_old_len,
1727 elem_new,
1728 elem_new_len,
1729 elem_old_full,
1730 strlen(elem_old_full),
1731 elem_old_full_offset_start);
1732
1733 if (sdna->names_len == sdna->names_len_alloc) {
1734 sdna->names_len_alloc += 64;
1735 sdna->names = MEM_recallocN((void *)sdna->names,
1736 sizeof(*sdna->names) * sdna->names_len_alloc);
1737 sdna->names_array_len = MEM_recallocN(
1738 (void *)sdna->names_array_len, sizeof(*sdna->names_array_len) * sdna->names_len_alloc);
1739 }
1740 const short name_nr_prev = member->name;
1741 member->name = sdna->names_len++;
1742 sdna->names[member->name] = elem_new_full;
1743 sdna->names_array_len[member->name] = sdna->names_array_len[name_nr_prev];
1744
1745 return true;
1746 }
1747 }
1748 return false;
1749 }
1750 /**
1751 * Replace \a elem_old with \a elem_new for struct \a struct_name
1752 * handles search & replace, maintaining surrounding non-identifier characters
1753 * such as pointer & array size.
1754 */
DNA_sdna_patch_struct_member(SDNA * sdna,const char * struct_name,const char * elem_old,const char * elem_new)1755 bool DNA_sdna_patch_struct_member(SDNA *sdna,
1756 const char *struct_name,
1757 const char *elem_old,
1758 const char *elem_new)
1759 {
1760 const int struct_name_nr = DNA_struct_find_nr(sdna, struct_name);
1761 if (struct_name_nr != -1) {
1762 return DNA_sdna_patch_struct_member_nr(sdna, struct_name_nr, elem_old, elem_new);
1763 }
1764 return false;
1765 }
1766
1767 /** \} */
1768
1769 /* -------------------------------------------------------------------- */
1770 /** \name Versioning (Forward Compatible)
1771 *
1772 * Versioning that allows new names.
1773 * \{ */
1774
1775 /**
1776 * Names are shared between structs which causes problems renaming.
1777 * Make sure every struct member gets its own name so renaming only ever impacts a single struct.
1778 *
1779 * The resulting SDNA is never written to disk.
1780 */
sdna_expand_names(SDNA * sdna)1781 static void sdna_expand_names(SDNA *sdna)
1782 {
1783 int names_expand_len = 0;
1784 for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1785 const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1786 names_expand_len += struct_old->members_len;
1787 }
1788 const char **names_expand = MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__);
1789 short *names_array_len_expand = MEM_mallocN(sizeof(*names_array_len_expand) * names_expand_len,
1790 __func__);
1791
1792 int names_expand_index = 0;
1793 for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1794 /* We can't edit this memory 'sdna->structs' points to (readonly datatoc file). */
1795 const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1796
1797 const int array_size = sizeof(short) * 2 + sizeof(SDNA_StructMember) * struct_old->members_len;
1798 SDNA_Struct *struct_new = BLI_memarena_alloc(sdna->mem_arena, array_size);
1799 memcpy(struct_new, struct_old, array_size);
1800 sdna->structs[struct_nr] = struct_new;
1801
1802 for (int i = 0; i < struct_old->members_len; i++) {
1803 const SDNA_StructMember *member_old = &struct_old->members[i];
1804 SDNA_StructMember *member_new = &struct_new->members[i];
1805
1806 names_expand[names_expand_index] = sdna->names[member_old->name];
1807 names_array_len_expand[names_expand_index] = sdna->names_array_len[member_old->name];
1808
1809 BLI_assert(names_expand_index < SHRT_MAX);
1810 member_new->name = names_expand_index;
1811 names_expand_index++;
1812 }
1813 }
1814 MEM_freeN((void *)sdna->names);
1815 sdna->names = names_expand;
1816
1817 MEM_freeN((void *)sdna->names_array_len);
1818 sdna->names_array_len = names_array_len_expand;
1819
1820 sdna->names_len = names_expand_len;
1821 }
1822
dna_sdna_alias_from_static_elem_full(SDNA * sdna,GHash * elem_map_alias_from_static,const char * struct_name_static,const char * elem_static_full)1823 static const char *dna_sdna_alias_from_static_elem_full(SDNA *sdna,
1824 GHash *elem_map_alias_from_static,
1825 const char *struct_name_static,
1826 const char *elem_static_full)
1827 {
1828 const int elem_static_full_len = strlen(elem_static_full);
1829 char *elem_static = alloca(elem_static_full_len + 1);
1830 const int elem_static_len = DNA_elem_id_strip_copy(elem_static, elem_static_full);
1831 const char *str_pair[2] = {struct_name_static, elem_static};
1832 const char *elem_alias = BLI_ghash_lookup(elem_map_alias_from_static, str_pair);
1833 if (elem_alias) {
1834 return DNA_elem_id_rename(sdna->mem_arena,
1835 elem_static,
1836 elem_static_len,
1837 elem_alias,
1838 strlen(elem_alias),
1839 elem_static_full,
1840 elem_static_full_len,
1841 DNA_elem_id_offset_start(elem_static_full));
1842 }
1843 return NULL;
1844 }
1845
DNA_sdna_alias_data_ensure(SDNA * sdna)1846 void DNA_sdna_alias_data_ensure(SDNA *sdna)
1847 {
1848 /* We may want this to be optional later. */
1849 const bool use_legacy_hack = true;
1850
1851 if (sdna->mem_arena == NULL) {
1852 sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
1853 }
1854
1855 GHash *struct_map_alias_from_static;
1856 GHash *elem_map_alias_from_static;
1857
1858 DNA_alias_maps(
1859 DNA_RENAME_ALIAS_FROM_STATIC, &struct_map_alias_from_static, &elem_map_alias_from_static);
1860
1861 if (sdna->alias.types == NULL) {
1862 sdna->alias.types = MEM_mallocN(sizeof(*sdna->alias.types) * sdna->types_len, __func__);
1863 for (int type_nr = 0; type_nr < sdna->types_len; type_nr++) {
1864 const char *struct_name_static = sdna->types[type_nr];
1865
1866 if (use_legacy_hack) {
1867 struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1868 }
1869
1870 sdna->alias.types[type_nr] = BLI_ghash_lookup_default(
1871 struct_map_alias_from_static, struct_name_static, (void *)struct_name_static);
1872 }
1873 }
1874
1875 if (sdna->alias.names == NULL) {
1876 sdna_expand_names(sdna);
1877 sdna->alias.names = MEM_mallocN(sizeof(*sdna->alias.names) * sdna->names_len, __func__);
1878 for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1879 const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1880 const char *struct_name_static = sdna->types[struct_info->type];
1881
1882 if (use_legacy_hack) {
1883 struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1884 }
1885
1886 for (int a = 0; a < struct_info->members_len; a++) {
1887 const SDNA_StructMember *member = &struct_info->members[a];
1888 const char *elem_alias_full = dna_sdna_alias_from_static_elem_full(
1889 sdna, elem_map_alias_from_static, struct_name_static, sdna->names[member->name]);
1890 if (elem_alias_full != NULL) {
1891 sdna->alias.names[member->name] = elem_alias_full;
1892 }
1893 else {
1894 sdna->alias.names[member->name] = sdna->names[member->name];
1895 }
1896 }
1897 }
1898 }
1899 BLI_ghash_free(struct_map_alias_from_static, NULL, NULL);
1900 BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL);
1901 }
1902
1903 /**
1904 * Separated from #DNA_sdna_alias_data_ensure because it's not needed
1905 * unless we want to lookup aliased struct names (#DNA_struct_alias_find_nr and friends).
1906 */
DNA_sdna_alias_data_ensure_structs_map(SDNA * sdna)1907 void DNA_sdna_alias_data_ensure_structs_map(SDNA *sdna)
1908 {
1909 DNA_sdna_alias_data_ensure(sdna);
1910 #ifdef WITH_DNA_GHASH
1911 /* create a ghash lookup to speed up */
1912 struct GHash *structs_map = BLI_ghash_str_new_ex(__func__, sdna->structs_len);
1913 for (intptr_t nr = 0; nr < sdna->structs_len; nr++) {
1914 const SDNA_Struct *struct_info = sdna->structs[nr];
1915 BLI_ghash_insert(
1916 structs_map, (void *)sdna->alias.types[struct_info->type], POINTER_FROM_INT(nr));
1917 }
1918 sdna->alias.structs_map = structs_map;
1919 #else
1920 UNUSED_VARS(sdna);
1921 #endif
1922 }
1923
1924 /** \} */
1925