Blender V4.3
dna_genfile.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
15#include <algorithm>
16#include <climits>
17#include <cstdio>
18#include <cstdlib>
19#include <cstring>
20
21#include "MEM_guardedalloc.h" /* for MEM_freeN MEM_mallocN MEM_callocN */
22
23#include "BLI_endian_switch.h"
25#include "BLI_memarena.h"
26#include "BLI_string.h"
27#include "BLI_utildefines.h"
28
29#include "BLI_ghash.h"
30
31#include "DNA_genfile.h"
32#include "DNA_sdna_types.h" /* for SDNA ;-) */
33
116#ifdef __BIG_ENDIAN__
117/* Big Endian */
118# define MAKE_ID(a, b, c, d) (int(a) << 24 | int(b) << 16 | (c) << 8 | (d))
119#else
120/* Little Endian */
121# define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
122#endif
123
124/* ************************* DIV ********************** */
125
127{
128 if (sdna->data_alloc) {
129 MEM_freeN((void *)sdna->data);
130 }
131
132 MEM_freeN((void *)sdna->members);
133 MEM_freeN((void *)sdna->members_array_num);
134 MEM_freeN((void *)sdna->types);
135 MEM_freeN(sdna->structs);
137
138#ifdef WITH_DNA_GHASH
139 if (sdna->types_to_structs_map) {
140 BLI_ghash_free(sdna->types_to_structs_map, nullptr, nullptr);
141 }
142#endif
143
144 if (sdna->mem_arena) {
146 }
147
150#ifdef WITH_DNA_GHASH
151 if (sdna->alias.types_to_structs_map) {
152 BLI_ghash_free(sdna->alias.types_to_structs_map, nullptr, nullptr);
153 }
154#endif
155
156 MEM_freeN(sdna);
157}
158
159int DNA_struct_size(const SDNA *sdna, int struct_index)
160{
161 return sdna->types_size[sdna->structs[struct_index]->type_index];
162}
163
167static bool ispointer(const char *name)
168{
169 /* check if pointer or function pointer */
170 return (name[0] == '*' || (name[0] == '(' && name[1] == '*'));
171}
172
173int DNA_struct_member_size(const SDNA *sdna, short type, short member_index)
174{
175 const char *cp = sdna->members[member_index];
176 int len = 0;
177
178 /* is it a pointer or function pointer? */
179 if (ispointer(cp)) {
180 /* has the name an extra length? (array) */
181 len = sdna->pointer_size * sdna->members_array_num[member_index];
182 }
183 else if (sdna->types_size[type]) {
184 /* has the name an extra length? (array) */
185 len = int(sdna->types_size[type]) * sdna->members_array_num[member_index];
186 }
187
188 return len;
189}
190
191#if 0
192static void printstruct(SDNA *sdna, short struct_index)
193{
194 /* is for debug */
195
196 SDNA_Struct *struct_info = sdna->structs[struct_index];
197 printf("struct %s\n", sdna->types[struct_info->type]);
198
199 for (int b = 0; b < struct_info->members_len; b++) {
200 SDNA_StructMember *struct_member = &struct_info->members[b];
201 printf(" %s %s\n", sdna->types[struct_member->type], sdna->names[struct_member->name]);
202 }
203}
204#endif
205
210 /* From SDNA struct. */
211 const char **types,
212 const int /*types_num*/,
213 SDNA_Struct **const structs,
214 const int structs_num,
215#ifdef WITH_DNA_GHASH
216 GHash *structs_map,
217#endif
218 /* Regular args. */
219 const char *str,
220 uint *struct_index_last)
221{
222 if (*struct_index_last < structs_num) {
223 const SDNA_Struct *struct_info = structs[*struct_index_last];
224 if (STREQ(types[struct_info->type_index], str)) {
225 return *struct_index_last;
226 }
227 }
228
229#ifdef WITH_DNA_GHASH
230 {
231 void **struct_index_p = BLI_ghash_lookup_p(structs_map, str);
232 if (struct_index_p) {
233 const int struct_index = POINTER_AS_INT(*struct_index_p);
234 *struct_index_last = struct_index;
235 return struct_index;
236 }
237 }
238#else
239 {
240 for (int struct_index = 0; struct_index < types_num; struct_index++) {
241 const SDNA_Struct *struct_info = structs[struct_index];
242 if (STREQ(types[struct_info->type], str)) {
243 *struct_index_last = struct_index;
244 return struct_index;
245 }
246 }
247 }
248#endif
249 return -1;
250}
251
253 const char *str,
254 uint *struct_index_last)
255{
256#ifdef WITH_DNA_GHASH
257 BLI_assert(sdna->types_to_structs_map != nullptr);
258#endif
260 /* Expand SDNA. */
261 sdna->types,
262 sdna->types_num,
263 sdna->structs,
264 sdna->structs_num,
265#ifdef WITH_DNA_GHASH
267#endif
268 /* Regular args. */
269 str,
270 struct_index_last);
271}
272
273int DNA_struct_find_index_with_alias_ex(const SDNA *sdna, const char *str, uint *struct_index_last)
274{
275#ifdef WITH_DNA_GHASH
276 BLI_assert(sdna->alias.types_to_structs_map != nullptr);
277#endif
279 /* Expand SDNA. */
280 sdna->alias.types,
281 sdna->types_num,
282 sdna->structs,
283 sdna->structs_num,
284#ifdef WITH_DNA_GHASH
286#endif
287 /* Regular args. */
288 str,
289 struct_index_last);
290}
291
292int DNA_struct_find_index_without_alias(const SDNA *sdna, const char *str)
293{
294 uint index_last_dummy = UINT_MAX;
295 return DNA_struct_find_index_without_alias_ex(sdna, str, &index_last_dummy);
296}
297
298int DNA_struct_find_with_alias(const SDNA *sdna, const char *str)
299{
300 uint index_last_dummy = UINT_MAX;
301 return DNA_struct_find_index_with_alias_ex(sdna, str, &index_last_dummy);
302}
303
304bool DNA_struct_exists_with_alias(const SDNA *sdna, const char *str)
305{
306 return DNA_struct_find_with_alias(sdna, str) != -1;
307}
308
309/* ************************* END DIV ********************** */
310
311/* ************************* READ DNA ********************** */
312
313BLI_INLINE const char *pad_up_4(const char *ptr)
314{
315 return (const char *)((uintptr_t(ptr) + 3) & ~3);
316}
317
321static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
322{
323 int member_index_gravity_fix = -1;
324
325 int *data = (int *)sdna->data;
326
327 /* Clear pointers in case of error. */
328 sdna->members = nullptr;
329 sdna->types = nullptr;
330 sdna->structs = nullptr;
331#ifdef WITH_DNA_GHASH
332 sdna->types_to_structs_map = nullptr;
333#endif
334 sdna->mem_arena = nullptr;
335
336 /* Lazy initialize. */
337 memset(&sdna->alias, 0, sizeof(sdna->alias));
338
339 /* Struct DNA ('SDNA') */
340 if (*data != MAKE_ID('S', 'D', 'N', 'A')) {
341 *r_error_message = "SDNA error in SDNA file";
342 return false;
343 }
344
345 const char *cp;
346
347 data++;
348 /* Names array ('NAME') */
349 if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
350 data++;
351
352 sdna->members_num = *data;
353 if (do_endian_swap) {
355 }
356 sdna->members_num_alloc = sdna->members_num;
357
358 data++;
359 sdna->members = static_cast<const char **>(
360 MEM_callocN(sizeof(void *) * sdna->members_num, "sdnanames"));
361 }
362 else {
363 *r_error_message = "NAME error in SDNA file";
364 return false;
365 }
366
367 cp = (char *)data;
368 for (int member_index = 0; member_index < sdna->members_num; member_index++) {
369 sdna->members[member_index] = cp;
370
371 /* "float gravity [3]" was parsed wrong giving both "gravity" and
372 * "[3]" members. we rename "[3]", and later set the type of
373 * "gravity" to "void" so the offsets work out correct */
374 if (*cp == '[' && STREQ(cp, "[3]")) {
375 if (member_index && STREQ(sdna->members[member_index - 1], "Cvi")) {
376 sdna->members[member_index] = "gravity[3]";
377 member_index_gravity_fix = member_index;
378 }
379 }
380 while (*cp) {
381 cp++;
382 }
383 cp++;
384 }
385
386 cp = pad_up_4(cp);
387
388 /* Type names array ('TYPE') */
389 data = (int *)cp;
390 if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
391 data++;
392
393 sdna->types_num = *data;
394 if (do_endian_swap) {
396 }
397
398 data++;
399 sdna->types = static_cast<const char **>(
400 MEM_callocN(sizeof(void *) * sdna->types_num, "sdnatypes"));
401 }
402 else {
403 *r_error_message = "TYPE error in SDNA file";
404 return false;
405 }
406
407 cp = (char *)data;
408 for (int type_index = 0; type_index < sdna->types_num; type_index++) {
409 /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */
411 while (*cp) {
412 cp++;
413 }
414 cp++;
415 }
416
417 cp = pad_up_4(cp);
418
419 /* Type lengths array ('TLEN') */
420 data = (int *)cp;
421 short *sp;
422 if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
423 data++;
424 sp = (short *)data;
425 sdna->types_size = sp;
426
427 if (do_endian_swap) {
429 }
430
431 sp += sdna->types_num;
432 }
433 else {
434 *r_error_message = "TLEN error in SDNA file";
435 return false;
436 }
437 /* prevent BUS error */
438 if (sdna->types_num & 1) {
439 sp++;
440 }
441
442 /* Struct array ('STRC') */
443 data = (int *)sp;
444 if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
445 data++;
446
447 sdna->structs_num = *data;
448 if (do_endian_swap) {
450 }
451
452 data++;
453 sdna->structs = static_cast<SDNA_Struct **>(
454 MEM_callocN(sizeof(SDNA_Struct *) * sdna->structs_num, "sdnastrcs"));
455 }
456 else {
457 *r_error_message = "STRC error in SDNA file";
458 return false;
459 }
460
461 sp = (short *)data;
462 for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
463 SDNA_Struct *struct_info = (SDNA_Struct *)sp;
464 sdna->structs[struct_index] = struct_info;
465
466 if (do_endian_swap) {
467 BLI_endian_switch_int16(&struct_info->type_index);
469
470 for (short a = 0; a < struct_info->members_num; a++) {
471 SDNA_StructMember *member = &struct_info->members[a];
474 }
475 }
476 sp += 2 + (sizeof(SDNA_StructMember) / sizeof(short)) * struct_info->members_num;
477 }
478
479 {
480 /* second part of gravity problem, setting "gravity" type to void */
481 if (member_index_gravity_fix > -1) {
482 for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
483 sp = (short *)sdna->structs[struct_index];
484 if (STREQ(sdna->types[sp[0]], "ClothSimSettings")) {
485 sp[10] = SDNA_TYPE_VOID;
486 }
487 }
488 }
489 }
490
491#ifdef WITH_DNA_GHASH
492 {
493 /* create a ghash lookup to speed up */
494 sdna->types_to_structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->structs_num);
495
496 for (intptr_t struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
497 SDNA_Struct *struct_info = sdna->structs[struct_index];
499 (void *)sdna->types[struct_info->type_index],
500 POINTER_FROM_INT(struct_index));
501 }
502 }
503#endif
504
505 /* Calculate 'sdna->pointer_size'.
506 *
507 * NOTE: Cannot just do `sizeof(void *)` here, since the current DNA may come from a blend-file
508 * saved on a different system, using a different pointer size. So instead, use half the size of
509 * the #ListBase struct (only made of two pointers).
510 */
511 {
512 const int struct_index = DNA_struct_find_index_without_alias(sdna, "ListBase");
513
514 /* Should never happen, only with corrupt file for example. */
515 if (UNLIKELY(struct_index == -1)) {
516 *r_error_message = "ListBase struct error! Not found.";
517 return false;
518 }
519
520 const SDNA_Struct *struct_info = sdna->structs[struct_index];
521 sdna->pointer_size = sdna->types_size[struct_info->type_index] / 2;
522
523 /* Should never fail, double-check that #ListBase struct is still what is should be
524 * (a couple of pointers and nothing else). */
525 if (UNLIKELY(struct_info->members_num != 2 || !ELEM(sdna->pointer_size, 4, 8))) {
526 *r_error_message = "ListBase struct error: invalid computed pointer-size.";
527 return false;
528 }
529 }
530
531 /* Cache name size. */
532 {
533 short *members_array_num = static_cast<short int *>(
534 MEM_mallocN(sizeof(*members_array_num) * sdna->members_num, __func__));
535 for (int member_index = 0; member_index < sdna->members_num; member_index++) {
536 members_array_num[member_index] = DNA_member_array_num(sdna->members[member_index]);
537 }
538 sdna->members_array_num = members_array_num;
539 }
540
541 sdna->types_alignment = static_cast<int *>(
542 MEM_malloc_arrayN(sdna->types_num, sizeof(int), __func__));
543 for (int type_index = 0; type_index < sdna->types_num; type_index++) {
544 sdna->types_alignment[type_index] = int(__STDCPP_DEFAULT_NEW_ALIGNMENT__);
545 }
546 {
547 /* TODO: This should be generalized at some point. We should be able to specify `overaligned`
548 * types directly in the DNA struct definitions. */
549 uint dummy_index = 0;
550 const int mat4x4f_struct_index = DNA_struct_find_index_without_alias_ex(
551 sdna, "mat4x4f", &dummy_index);
552 if (mat4x4f_struct_index > 0) {
553 const SDNA_Struct *struct_info = sdna->structs[mat4x4f_struct_index];
554 const int mat4x4f_type_index = struct_info->type_index;
555 sdna->types_alignment[mat4x4f_type_index] = alignof(blender::float4x4);
556 }
557 }
558
559 return true;
560}
561
562SDNA *DNA_sdna_from_data(const void *data,
563 const int data_len,
564 bool do_endian_swap,
565 bool data_alloc,
566 const bool do_alias,
567 const char **r_error_message)
568{
569 SDNA *sdna = static_cast<SDNA *>(MEM_mallocN(sizeof(*sdna), "sdna"));
570 const char *error_message = nullptr;
571
572 sdna->data_size = data_len;
573 if (data_alloc) {
574 char *data_copy = static_cast<char *>(MEM_mallocN(data_len, "sdna_data"));
575 memcpy(data_copy, data, data_len);
576 sdna->data = data_copy;
577 }
578 else {
579 sdna->data = static_cast<const char *>(data);
580 }
581 sdna->data_alloc = data_alloc;
582
583 if (init_structDNA(sdna, do_endian_swap, &error_message)) {
584 if (do_alias) {
586 }
587 return sdna;
588 }
589
590 if (r_error_message == nullptr) {
591 fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message);
592 }
593 else {
594 *r_error_message = error_message;
595 }
596 DNA_sdna_free(sdna);
597 return nullptr;
598}
599
606static SDNA *g_sdna = nullptr;
607
609{
610 g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, true, nullptr);
611}
612
614{
615 BLI_assert(g_sdna != nullptr);
616 return g_sdna;
617}
618
620{
622 g_sdna = nullptr;
623}
624
625/* ******************** END READ DNA ********************** */
626
627/* ******************* HANDLE DNA ***************** */
628
633static void set_compare_flags_for_struct(const SDNA *oldsdna,
634 const SDNA *newsdna,
635 char *compare_flags,
636 const int old_struct_index)
637{
638 if (compare_flags[old_struct_index] != SDNA_CMP_UNKNOWN) {
639 /* This flag has been initialized already. */
640 return;
641 }
642
643 SDNA_Struct *old_struct = oldsdna->structs[old_struct_index];
644 const char *struct_name = oldsdna->types[old_struct->type_index];
645
646 const int new_struct_index = DNA_struct_find_index_without_alias(newsdna, struct_name);
647 if (new_struct_index == -1) {
648 /* Didn't find a matching new struct, so it has been removed. */
649 compare_flags[old_struct_index] = SDNA_CMP_REMOVED;
650 return;
651 }
652
653 SDNA_Struct *new_struct = newsdna->structs[new_struct_index];
654 if (old_struct->members_num != new_struct->members_num) {
655 /* Structs with a different amount of members are not equal. */
656 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
657 return;
658 }
659 if (oldsdna->types_size[old_struct->type_index] != newsdna->types_size[new_struct->type_index]) {
660 /* Structs that don't have the same size are not equal. */
661 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
662 return;
663 }
664
665 /* Compare each member individually. */
666 for (int member_index = 0; member_index < old_struct->members_num; member_index++) {
667 const SDNA_StructMember *old_member = &old_struct->members[member_index];
668 const SDNA_StructMember *new_member = &new_struct->members[member_index];
669
670 const char *old_type_name = oldsdna->types[old_member->type_index];
671 const char *new_type_name = newsdna->types[new_member->type_index];
672 if (!STREQ(old_type_name, new_type_name)) {
673 /* If two members have a different type in the same place, the structs are not equal. */
674 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
675 return;
676 }
677
678 const char *old_member_name = oldsdna->members[old_member->member_index];
679 const char *new_member_name = newsdna->members[new_member->member_index];
680 if (!STREQ(old_member_name, new_member_name)) {
681 /* If two members have a different name in the same place, the structs are not equal. */
682 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
683 return;
684 }
685
686 if (ispointer(old_member_name)) {
687 if (oldsdna->pointer_size != newsdna->pointer_size) {
688 /* When the struct contains a pointer, and the pointer sizes differ, the structs are not
689 * equal. */
690 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
691 return;
692 }
693 }
694 else {
695 const int old_member_struct_index = DNA_struct_find_index_without_alias(oldsdna,
696 old_type_name);
697 if (old_member_struct_index >= 0) {
698 set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, old_member_struct_index);
699 if (compare_flags[old_member_struct_index] != SDNA_CMP_EQUAL) {
700 /* If an embedded struct is not equal, the parent struct cannot be equal either. */
701 compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
702 return;
703 }
704 }
705 }
706 }
707
708 compare_flags[old_struct_index] = SDNA_CMP_EQUAL;
709}
710
711const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
712{
713 if (oldsdna->structs_num == 0) {
714 printf("error: file without SDNA\n");
715 return nullptr;
716 }
717
718 char *compare_flags = static_cast<char *>(MEM_mallocN(oldsdna->structs_num, "compare flags"));
719 memset(compare_flags, SDNA_CMP_UNKNOWN, oldsdna->structs_num);
720
721 /* Set correct flag for every struct. */
722 for (int old_struct_index = 0; old_struct_index < oldsdna->structs_num; old_struct_index++) {
723 set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, old_struct_index);
724 BLI_assert(compare_flags[old_struct_index] != SDNA_CMP_UNKNOWN);
725 }
726
727 /* First struct is the fake 'raw data' one (see the #SDNA_TYPE_RAW_DATA 'basic type' definition
728 * and its usages). By definition, it is always 'equal'.
729 *
730 * NOTE: Bugs History (pre-4.3).
731 *
732 * It used to be `struct Link`, it was skipped in compare_flags (at index `0`). This was a bug,
733 * and was dirty-patched by setting `compare_flags[0]` to `SDNA_CMP_EQUAL` unconditionally.
734 *
735 * Then the `0` struct became `struct DrawDataList`, which was never actually written in
736 * blend-files.
737 *
738 * Write and read blend-file code also has had implicit assumptions that a `0` value in the
739 * #BHead.SDNAnr (aka DNA struct index) meant 'raw data', and therefore was not representing any
740 * real DNA struct. This assumption has been false for years. By luck, this bug seems to have
741 * been fully harmless, for at least the following reasons:
742 * - Read code always ignored DNA struct info in BHead blocks with a `0` value.
743 * - `DrawDataList` data was never actually written in blend-files.
744 * - `struct Link` never needed DNA-versioning.
745 *
746 * NOTE: This may have been broken in BE/LE conversion cases, however this endianness handling
747 * code have likely been dead/never used in practice for many years now.
748 */
749 BLI_STATIC_ASSERT(SDNA_RAW_DATA_STRUCT_INDEX == 0, "'raw data' SDNA struct index should be 0")
751
752/* This code can be enabled to see which structs have changed. */
753#if 0
754 for (int a = 0; a < oldsdna->structs_len; a++) {
755 if (compare_flags[a] == SDNA_CMP_NOT_EQUAL) {
756 SDNA_Struct *struct_info = oldsdna->structs[a];
757 printf("changed: %s\n", oldsdna->types[struct_info->type]);
758 }
759 }
760#endif
761
762 return compare_flags;
763}
764
777static void cast_primitive_type(const eSDNA_Type old_type,
778 const eSDNA_Type new_type,
779 const int array_len,
780 const char *old_data,
781 char *new_data)
782{
783 /* define lengths */
784 const int oldlen = DNA_elem_type_size(old_type);
785 const int curlen = DNA_elem_type_size(new_type);
786
787 double old_value_f = 0.0;
788 /* Intentionally overflow signed values into an unsigned type.
789 * Casting back to a signed value preserves the sign (when the new value is signed). */
790 uint64_t old_value_i = 0;
791
792 for (int a = 0; a < array_len; a++) {
793 switch (old_type) {
794 case SDNA_TYPE_CHAR: {
795 const char value = *old_data;
796 old_value_i = value;
797 old_value_f = double(value);
798 break;
799 }
800 case SDNA_TYPE_UCHAR: {
801 const uchar value = *reinterpret_cast<const uchar *>(old_data);
802 old_value_i = value;
803 old_value_f = double(value);
804 break;
805 }
806 case SDNA_TYPE_SHORT: {
807 const short value = *reinterpret_cast<const short *>(old_data);
808 old_value_i = value;
809 old_value_f = double(value);
810 break;
811 }
812 case SDNA_TYPE_USHORT: {
813 const ushort value = *reinterpret_cast<const ushort *>(old_data);
814 old_value_i = value;
815 old_value_f = double(value);
816 break;
817 }
818 case SDNA_TYPE_INT: {
819 const int value = *reinterpret_cast<const int *>(old_data);
820 old_value_i = value;
821 old_value_f = double(value);
822 break;
823 }
824 case SDNA_TYPE_FLOAT: {
825 const float value = *reinterpret_cast<const float *>(old_data);
826 /* `int64_t` range stored in a `uint64_t`. */
827 old_value_i = uint64_t(int64_t(value));
828 old_value_f = value;
829 break;
830 }
831 case SDNA_TYPE_DOUBLE: {
832 const double value = *reinterpret_cast<const double *>(old_data);
833 /* `int64_t` range stored in a `uint64_t`. */
834 old_value_i = uint64_t(int64_t(value));
835 old_value_f = value;
836 break;
837 }
838 case SDNA_TYPE_INT64: {
839 const int64_t value = *reinterpret_cast<const int64_t *>(old_data);
840 old_value_i = uint64_t(value);
841 old_value_f = double(value);
842 break;
843 }
844 case SDNA_TYPE_UINT64: {
845 const uint64_t value = *reinterpret_cast<const uint64_t *>(old_data);
846 old_value_i = value;
847 old_value_f = double(value);
848 break;
849 }
850 case SDNA_TYPE_INT8: {
851 const int8_t value = *reinterpret_cast<const int8_t *>(old_data);
852 old_value_i = uint64_t(value);
853 old_value_f = double(value);
854 break;
855 }
857 BLI_assert_msg(false, "Conversion from SDNA_TYPE_RAW_DATA is not supported");
858 break;
859 }
860
861 switch (new_type) {
862 case SDNA_TYPE_CHAR:
863 *new_data = char(old_value_i);
864 break;
865 case SDNA_TYPE_UCHAR:
866 *reinterpret_cast<uchar *>(new_data) = uchar(old_value_i);
867 break;
868 case SDNA_TYPE_SHORT:
869 *reinterpret_cast<short *>(new_data) = short(old_value_i);
870 break;
871 case SDNA_TYPE_USHORT:
872 *reinterpret_cast<ushort *>(new_data) = ushort(old_value_i);
873 break;
874 case SDNA_TYPE_INT:
875 *reinterpret_cast<int *>(new_data) = int(old_value_i);
876 break;
877 case SDNA_TYPE_FLOAT:
878 if (old_type < 2) {
879 old_value_f /= 255.0;
880 }
881 *reinterpret_cast<float *>(new_data) = old_value_f;
882 break;
883 case SDNA_TYPE_DOUBLE:
884 if (old_type < 2) {
885 old_value_f /= 255.0;
886 }
887 *reinterpret_cast<double *>(new_data) = old_value_f;
888 break;
889 case SDNA_TYPE_INT64:
890 *reinterpret_cast<int64_t *>(new_data) = int64_t(old_value_i);
891 break;
892 case SDNA_TYPE_UINT64:
893 *reinterpret_cast<uint64_t *>(new_data) = old_value_i;
894 break;
895 case SDNA_TYPE_INT8:
896 *reinterpret_cast<int8_t *>(new_data) = int8_t(old_value_i);
897 break;
899 BLI_assert_msg(false, "Conversion to SDNA_TYPE_RAW_DATA is not supported");
900 break;
901 }
902
903 old_data += oldlen;
904 new_data += curlen;
905 }
906}
907
908static void cast_pointer_32_to_64(const int array_len,
909 const uint32_t *old_data,
910 uint64_t *new_data)
911{
912 for (int a = 0; a < array_len; a++) {
913 new_data[a] = old_data[a];
914 }
915}
916
917static void cast_pointer_64_to_32(const int array_len,
918 const uint64_t *old_data,
919 uint32_t *new_data)
920{
921 /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
922 * pointers may lose uniqueness on truncation! (Hopefully this won't
923 * happen unless/until we ever get to multi-gigabyte .blend files...) */
924 for (int a = 0; a < array_len; a++) {
925 new_data[a] = old_data[a] >> 3;
926 }
927}
928
932static bool elem_streq(const char *name, const char *oname)
933{
934 int a = 0;
935
936 while (true) {
937 if (name[a] != oname[a]) {
938 return false;
939 }
940 if (name[a] == '[' || oname[a] == '[') {
941 break;
942 }
943 if (name[a] == 0 || oname[a] == 0) {
944 break;
945 }
946 a++;
947 }
948 return true;
949}
950
961 /* Expand SDNA. */
962 const char **types,
963 const char **names,
964 /* Regular args. */
965 const char *type,
966 const char *name,
967 const SDNA_Struct *old)
968{
969 /* in old is the old struct */
970 for (int a = 0; a < old->members_num; a++) {
971 const SDNA_StructMember *member = &old->members[a];
972 const char *otype = types[member->type_index];
973 const char *oname = names[member->member_index];
974
975 if (elem_streq(name, oname)) { /* name equal */
976 return STREQ(type, otype); /* type equal */
977 }
978 }
979 return false;
980}
981
985static bool elem_exists_without_alias(const SDNA *sdna,
986 const char *type,
987 const char *name,
988 const SDNA_Struct *old)
989{
990 return elem_exists_impl(
991 /* Expand SDNA. */
992 sdna->types,
993 sdna->members,
994 /* Regular args. */
995 type,
996 name,
997 old);
998}
999
1000static bool elem_exists_with_alias(const SDNA *sdna,
1001 const char *type,
1002 const char *name,
1003 const SDNA_Struct *old)
1004{
1005 return elem_exists_impl(
1006 /* Expand SDNA. */
1007 sdna->alias.types,
1008 sdna->alias.members,
1009 /* Regular args. */
1010 type,
1011 name,
1012 old);
1013}
1014
1015static int elem_offset_impl(const SDNA *sdna,
1016 const char **types,
1017 const char **names,
1018 const char *type,
1019 const char *name,
1020 const SDNA_Struct *old)
1021{
1022 /* Without array-part, so names can differ: return old `namenr` and type. */
1023
1024 /* in old is the old struct */
1025 int offset = 0;
1026 for (int a = 0; a < old->members_num; a++) {
1027 const SDNA_StructMember *member = &old->members[a];
1028 const char *otype = types[member->type_index];
1029 const char *oname = names[member->member_index];
1030 if (elem_streq(name, oname)) { /* name equal */
1031 if (STREQ(type, otype)) { /* type equal */
1032 return offset;
1033 }
1034 break; /* Fail below. */
1035 }
1036 offset += DNA_struct_member_size(sdna, member->type_index, member->member_index);
1037 }
1038 return -1;
1039}
1040
1056static int elem_offset_without_alias(const SDNA *sdna,
1057 const char *type,
1058 const char *name,
1059 const SDNA_Struct *old)
1060{
1061 return elem_offset_impl(sdna, sdna->types, sdna->members, type, name, old);
1062}
1063
1067static int elem_offset_with_alias(const SDNA *sdna,
1068 const char *type,
1069 const char *name,
1070 const SDNA_Struct *old)
1071{
1072 return elem_offset_impl(sdna, sdna->alias.types, sdna->alias.members, type, name, old);
1073}
1074
1075/* Each struct member belongs to one of the categories below. */
1081
1083 const SDNA_StructMember *member)
1084{
1085 const char *member_name = sdna->members[member->member_index];
1086 if (ispointer(member_name)) {
1088 }
1089 const char *member_type_name = sdna->types[member->type_index];
1090 if (DNA_struct_exists_without_alias(sdna, member_type_name)) {
1092 }
1094}
1095
1096static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
1097{
1098 const char *name = sdna->members[member->member_index];
1099 const int array_length = sdna->members_array_num[member->member_index];
1100 if (ispointer(name)) {
1101 return sdna->pointer_size * array_length;
1102 }
1103 const int type_size = sdna->types_size[member->type_index];
1104 return type_size * array_length;
1105}
1106
1107void DNA_struct_switch_endian(const SDNA *sdna, int struct_index, char *data)
1108{
1109 if (struct_index == -1) {
1110 return;
1111 }
1112
1113 const SDNA_Struct *struct_info = sdna->structs[struct_index];
1114
1115 int offset_in_bytes = 0;
1116 for (int member_index = 0; member_index < struct_info->members_num; member_index++) {
1117 const SDNA_StructMember *member = &struct_info->members[member_index];
1118 const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
1119 char *member_data = data + offset_in_bytes;
1120 const char *member_type_name = sdna->types[member->type_index];
1121 const int member_array_length = sdna->members_array_num[member->member_index];
1122
1123 switch (member_category) {
1125 const int substruct_size = sdna->types_size[member->type_index];
1126 const int substruct_index = DNA_struct_find_index_without_alias(sdna, member_type_name);
1127 BLI_assert(substruct_index != -1);
1128 for (int a = 0; a < member_array_length; a++) {
1129 DNA_struct_switch_endian(sdna, substruct_index, member_data + a * substruct_size);
1130 }
1131 break;
1132 }
1134 switch (member->type_index) {
1135 case SDNA_TYPE_SHORT:
1136 case SDNA_TYPE_USHORT: {
1137 BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
1138 break;
1139 }
1140 case SDNA_TYPE_INT:
1141 case SDNA_TYPE_FLOAT: {
1142 /* NOTE: intentionally ignore `long/ulong`, because these could be 4 or 8 bytes.
1143 * Fortunately, we only use these types for runtime variables and only once for a
1144 * struct type that is no longer used. */
1145 BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
1146 break;
1147 }
1148 case SDNA_TYPE_INT64:
1149 case SDNA_TYPE_UINT64:
1150 case SDNA_TYPE_DOUBLE: {
1151 BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
1152 break;
1153 }
1154 default: {
1155 break;
1156 }
1157 }
1158 break;
1159 }
1161 /* See `readfile.cc` (#bh4_from_bh8 swap endian argument),
1162 * this is only done when reducing the size of a pointer from 4 to 8. */
1163 if (sizeof(void *) < 8) {
1164 if (sdna->pointer_size == 8) {
1165 BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
1166 }
1167 }
1168 break;
1169 }
1170 }
1171 offset_in_bytes += get_member_size_in_bytes(sdna, member);
1172 }
1173}
1174
1183
1186 union {
1187 struct {
1190 int size;
1192 struct {
1193 int old_offset;
1194 int new_offset;
1199 struct {
1200 int old_offset;
1201 int new_offset;
1202 int array_len;
1204 struct {
1205 int old_offset;
1206 int new_offset;
1207 int array_len;
1212};
1213
1222
1223static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1224 const int blocks,
1225 const int old_struct_index,
1226 const int new_struct_index,
1227 const char *old_blocks,
1228 char *new_blocks);
1229
1239static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info,
1240 const int new_struct_index,
1241 const char *old_block,
1242 char *new_block)
1243{
1244 const ReconstructStep *steps = reconstruct_info->steps[new_struct_index];
1245 const int step_count = reconstruct_info->step_counts[new_struct_index];
1246
1247 /* Execute all preprocessed steps. */
1248 for (int a = 0; a < step_count; a++) {
1249 const ReconstructStep *step = &steps[a];
1250 switch (step->type) {
1252 memcpy(new_block + step->data.memcpy.new_offset,
1253 old_block + step->data.memcpy.old_offset,
1254 step->data.memcpy.size);
1255 break;
1257 cast_primitive_type(step->data.cast_primitive.old_type,
1258 step->data.cast_primitive.new_type,
1259 step->data.cast_primitive.array_len,
1260 old_block + step->data.cast_primitive.old_offset,
1261 new_block + step->data.cast_primitive.new_offset);
1262 break;
1264 cast_pointer_64_to_32(step->data.cast_pointer.array_len,
1265 (const uint64_t *)(old_block + step->data.cast_pointer.old_offset),
1266 (uint32_t *)(new_block + step->data.cast_pointer.new_offset));
1267 break;
1269 cast_pointer_32_to_64(step->data.cast_pointer.array_len,
1270 (const uint32_t *)(old_block + step->data.cast_pointer.old_offset),
1271 (uint64_t *)(new_block + step->data.cast_pointer.new_offset));
1272 break;
1274 reconstruct_structs(reconstruct_info,
1275 step->data.substruct.array_len,
1276 step->data.substruct.old_struct_index,
1277 step->data.substruct.new_struct_index,
1278 old_block + step->data.substruct.old_offset,
1279 new_block + step->data.substruct.new_offset);
1280 break;
1282 /* Do nothing, because the memory block are zeroed (from #MEM_callocN).
1283 *
1284 * Note that the struct could be initialized with the default struct,
1285 * however this complicates versioning, especially with flags, see: D4500. */
1286 break;
1287 }
1288 }
1289}
1290
1292static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1293 const int blocks,
1294 const int old_struct_index,
1295 const int new_struct_index,
1296 const char *old_blocks,
1297 char *new_blocks)
1298{
1299 const SDNA_Struct *old_struct = reconstruct_info->oldsdna->structs[old_struct_index];
1300 const SDNA_Struct *new_struct = reconstruct_info->newsdna->structs[new_struct_index];
1301
1302 const int old_block_size = reconstruct_info->oldsdna->types_size[old_struct->type_index];
1303 const int new_block_size = reconstruct_info->newsdna->types_size[new_struct->type_index];
1304
1305 for (int a = 0; a < blocks; a++) {
1306 const char *old_block = old_blocks + a * old_block_size;
1307 char *new_block = new_blocks + a * new_block_size;
1308 reconstruct_struct(reconstruct_info, new_struct_index, old_block, new_block);
1309 }
1310}
1311
1312void *DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info,
1313 int old_struct_index,
1314 int blocks,
1315 const void *old_blocks,
1316 const char *alloc_name)
1317{
1318 const SDNA *oldsdna = reconstruct_info->oldsdna;
1319 const SDNA *newsdna = reconstruct_info->newsdna;
1320
1321 const SDNA_Struct *old_struct = oldsdna->structs[old_struct_index];
1322 const char *type_name = oldsdna->types[old_struct->type_index];
1323 const int new_struct_index = DNA_struct_find_index_without_alias(newsdna, type_name);
1324
1325 if (new_struct_index == -1) {
1326 return nullptr;
1327 }
1328
1329 const SDNA_Struct *new_struct = newsdna->structs[new_struct_index];
1330 const int new_block_size = newsdna->types_size[new_struct->type_index];
1331
1332 const int alignment = DNA_struct_alignment(newsdna, new_struct_index);
1333 char *new_blocks = static_cast<char *>(
1334 MEM_calloc_arrayN_aligned(new_block_size, blocks, alignment, alloc_name));
1335 reconstruct_structs(reconstruct_info,
1336 blocks,
1337 old_struct_index,
1338 new_struct_index,
1339 static_cast<const char *>(old_blocks),
1340 new_blocks);
1341 return new_blocks;
1342}
1343
1346 const SDNA_Struct *struct_info,
1347 const char *name,
1348 int *r_offset)
1349{
1350 int offset = 0;
1351 for (int a = 0; a < struct_info->members_num; a++) {
1352 const SDNA_StructMember *member = &struct_info->members[a];
1353 const char *member_name = sdna->members[member->member_index];
1354 if (elem_streq(name, member_name)) {
1355 *r_offset = offset;
1356 return member;
1357 }
1358 offset += get_member_size_in_bytes(sdna, member);
1359 }
1360 return nullptr;
1361}
1362
1364static void init_reconstruct_step_for_member(const SDNA *oldsdna,
1365 const SDNA *newsdna,
1366 const char *compare_flags,
1367 const SDNA_Struct *old_struct,
1368 const SDNA_StructMember *new_member,
1369 const int new_member_offset,
1370 ReconstructStep *r_step)
1371{
1372
1373 /* Find the matching old member. */
1374 int old_member_offset;
1375 const char *new_name = newsdna->members[new_member->member_index];
1377 oldsdna, old_struct, new_name, &old_member_offset);
1378
1379 if (old_member == nullptr) {
1380 /* No matching member has been found in the old struct. */
1382 return;
1383 }
1384
1385 /* Determine the member category of the old an new members. */
1386 const eStructMemberCategory new_category = get_struct_member_category(newsdna, new_member);
1387 const eStructMemberCategory old_category = get_struct_member_category(oldsdna, old_member);
1388
1389 if (new_category != old_category) {
1390 /* Can only reconstruct the new member based on the old member, when the belong to the same
1391 * category. */
1393 return;
1394 }
1395
1396 const int new_array_length = newsdna->members_array_num[new_member->member_index];
1397 const int old_array_length = oldsdna->members_array_num[old_member->member_index];
1398 const int shared_array_length = std::min(new_array_length, old_array_length);
1399
1400 const char *new_type_name = newsdna->types[new_member->type_index];
1401 const char *old_type_name = oldsdna->types[old_member->type_index];
1402
1403 switch (new_category) {
1405 if (STREQ(new_type_name, old_type_name)) {
1406 const int old_struct_index = DNA_struct_find_index_without_alias(oldsdna, old_type_name);
1407 BLI_assert(old_struct_index != -1);
1408 enum eSDNA_StructCompare compare_flag = eSDNA_StructCompare(
1409 compare_flags[old_struct_index]);
1410 BLI_assert(compare_flag != SDNA_CMP_REMOVED);
1411 if (compare_flag == SDNA_CMP_EQUAL) {
1412 /* The old and new members are identical, just do a #memcpy. */
1413 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1414 r_step->data.memcpy.new_offset = new_member_offset;
1415 r_step->data.memcpy.old_offset = old_member_offset;
1416 r_step->data.memcpy.size = newsdna->types_size[new_member->type_index] *
1417 shared_array_length;
1418 }
1419 else {
1420 const int new_struct_index = DNA_struct_find_index_without_alias(newsdna, new_type_name);
1421 BLI_assert(new_struct_index != -1);
1422
1423 /* The old and new members are different, use recursion to reconstruct the
1424 * nested struct. */
1425 BLI_assert(compare_flag == SDNA_CMP_NOT_EQUAL);
1427 r_step->data.substruct.new_offset = new_member_offset;
1428 r_step->data.substruct.old_offset = old_member_offset;
1429 r_step->data.substruct.array_len = shared_array_length;
1430 r_step->data.substruct.new_struct_index = new_struct_index;
1431 r_step->data.substruct.old_struct_index = old_struct_index;
1432 }
1433 }
1434 else {
1435 /* Cannot match structs that have different names. */
1437 }
1438 break;
1439 }
1441 if (STREQ(new_type_name, old_type_name)) {
1442 /* Primitives with the same name cannot be different, so just do a #memcpy. */
1443 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1444 r_step->data.memcpy.new_offset = new_member_offset;
1445 r_step->data.memcpy.old_offset = old_member_offset;
1446 r_step->data.memcpy.size = newsdna->types_size[new_member->type_index] *
1447 shared_array_length;
1448 }
1449 else {
1450 /* The old and new primitive types are different, cast from the old to new type. */
1452 r_step->data.cast_primitive.array_len = shared_array_length;
1453 r_step->data.cast_primitive.new_offset = new_member_offset;
1454 r_step->data.cast_primitive.old_offset = old_member_offset;
1455 r_step->data.cast_primitive.new_type = eSDNA_Type(new_member->type_index);
1456 r_step->data.cast_primitive.old_type = eSDNA_Type(old_member->type_index);
1457 }
1458 break;
1459 }
1461 if (newsdna->pointer_size == oldsdna->pointer_size) {
1462 /* The pointer size is the same, so just do a #memcpy. */
1463 r_step->type = RECONSTRUCT_STEP_MEMCPY;
1464 r_step->data.memcpy.new_offset = new_member_offset;
1465 r_step->data.memcpy.old_offset = old_member_offset;
1466 r_step->data.memcpy.size = newsdna->pointer_size * shared_array_length;
1467 }
1468 else if (newsdna->pointer_size == 8 && oldsdna->pointer_size == 4) {
1469 /* Need to convert from 32 bit to 64 bit pointers. */
1471 r_step->data.cast_pointer.new_offset = new_member_offset;
1472 r_step->data.cast_pointer.old_offset = old_member_offset;
1473 r_step->data.cast_pointer.array_len = shared_array_length;
1474 }
1475 else if (newsdna->pointer_size == 4 && oldsdna->pointer_size == 8) {
1476 /* Need to convert from 64 bit to 32 bit pointers. */
1478 r_step->data.cast_pointer.new_offset = new_member_offset;
1479 r_step->data.cast_pointer.old_offset = old_member_offset;
1480 r_step->data.cast_pointer.array_len = shared_array_length;
1481 }
1482 else {
1483 BLI_assert_msg(0, "invalid pointer size");
1485 }
1486 break;
1487 }
1488 }
1489}
1490
1492[[maybe_unused]] static void print_reconstruct_step(const ReconstructStep *step,
1493 const SDNA *oldsdna,
1494 const SDNA *newsdna)
1495{
1496 switch (step->type) {
1498 printf("initialize zero");
1499 break;
1500 }
1502 printf("memcpy, size: %d, old offset: %d, new offset: %d",
1503 step->data.memcpy.size,
1504 step->data.memcpy.old_offset,
1505 step->data.memcpy.new_offset);
1506 break;
1507 }
1509 printf(
1510 "cast element, old type: %d ('%s'), new type: %d ('%s'), old offset: %d, new offset: "
1511 "%d, length: %d",
1512 int(step->data.cast_primitive.old_type),
1513 oldsdna->types[step->data.cast_primitive.old_type],
1514 int(step->data.cast_primitive.new_type),
1515 newsdna->types[step->data.cast_primitive.new_type],
1516 step->data.cast_primitive.old_offset,
1517 step->data.cast_primitive.new_offset,
1518 step->data.cast_primitive.array_len);
1519 break;
1520 }
1522 printf("pointer to 32, old offset: %d, new offset: %d, length: %d",
1523 step->data.cast_pointer.old_offset,
1524 step->data.cast_pointer.new_offset,
1525 step->data.cast_pointer.array_len);
1526 break;
1527 }
1529 printf("pointer to 64, old offset: %d, new offset: %d, length: %d",
1530 step->data.cast_pointer.old_offset,
1531 step->data.cast_pointer.new_offset,
1532 step->data.cast_pointer.array_len);
1533 break;
1534 }
1536 printf(
1537 "substruct, old offset: %d, new offset: %d, new struct: %d ('%s', size per struct: %d), "
1538 "length: %d",
1539 step->data.substruct.old_offset,
1540 step->data.substruct.new_offset,
1541 step->data.substruct.new_struct_index,
1542 newsdna->types[newsdna->structs[step->data.substruct.new_struct_index]->type_index],
1543 newsdna->types_size[newsdna->structs[step->data.substruct.new_struct_index]->type_index],
1544 step->data.substruct.array_len);
1545 break;
1546 }
1547 }
1548}
1549
1555 const SDNA *newsdna,
1556 const char *compare_flags,
1557 const SDNA_Struct *old_struct,
1558 const SDNA_Struct *new_struct)
1559{
1560 ReconstructStep *steps = static_cast<ReconstructStep *>(
1561 MEM_calloc_arrayN(new_struct->members_num, sizeof(ReconstructStep), __func__));
1562
1563 int new_member_offset = 0;
1564 for (int new_member_index = 0; new_member_index < new_struct->members_num; new_member_index++) {
1565 const SDNA_StructMember *new_member = &new_struct->members[new_member_index];
1567 newsdna,
1568 compare_flags,
1569 old_struct,
1570 new_member,
1571 new_member_offset,
1572 &steps[new_member_index]);
1573 new_member_offset += get_member_size_in_bytes(newsdna, new_member);
1574 }
1575
1576 return steps;
1577}
1578
1580static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
1581{
1582 int new_step_count = 0;
1583 for (int a = 0; a < old_step_count; a++) {
1584 ReconstructStep *step = &steps[a];
1585 switch (step->type) {
1587 /* These steps are simply removed. */
1588 break;
1590 if (new_step_count > 0) {
1591 /* Try to merge this memcpy step with the previous one. */
1592 ReconstructStep *prev_step = &steps[new_step_count - 1];
1593 if (prev_step->type == RECONSTRUCT_STEP_MEMCPY) {
1594 /* Check if there are no bytes between the blocks to copy. */
1595 if (prev_step->data.memcpy.old_offset + prev_step->data.memcpy.size ==
1596 step->data.memcpy.old_offset &&
1597 prev_step->data.memcpy.new_offset + prev_step->data.memcpy.size ==
1598 step->data.memcpy.new_offset)
1599 {
1600 prev_step->data.memcpy.size += step->data.memcpy.size;
1601 break;
1602 }
1603 }
1604 }
1605 steps[new_step_count] = *step;
1606 new_step_count++;
1607 break;
1612 /* These steps are not changed at all for now. It should be possible to merge consecutive
1613 * steps of the same type, but it is not really worth it. */
1614 steps[new_step_count] = *step;
1615 new_step_count++;
1616 break;
1617 }
1618 }
1619 return new_step_count;
1620}
1621
1623 const SDNA *newsdna,
1624 const char *compare_flags)
1625{
1626 DNA_ReconstructInfo *reconstruct_info = static_cast<DNA_ReconstructInfo *>(
1627 MEM_callocN(sizeof(DNA_ReconstructInfo), __func__));
1628 reconstruct_info->oldsdna = oldsdna;
1629 reconstruct_info->newsdna = newsdna;
1630 reconstruct_info->compare_flags = compare_flags;
1631 reconstruct_info->step_counts = static_cast<int *>(
1632 MEM_malloc_arrayN(newsdna->structs_num, sizeof(int), __func__));
1633 reconstruct_info->steps = static_cast<ReconstructStep **>(
1634 MEM_malloc_arrayN(newsdna->structs_num, sizeof(ReconstructStep *), __func__));
1635
1636 /* Generate reconstruct steps for all structs. */
1637 for (int new_struct_index = 0; new_struct_index < newsdna->structs_num; new_struct_index++) {
1638 const SDNA_Struct *new_struct = newsdna->structs[new_struct_index];
1639 const char *new_struct_name = newsdna->types[new_struct->type_index];
1640 const int old_struct_index = DNA_struct_find_index_without_alias(oldsdna, new_struct_name);
1641 if (old_struct_index < 0) {
1642 reconstruct_info->steps[new_struct_index] = nullptr;
1643 reconstruct_info->step_counts[new_struct_index] = 0;
1644 continue;
1645 }
1646 const SDNA_Struct *old_struct = oldsdna->structs[old_struct_index];
1648 oldsdna, newsdna, compare_flags, old_struct, new_struct);
1649
1650 /* Comment the line below to skip the compression for debugging purposes. */
1651 const int steps_len = compress_reconstruct_steps(steps, new_struct->members_num);
1652
1653 reconstruct_info->steps[new_struct_index] = steps;
1654 reconstruct_info->step_counts[new_struct_index] = steps_len;
1655
1656/* This is useful when debugging the reconstruct steps. */
1657#if 0
1658 printf("%s: \n", new_struct_name);
1659 for (int a = 0; a < steps_len; a++) {
1660 printf(" ");
1661 print_reconstruct_step(&steps[a], oldsdna, newsdna);
1662 printf("\n");
1663 }
1664#endif
1665 }
1666
1667 return reconstruct_info;
1668}
1669
1671{
1672 for (int new_struct_index = 0; new_struct_index < reconstruct_info->newsdna->structs_num;
1673 new_struct_index++)
1674 {
1675 if (reconstruct_info->steps[new_struct_index] != nullptr) {
1676 MEM_freeN(reconstruct_info->steps[new_struct_index]);
1677 }
1678 }
1679 MEM_freeN(reconstruct_info->steps);
1680 MEM_freeN(reconstruct_info->step_counts);
1681 MEM_freeN(reconstruct_info);
1682}
1683
1685 const char *stype,
1686 const char *vartype,
1687 const char *name)
1688{
1689 const int struct_index = DNA_struct_find_index_without_alias(sdna, stype);
1690 BLI_assert(struct_index != -1);
1691 const SDNA_Struct *const struct_info = sdna->structs[struct_index];
1692 return elem_offset_without_alias(sdna, vartype, name, struct_info);
1693}
1694
1696 const char *stype,
1697 const char *vartype,
1698 const char *name)
1699{
1700 const int struct_index = DNA_struct_find_with_alias(sdna, stype);
1701 BLI_assert(struct_index != -1);
1702 const SDNA_Struct *const struct_info = sdna->structs[struct_index];
1703 return elem_offset_with_alias(sdna, vartype, name, struct_info);
1704}
1705
1706bool DNA_struct_exists_without_alias(const SDNA *sdna, const char *stype)
1707{
1708 return DNA_struct_find_index_without_alias(sdna, stype) != -1;
1709}
1710
1712 const char *stype,
1713 const char *vartype,
1714 const char *name)
1715{
1716 const int struct_index = DNA_struct_find_index_without_alias(sdna, stype);
1717
1718 if (struct_index != -1) {
1719 const SDNA_Struct *const struct_info = sdna->structs[struct_index];
1720 const bool found = elem_exists_without_alias(sdna, vartype, name, struct_info);
1721
1722 if (found) {
1723 return true;
1724 }
1725 }
1726 return false;
1727}
1728
1730 const char *stype,
1731 const char *vartype,
1732 const char *name)
1733{
1734 const int SDNAnr = DNA_struct_find_with_alias(sdna, stype);
1735
1736 if (SDNAnr != -1) {
1737 const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1738 const bool found = elem_exists_with_alias(sdna, vartype, name, spo);
1739
1740 if (found) {
1741 return true;
1742 }
1743 }
1744 return false;
1745}
1746
1748{
1749 /* should contain all enum types */
1750 switch (elem_nr) {
1751 case SDNA_TYPE_CHAR:
1752 case SDNA_TYPE_UCHAR:
1753 case SDNA_TYPE_INT8:
1754 return 1;
1755 case SDNA_TYPE_SHORT:
1756 case SDNA_TYPE_USHORT:
1757 return 2;
1758 case SDNA_TYPE_INT:
1759 case SDNA_TYPE_FLOAT:
1760 return 4;
1761 case SDNA_TYPE_DOUBLE:
1762 case SDNA_TYPE_INT64:
1763 case SDNA_TYPE_UINT64:
1764 return 8;
1765 case SDNA_TYPE_RAW_DATA:
1766 BLI_assert_msg(false, "Operations on the size of SDNA_TYPE_RAW_DATA is not supported");
1767 return 0;
1768 }
1769
1770 /* weak */
1771 return 8;
1772}
1773
1774int DNA_struct_alignment(const SDNA *sdna, const int struct_index)
1775{
1776 return sdna->types_alignment[struct_index];
1777}
1778
1779const char *DNA_struct_identifier(SDNA *sdna, const int struct_index)
1780{
1782 const SDNA_Struct *struct_info = sdna->structs[struct_index];
1783 return sdna->alias.types[struct_info->type_index];
1784}
1785
1786/* -------------------------------------------------------------------- */
1790static bool DNA_sdna_patch_struct(SDNA *sdna, const int struct_index, const char *new_type_name)
1791{
1793 const SDNA_Struct *struct_info = sdna->structs[struct_index];
1794#ifdef WITH_DNA_GHASH
1796 sdna->types_to_structs_map, (void *)sdna->types[struct_info->type_index], nullptr, nullptr);
1798 sdna->types_to_structs_map, (void *)new_type_name, POINTER_FROM_INT(struct_index));
1799#endif
1800 sdna->types[struct_info->type_index] = new_type_name;
1801 return true;
1802}
1804 const char *old_type_name,
1805 const char *new_type_name)
1806{
1807 const int struct_index = DNA_struct_find_index_without_alias(sdna, old_type_name);
1808 if (struct_index != -1) {
1809 return DNA_sdna_patch_struct(sdna, struct_index, new_type_name);
1810 }
1811 return false;
1812}
1813
1814/* Make public if called often with same struct (avoid duplicate lookups). */
1816 const int struct_index,
1817 const char *old_member_name,
1818 const char *new_member_name)
1819{
1820 /* These names aren't handled here (it's not used).
1821 * Ensure they are never used or we get out of sync arrays. */
1822 BLI_assert(sdna->alias.members == nullptr);
1823 const int old_member_name_len = strlen(old_member_name);
1824 const int new_member_name_len = strlen(new_member_name);
1825 BLI_assert(new_member_name != nullptr);
1826 SDNA_Struct *struct_info = sdna->structs[struct_index];
1827 for (int struct_member_index = struct_info->members_num; struct_member_index > 0;
1828 struct_member_index--)
1829 {
1830 SDNA_StructMember *member_info = &struct_info->members[struct_member_index];
1831 const char *old_member_name_full = sdna->members[member_info->member_index];
1832 /* Start & end offsets in #old_member_full. */
1833 uint old_member_name_full_offset_start;
1834 if (DNA_member_id_match(old_member_name,
1835 old_member_name_len,
1836 old_member_name_full,
1837 &old_member_name_full_offset_start))
1838 {
1839 if (sdna->mem_arena == nullptr) {
1841 }
1842 const char *new_member_name_full = DNA_member_id_rename(sdna->mem_arena,
1843 old_member_name,
1844 old_member_name_len,
1845 new_member_name,
1846 new_member_name_len,
1847 old_member_name_full,
1848 strlen(old_member_name_full),
1849 old_member_name_full_offset_start);
1850
1851 if (sdna->members_num == sdna->members_num_alloc) {
1852 sdna->members_num_alloc += 64;
1853 sdna->members = static_cast<const char **>(MEM_recallocN(
1854 (void *)sdna->members, sizeof(*sdna->members) * sdna->members_num_alloc));
1855 sdna->members_array_num = static_cast<short int *>(
1856 MEM_recallocN((void *)sdna->members_array_num,
1857 sizeof(*sdna->members_array_num) * sdna->members_num_alloc));
1858 }
1859 const short old_member_index = member_info->member_index;
1860 member_info->member_index = sdna->members_num++;
1861 sdna->members[member_info->member_index] = new_member_name_full;
1862 sdna->members_array_num[member_info->member_index] =
1863 sdna->members_array_num[old_member_index];
1864
1865 return true;
1866 }
1867 }
1868 return false;
1869}
1871 const char *type_name,
1872 const char *old_member_name,
1873 const char *new_member_name)
1874{
1875 const int struct_index = DNA_struct_find_index_without_alias(sdna, type_name);
1876 if (struct_index != -1) {
1877 return DNA_sdna_patch_struct_member(sdna, struct_index, old_member_name, new_member_name);
1878 }
1879 return false;
1880}
1881
1884/* -------------------------------------------------------------------- */
1896static void sdna_expand_names(SDNA *sdna)
1897{
1898 int names_expand_len = 0;
1899 for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
1900 const SDNA_Struct *struct_old = sdna->structs[struct_index];
1901 names_expand_len += struct_old->members_num;
1902 }
1903 const char **names_expand = static_cast<const char **>(
1904 MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__));
1905 short *names_array_len_expand = static_cast<short int *>(
1906 MEM_mallocN(sizeof(*names_array_len_expand) * names_expand_len, __func__));
1907
1908 int names_expand_index = 0;
1909 for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
1910 /* We can't edit this memory 'sdna->structs' points to (read-only `datatoc` file). */
1911 const SDNA_Struct *struct_old = sdna->structs[struct_index];
1912
1913 const int array_size = sizeof(short) * 2 + sizeof(SDNA_StructMember) * struct_old->members_num;
1914 SDNA_Struct *struct_new = static_cast<SDNA_Struct *>(
1915 BLI_memarena_alloc(sdna->mem_arena, array_size));
1916 memcpy(struct_new, struct_old, array_size);
1917 sdna->structs[struct_index] = struct_new;
1918
1919 for (int i = 0; i < struct_old->members_num; i++) {
1920 const SDNA_StructMember *member_old = &struct_old->members[i];
1921 SDNA_StructMember *member_new = &struct_new->members[i];
1922
1923 names_expand[names_expand_index] = sdna->members[member_old->member_index];
1924 names_array_len_expand[names_expand_index] =
1925 sdna->members_array_num[member_old->member_index];
1926
1927 BLI_assert(names_expand_index < SHRT_MAX);
1928 member_new->member_index = names_expand_index;
1929 names_expand_index++;
1930 }
1931 }
1932 MEM_freeN((void *)sdna->members);
1933 sdna->members = names_expand;
1934
1935 MEM_freeN((void *)sdna->members_array_num);
1936 sdna->members_array_num = names_array_len_expand;
1937
1938 sdna->members_num = names_expand_len;
1939}
1940
1942 GHash *elem_map_alias_from_static,
1943 const char *struct_name_static,
1944 const char *elem_static_full)
1945{
1946 const int elem_static_full_len = strlen(elem_static_full);
1947 char *elem_static = static_cast<char *>(alloca(elem_static_full_len + 1));
1948 const int elem_static_len = DNA_member_id_strip_copy(elem_static, elem_static_full);
1949 const char *str_pair[2] = {struct_name_static, elem_static};
1950 const char *elem_alias = static_cast<const char *>(
1951 BLI_ghash_lookup(elem_map_alias_from_static, str_pair));
1952 if (elem_alias) {
1953 return DNA_member_id_rename(sdna->mem_arena,
1954 elem_static,
1955 elem_static_len,
1956 elem_alias,
1957 strlen(elem_alias),
1958 elem_static_full,
1959 elem_static_full_len,
1960 DNA_member_id_offset_start(elem_static_full));
1961 }
1962 return nullptr;
1963}
1964
1966{
1967 if (sdna->alias.members && sdna->alias.types) {
1968 return;
1969 }
1970
1971 /* We may want this to be optional later. */
1972 const bool use_legacy_hack = true;
1973
1974 if (sdna->mem_arena == nullptr) {
1976 }
1977
1980
1983
1984 if (sdna->alias.types == nullptr) {
1985 sdna->alias.types = static_cast<const char **>(
1986 MEM_mallocN(sizeof(*sdna->alias.types) * sdna->types_num, __func__));
1987 for (int type_index = 0; type_index < sdna->types_num; type_index++) {
1988 const char *type_name_static = sdna->types[type_index];
1989
1990 if (use_legacy_hack) {
1991 type_name_static = DNA_struct_rename_legacy_hack_alias_from_static(type_name_static);
1992 }
1993
1994 sdna->alias.types[type_index] = static_cast<const char *>(BLI_ghash_lookup_default(
1995 type_map_alias_from_static, type_name_static, (void *)type_name_static));
1996 }
1997 }
1998
1999 if (sdna->alias.members == nullptr) {
2000 sdna_expand_names(sdna);
2001 sdna->alias.members = static_cast<const char **>(
2002 MEM_mallocN(sizeof(*sdna->alias.members) * sdna->members_num, __func__));
2003 for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
2004 const SDNA_Struct *struct_info = sdna->structs[struct_index];
2005 const char *struct_name_static = sdna->types[struct_info->type_index];
2006
2007 if (use_legacy_hack) {
2008 struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
2009 }
2010
2011 for (int a = 0; a < struct_info->members_num; a++) {
2012 const SDNA_StructMember *member = &struct_info->members[a];
2013 const char *member_alias_full = dna_sdna_alias_from_static_elem_full(
2014 sdna,
2016 struct_name_static,
2017 sdna->members[member->member_index]);
2018 if (member_alias_full != nullptr) {
2019 sdna->alias.members[member->member_index] = member_alias_full;
2020 }
2021 else {
2022 sdna->alias.members[member->member_index] = sdna->members[member->member_index];
2023 }
2024 }
2025 }
2026 }
2027 BLI_ghash_free(type_map_alias_from_static, nullptr, nullptr);
2029}
2030
2032{
2033 if (sdna->alias.types_to_structs_map) {
2034 return;
2035 }
2036
2038#ifdef WITH_DNA_GHASH
2039 /* create a ghash lookup to speed up */
2040 GHash *type_to_struct_index_map = BLI_ghash_str_new_ex(__func__, sdna->structs_num);
2041 for (intptr_t struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
2042 const SDNA_Struct *struct_info = sdna->structs[struct_index];
2043 BLI_ghash_insert(type_to_struct_index_map,
2044 (void *)sdna->alias.types[struct_info->type_index],
2045 POINTER_FROM_INT(struct_index));
2046 }
2047 sdna->alias.types_to_structs_map = type_to_struct_index_map;
2048#else
2049 UNUSED_VARS(sdna);
2050#endif
2051}
2052
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:87
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define BLI_INLINE
BLI_INLINE void BLI_endian_switch_int32(int *val) ATTR_NONNULL(1)
void BLI_endian_switch_int32_array(int *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_uint64_array(uint64_t *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_int64_array(int64_t *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_int16_array(short *val, int size) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_int16(short *val) ATTR_NONNULL(1)
void * BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:738
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:745
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:787
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
unsigned char uchar
unsigned short ushort
unsigned int uint
#define UNUSED_VARS(...)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
blenloader genfile private function prototypes
#define SDNA_TYPE_VOID
Definition DNA_genfile.h:48
eSDNA_Type
Definition DNA_genfile.h:36
@ SDNA_TYPE_CHAR
Definition DNA_genfile.h:37
@ SDNA_TYPE_RAW_DATA
Definition DNA_genfile.h:58
@ SDNA_TYPE_INT
Definition DNA_genfile.h:41
@ SDNA_TYPE_UINT64
Definition DNA_genfile.h:50
@ SDNA_TYPE_DOUBLE
Definition DNA_genfile.h:45
@ SDNA_TYPE_SHORT
Definition DNA_genfile.h:39
@ SDNA_TYPE_UCHAR
Definition DNA_genfile.h:38
@ SDNA_TYPE_INT8
Definition DNA_genfile.h:51
@ SDNA_TYPE_INT64
Definition DNA_genfile.h:49
@ SDNA_TYPE_FLOAT
Definition DNA_genfile.h:44
@ SDNA_TYPE_USHORT
Definition DNA_genfile.h:40
const unsigned char DNAstr[]
const int DNAlen
eSDNA_StructCompare
Definition DNA_genfile.h:64
@ SDNA_CMP_EQUAL
Definition DNA_genfile.h:70
@ SDNA_CMP_REMOVED
Definition DNA_genfile.h:67
@ SDNA_CMP_UNKNOWN
Definition DNA_genfile.h:75
@ SDNA_CMP_NOT_EQUAL
Definition DNA_genfile.h:73
struct SDNA_StructMember SDNA_StructMember
#define SDNA_RAW_DATA_STRUCT_INDEX
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
local_group_size(16, 16) .push_constant(Type b
#define printf
bool DNA_struct_member_exists_with_alias(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
static void print_reconstruct_step(const ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info, const int new_struct_index, const char *old_block, char *new_block)
static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info, const int blocks, const int old_struct_index, const int new_struct_index, const char *old_blocks, char *new_blocks)
int DNA_struct_find_index_without_alias_ex(const SDNA *sdna, const char *str, uint *struct_index_last)
const char * DNA_struct_identifier(SDNA *sdna, const int struct_index)
void DNA_sdna_current_free()
int DNA_struct_find_with_alias(const SDNA *sdna, const char *str)
SDNA * DNA_sdna_from_data(const void *data, const int data_len, bool do_endian_swap, bool data_alloc, const bool do_alias, const char **r_error_message)
DNA_ReconstructInfo * DNA_reconstruct_info_create(const SDNA *oldsdna, const SDNA *newsdna, const char *compare_flags)
eReconstructStepType
@ RECONSTRUCT_STEP_CAST_POINTER_TO_32
@ RECONSTRUCT_STEP_CAST_POINTER_TO_64
@ RECONSTRUCT_STEP_INIT_ZERO
@ RECONSTRUCT_STEP_SUBSTRUCT
@ RECONSTRUCT_STEP_CAST_PRIMITIVE
@ RECONSTRUCT_STEP_MEMCPY
int DNA_elem_type_size(const eSDNA_Type elem_nr)
static bool ispointer(const char *name)
static bool DNA_sdna_patch_struct_member(SDNA *sdna, const int struct_index, const char *old_member_name, const char *new_member_name)
int DNA_struct_member_size(const SDNA *sdna, short type, short member_index)
static bool elem_exists_impl(const char **types, const char **names, const char *type, const char *name, const SDNA_Struct *old)
static bool DNA_sdna_patch_struct(SDNA *sdna, const int struct_index, const char *new_type_name)
static int elem_offset_with_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
static void cast_primitive_type(const eSDNA_Type old_type, const eSDNA_Type new_type, const int array_len, const char *old_data, char *new_data)
BLI_INLINE const char * pad_up_4(const char *ptr)
bool DNA_struct_exists_without_alias(const SDNA *sdna, const char *stype)
static void 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)
static void cast_pointer_64_to_32(const int array_len, const uint64_t *old_data, uint32_t *new_data)
void DNA_struct_switch_endian(const SDNA *sdna, int struct_index, char *data)
static void sdna_expand_names(SDNA *sdna)
static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
static int dna_struct_find_index_ex_impl(const char **types, const int, SDNA_Struct **const structs, const int structs_num, const char *str, uint *struct_index_last)
int DNA_struct_alignment(const SDNA *sdna, const int struct_index)
const SDNA * DNA_sdna_current_get()
static const char * 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)
static bool elem_exists_without_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
#define MAKE_ID(a, b, c, d)
int DNA_struct_size(const SDNA *sdna, int struct_index)
static eStructMemberCategory get_struct_member_category(const SDNA *sdna, const SDNA_StructMember *member)
static bool elem_exists_with_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
static void set_compare_flags_for_struct(const SDNA *oldsdna, const SDNA *newsdna, char *compare_flags, const int old_struct_index)
void DNA_reconstruct_info_free(DNA_ReconstructInfo *reconstruct_info)
int DNA_struct_member_offset_by_name_with_alias(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
static const SDNA_StructMember * find_member_with_matching_name(const SDNA *sdna, const SDNA_Struct *struct_info, const char *name, int *r_offset)
static ReconstructStep * 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)
const char * DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
static int elem_offset_without_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
void DNA_sdna_alias_data_ensure(SDNA *sdna)
static int elem_offset_impl(const SDNA *sdna, const char **types, const char **names, const char *type, const char *name, const SDNA_Struct *old)
eStructMemberCategory
@ STRUCT_MEMBER_CATEGORY_STRUCT
@ STRUCT_MEMBER_CATEGORY_POINTER
@ STRUCT_MEMBER_CATEGORY_PRIMITIVE
static void cast_pointer_32_to_64(const int array_len, const uint32_t *old_data, uint64_t *new_data)
bool DNA_sdna_patch_struct_member_by_name(SDNA *sdna, const char *type_name, const char *old_member_name, const char *new_member_name)
void DNA_sdna_free(SDNA *sdna)
static bool elem_streq(const char *name, const char *oname)
void * DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info, int old_struct_index, int blocks, const void *old_blocks, const char *alloc_name)
bool DNA_struct_exists_with_alias(const SDNA *sdna, const char *str)
void DNA_sdna_current_init()
void DNA_sdna_alias_data_ensure_structs_map(SDNA *sdna)
static SDNA * g_sdna
int DNA_struct_find_index_with_alias_ex(const SDNA *sdna, const char *str, uint *struct_index_last)
int DNA_struct_member_offset_by_name_without_alias(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
bool DNA_struct_member_exists_without_alias(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
int DNA_struct_find_index_without_alias(const SDNA *sdna, const char *str)
bool DNA_sdna_patch_struct_by_name(SDNA *sdna, const char *old_type_name, const char *new_type_name)
const char * DNA_struct_rename_legacy_hack_static_from_alias(const char *name)
Definition dna_utils.cc:293
const char * DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
Definition dna_utils.cc:309
int DNA_member_array_num(const char *str)
Definition dna_utils.cc:29
void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_type_map, GHash **r_member_map)
Definition dna_utils.cc:193
bool DNA_member_id_match(const char *member_id, const int member_id_len, const char *member_full, uint *r_member_full_offset)
Definition dna_utils.cc:116
uint DNA_member_id_offset_start(const char *member_full)
Definition dna_utils.cc:74
uint DNA_member_id_strip_copy(char *member_id_dst, const char *member_full_src)
Definition dna_utils.cc:96
char * DNA_member_id_rename(MemArena *mem_arena, const char *member_id_src, const int member_id_src_len, const char *member_id_dst, const int member_id_dst_len, const char *member_full_src, const int member_full_src_len, const uint member_full_src_offset_len)
Definition dna_utils.cc:134
@ DNA_RENAME_ALIAS_FROM_STATIC
Definition dna_utils.h:89
int len
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define str(s)
#define UINT_MAX
Definition hash_md5.cc:44
static int types_num
Definition makesdna.cc:66
GHash * type_map_alias_from_static
Definition makesdna.cc:92
GHash * member_map_alias_from_static
Definition makesdna.cc:94
static short ** structs
Definition makesdna.cc:88
static int structs_num
Definition makesdna.cc:67
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void *(* MEM_calloc_arrayN_aligned)(size_t len, size_t size, size_t alignment, const char *str)
Definition mallocn.cc:51
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:43
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
MatBase< float, 4, 4 > float4x4
static const int steps
signed short int16_t
Definition stdint.h:76
_W64 unsigned int uintptr_t
Definition stdint.h:119
unsigned int uint32_t
Definition stdint.h:80
__int64 int64_t
Definition stdint.h:89
_W64 int intptr_t
Definition stdint.h:118
signed int int32_t
Definition stdint.h:77
unsigned __int64 uint64_t
Definition stdint.h:90
signed char int8_t
Definition stdint.h:75
ReconstructStep ** steps
const char * compare_flags
eSDNA_Type old_type
struct ReconstructStep::@1320::@1324 substruct
eReconstructStepType type
struct ReconstructStep::@1320::@1321 memcpy
struct ReconstructStep::@1320::@1322 cast_primitive
union ReconstructStep::@1320 data
eSDNA_Type new_type
struct ReconstructStep::@1320::@1323 cast_pointer
SDNA_StructMember members[]
struct GHash * types_to_structs_map
const char ** members
int types_num
int structs_num
struct SDNA::@1177 alias
short * types_size
SDNA_Struct ** structs
int * types_alignment
struct MemArena * mem_arena
int members_num
int members_num_alloc
const char ** types
int pointer_size
const char * data
bool data_alloc
short * members_array_num
int data_size
PointerRNA * ptr
Definition wm_files.cc:4126