Blender  V2.93
dna_genfile.c
Go to the documentation of this file.
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 
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 
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 
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) {
153  }
154 #endif
155 
156  if (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) {
165  }
166 #endif
167 
168  MEM_freeN(sdna);
169 }
170 
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 
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 
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 
271 int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
272 {
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 
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
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 
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 
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 
324 BLI_INLINE const char *pad_up_4(const char *ptr)
325 {
326  return (const char *)((((uintptr_t)ptr) + 3) & ~3);
327 }
328 
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) {
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) {
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. */
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) {
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) {
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];
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 
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 
590 static SDNA *g_sdna = NULL;
591 
593 {
594  g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
595 }
596 
597 const struct SDNA *DNA_sdna_current_get(void)
598 {
599  BLI_assert(g_sdna != NULL);
600  return g_sdna;
601 }
602 
604 {
606  g_sdna = NULL;
607 }
608 
609 /* ******************** END READ DNA ********************** */
610 
611 /* ******************* HANDLE DNA ***************** */
612 
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 
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 
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  /* Intentionally overflow signed values into an unsigned type.
756  * Casting back to a signed value preserves the sign (when the new value is signed).
757  * It's also important to cast to `int64_t` when setting `old_value_f` from a signed value. */
758  uint64_t old_value_i = 0;
759 
760  for (int a = 0; a < array_len; a++) {
761  switch (old_type) {
762  case SDNA_TYPE_CHAR: {
763  const char value = *old_data;
764  old_value_i = value;
765  old_value_f = (double)old_value_i;
766  break;
767  }
768  case SDNA_TYPE_UCHAR: {
769  const uchar value = *((uchar *)old_data);
770  old_value_i = value;
771  old_value_f = (double)old_value_i;
772  break;
773  }
774  case SDNA_TYPE_SHORT: {
775  const short value = *((short *)old_data);
776  old_value_i = value;
777  old_value_f = (double)(int64_t)old_value_i;
778  break;
779  }
780  case SDNA_TYPE_USHORT: {
781  const ushort value = *((unsigned short *)old_data);
782  old_value_i = value;
783  old_value_f = (double)old_value_i;
784  break;
785  }
786  case SDNA_TYPE_INT: {
787  const int value = *((int *)old_data);
788  old_value_i = value;
789  old_value_f = (double)(int64_t)old_value_i;
790  break;
791  }
792  case SDNA_TYPE_FLOAT: {
793  const float value = *((float *)old_data);
794  old_value_f = value;
795  old_value_i = (uint64_t)(int64_t)old_value_f;
796  break;
797  }
798  case SDNA_TYPE_DOUBLE: {
799  const double value = *((double *)old_data);
800  old_value_f = value;
801  old_value_i = (uint64_t)(int64_t)old_value_f;
802  break;
803  }
804  case SDNA_TYPE_INT64: {
805  const int64_t value = *((int64_t *)old_data);
806  old_value_i = (uint64_t)value;
807  old_value_f = (double)(int64_t)old_value_i;
808  break;
809  }
810  case SDNA_TYPE_UINT64: {
811  const uint64_t value = *((uint64_t *)old_data);
812  old_value_i = value;
813  old_value_f = (double)old_value_i;
814  break;
815  }
816  case SDNA_TYPE_INT8: {
817  const int8_t value = *((int8_t *)old_data);
818  old_value_i = (uint64_t)value;
819  old_value_f = (double)(int64_t)old_value_i;
820  }
821  }
822 
823  switch (new_type) {
824  case SDNA_TYPE_CHAR:
825  *new_data = (char)old_value_i;
826  break;
827  case SDNA_TYPE_UCHAR:
828  *((unsigned char *)new_data) = (unsigned char)old_value_i;
829  break;
830  case SDNA_TYPE_SHORT:
831  *((short *)new_data) = (short)old_value_i;
832  break;
833  case SDNA_TYPE_USHORT:
834  *((unsigned short *)new_data) = (unsigned short)old_value_i;
835  break;
836  case SDNA_TYPE_INT:
837  *((int *)new_data) = (int)old_value_i;
838  break;
839  case SDNA_TYPE_FLOAT:
840  if (old_type < 2) {
841  old_value_f /= 255.0;
842  }
843  *((float *)new_data) = old_value_f;
844  break;
845  case SDNA_TYPE_DOUBLE:
846  if (old_type < 2) {
847  old_value_f /= 255.0;
848  }
849  *((double *)new_data) = old_value_f;
850  break;
851  case SDNA_TYPE_INT64:
852  *((int64_t *)new_data) = (int64_t)old_value_i;
853  break;
854  case SDNA_TYPE_UINT64:
855  *((uint64_t *)new_data) = old_value_i;
856  break;
857  case SDNA_TYPE_INT8:
858  *((int8_t *)new_data) = (int8_t)old_value_i;
859  break;
860  }
861 
862  old_data += oldlen;
863  new_data += curlen;
864  }
865 }
866 
867 static void cast_pointer_32_to_64(const int array_len,
868  const uint32_t *old_data,
869  uint64_t *new_data)
870 {
871  for (int a = 0; a < array_len; a++) {
872  new_data[a] = old_data[a];
873  }
874 }
875 
876 static void cast_pointer_64_to_32(const int array_len,
877  const uint64_t *old_data,
878  uint32_t *new_data)
879 {
880  /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
881  * pointers may lose uniqueness on truncation! (Hopefully this wont
882  * happen unless/until we ever get to multi-gigabyte .blend files...) */
883  for (int a = 0; a < array_len; a++) {
884  new_data[a] = old_data[a] >> 3;
885  }
886 }
887 
891 static bool elem_streq(const char *name, const char *oname)
892 {
893  int a = 0;
894 
895  while (1) {
896  if (name[a] != oname[a]) {
897  return false;
898  }
899  if (name[a] == '[' || oname[a] == '[') {
900  break;
901  }
902  if (name[a] == 0 || oname[a] == 0) {
903  break;
904  }
905  a++;
906  }
907  return true;
908 }
909 
919 static bool elem_exists_impl(
920  /* Expand SDNA. */
921  const char **types,
922  const char **names,
923  /* Regular args. */
924  const char *type,
925  const char *name,
926  const SDNA_Struct *old)
927 {
928  /* in old is the old struct */
929  for (int a = 0; a < old->members_len; a++) {
930  const SDNA_StructMember *member = &old->members[a];
931  const char *otype = types[member->type];
932  const char *oname = names[member->name];
933 
934  if (elem_streq(name, oname)) { /* name equal */
935  return STREQ(type, otype); /* type equal */
936  }
937  }
938  return false;
939 }
940 
944 static bool elem_exists(const SDNA *sdna,
945  const char *type,
946  const char *name,
947  const SDNA_Struct *old)
948 {
949  return elem_exists_impl(
950  /* Expand SDNA. */
951  sdna->types,
952  sdna->names,
953  /* Regular args. */
954  type,
955  name,
956  old);
957 }
958 
959 static bool elem_exists_alias(const SDNA *sdna,
960  const char *type,
961  const char *name,
962  const SDNA_Struct *old)
963 {
964  return elem_exists_impl(
965  /* Expand SDNA. */
966  sdna->alias.types,
967  sdna->alias.names,
968  /* Regular args. */
969  type,
970  name,
971  old);
972 }
973 
988 static int elem_offset(const SDNA *sdna,
989  const char *type,
990  const char *name,
991  const SDNA_Struct *old)
992 {
993  /* without arraypart, so names can differ: return old namenr and type */
994 
995  /* in old is the old struct */
996  int offset = 0;
997  for (int a = 0; a < old->members_len; a++) {
998  const SDNA_StructMember *member = &old->members[a];
999  const char *otype = sdna->types[member->type];
1000  const char *oname = sdna->names[member->name];
1001  if (elem_streq(name, oname)) { /* name equal */
1002  if (STREQ(type, otype)) { /* type equal */
1003  return offset;
1004  }
1005  break; /* Fail below. */
1006  }
1007  offset += DNA_elem_size_nr(sdna, member->type, member->name);
1008  }
1009  return -1;
1010 }
1011 
1012 /* Each struct member belongs to one of the categories below. */
1018 
1020  const SDNA_StructMember *member)
1021 {
1022  const char *member_name = sdna->names[member->name];
1023  if (ispointer(member_name)) {
1025  }
1026  const char *member_type_name = sdna->types[member->type];
1027  if (DNA_struct_find(sdna, member_type_name)) {
1029  }
1031 }
1032 
1033 static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
1034 {
1035  const char *name = sdna->names[member->name];
1036  const int array_length = sdna->names_array_len[member->name];
1037  if (ispointer(name)) {
1038  return sdna->pointer_size * array_length;
1039  }
1040  const int type_size = sdna->types_size[member->type];
1041  return type_size * array_length;
1042 }
1043 
1051 void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
1052 {
1053  if (struct_nr == -1) {
1054  return;
1055  }
1056 
1057  const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1058 
1059  int offset_in_bytes = 0;
1060  for (int member_index = 0; member_index < struct_info->members_len; member_index++) {
1061  const SDNA_StructMember *member = &struct_info->members[member_index];
1062  const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
1063  char *member_data = data + offset_in_bytes;
1064  const char *member_type_name = sdna->types[member->type];
1065  const int member_array_length = sdna->names_array_len[member->name];
1066 
1067  switch (member_category) {
1069  const int substruct_size = sdna->types_size[member->type];
1070  const int substruct_nr = DNA_struct_find_nr(sdna, member_type_name);
1071  BLI_assert(substruct_nr != -1);
1072  for (int a = 0; a < member_array_length; a++) {
1073  DNA_struct_switch_endian(sdna, substruct_nr, member_data + a * substruct_size);
1074  }
1075  break;
1076  }
1078  switch (member->type) {
1079  case SDNA_TYPE_SHORT:
1080  case SDNA_TYPE_USHORT: {
1081  BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
1082  break;
1083  }
1084  case SDNA_TYPE_INT:
1085  case SDNA_TYPE_FLOAT: {
1086  /* Note, intentionally ignore long/ulong, because these could be 4 or 8 bytes.
1087  * Fortunately, we only use these types for runtime variables and only once for a
1088  * struct type that is no longer used. */
1089  BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
1090  break;
1091  }
1092  case SDNA_TYPE_INT64:
1093  case SDNA_TYPE_UINT64:
1094  case SDNA_TYPE_DOUBLE: {
1095  BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
1096  break;
1097  }
1098  default: {
1099  break;
1100  }
1101  }
1102  break;
1103  }
1105  /* See readfile.c (#bh4_from_bh8 swap endian argument),
1106  * this is only done when reducing the size of a pointer from 4 to 8. */
1107  if (sizeof(void *) < 8) {
1108  if (sdna->pointer_size == 8) {
1109  BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
1110  }
1111  }
1112  break;
1113  }
1114  }
1115  offset_in_bytes += get_member_size_in_bytes(sdna, member);
1116  }
1117 }
1118 
1119 typedef enum eReconstructStepType {
1127 
1128 typedef struct ReconstructStep {
1130  union {
1131  struct {
1134  int size;
1136  struct {
1137  int old_offset;
1138  int new_offset;
1143  struct {
1144  int old_offset;
1145  int new_offset;
1146  int array_len;
1148  struct {
1149  int old_offset;
1150  int new_offset;
1151  int array_len;
1155  } data;
1157 
1158 typedef struct DNA_ReconstructInfo {
1159  const SDNA *oldsdna;
1160  const SDNA *newsdna;
1161  const char *compare_flags;
1162 
1166 
1167 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1168  const int blocks,
1169  const int old_struct_nr,
1170  const int new_struct_nr,
1171  const char *old_blocks,
1172  char *new_blocks);
1173 
1183 static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info,
1184  const int new_struct_nr,
1185  const char *old_block,
1186  char *new_block)
1187 {
1188  const ReconstructStep *steps = reconstruct_info->steps[new_struct_nr];
1189  const int step_count = reconstruct_info->step_counts[new_struct_nr];
1190 
1191  /* Execute all preprocessed steps. */
1192  for (int a = 0; a < step_count; a++) {
1193  const ReconstructStep *step = &steps[a];
1194  switch (step->type) {
1196  memcpy(new_block + step->data.memcpy.new_offset,
1197  old_block + step->data.memcpy.old_offset,
1198  step->data.memcpy.size);
1199  break;
1201  cast_primitive_type(step->data.cast_primitive.old_type,
1202  step->data.cast_primitive.new_type,
1203  step->data.cast_primitive.array_len,
1204  old_block + step->data.cast_primitive.old_offset,
1205  new_block + step->data.cast_primitive.new_offset);
1206  break;
1208  cast_pointer_64_to_32(step->data.cast_pointer.array_len,
1209  (const uint64_t *)(old_block + step->data.cast_pointer.old_offset),
1210  (uint32_t *)(new_block + step->data.cast_pointer.new_offset));
1211  break;
1213  cast_pointer_32_to_64(step->data.cast_pointer.array_len,
1214  (const uint32_t *)(old_block + step->data.cast_pointer.old_offset),
1215  (uint64_t *)(new_block + step->data.cast_pointer.new_offset));
1216  break;
1218  reconstruct_structs(reconstruct_info,
1219  step->data.substruct.array_len,
1220  step->data.substruct.old_struct_nr,
1221  step->data.substruct.new_struct_nr,
1222  old_block + step->data.substruct.old_offset,
1223  new_block + step->data.substruct.new_offset);
1224  break;
1226  /* Do nothing, because the memory block are zeroed (from #MEM_callocN).
1227  *
1228  * Note that the struct could be initialized with the default struct,
1229  * however this complicates versioning, especially with flags, see: D4500. */
1230  break;
1231  }
1232  }
1233 }
1234 
1236 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1237  const int blocks,
1238  const int old_struct_nr,
1239  const int new_struct_nr,
1240  const char *old_blocks,
1241  char *new_blocks)
1242 {
1243  const SDNA_Struct *old_struct = reconstruct_info->oldsdna->structs[old_struct_nr];
1244  const SDNA_Struct *new_struct = reconstruct_info->newsdna->structs[new_struct_nr];
1245 
1246  const int old_block_size = reconstruct_info->oldsdna->types_size[old_struct->type];
1247  const int new_block_size = reconstruct_info->newsdna->types_size[new_struct->type];
1248 
1249  for (int a = 0; a < blocks; a++) {
1250  const char *old_block = old_blocks + a * old_block_size;
1251  char *new_block = new_blocks + a * new_block_size;
1252  reconstruct_struct(reconstruct_info, new_struct_nr, old_block, new_block);
1253  }
1254 }
1255 
1263 void *DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info,
1264  int old_struct_nr,
1265  int blocks,
1266  const void *old_blocks)
1267 {
1268  const SDNA *oldsdna = reconstruct_info->oldsdna;
1269  const SDNA *newsdna = reconstruct_info->newsdna;
1270 
1271  const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1272  const char *type_name = oldsdna->types[old_struct->type];
1273  const int new_struct_nr = DNA_struct_find_nr(newsdna, type_name);
1274 
1275  if (new_struct_nr == -1) {
1276  return NULL;
1277  }
1278 
1279  const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1280  const int new_block_size = newsdna->types_size[new_struct->type];
1281 
1282  char *new_blocks = MEM_callocN(blocks * new_block_size, "reconstruct");
1284  reconstruct_info, blocks, old_struct_nr, new_struct_nr, old_blocks, new_blocks);
1285  return new_blocks;
1286 }
1287 
1290  const SDNA_Struct *struct_info,
1291  const char *name,
1292  int *r_offset)
1293 {
1294  int offset = 0;
1295  for (int a = 0; a < struct_info->members_len; a++) {
1296  const SDNA_StructMember *member = &struct_info->members[a];
1297  const char *member_name = sdna->names[member->name];
1298  if (elem_streq(name, member_name)) {
1299  *r_offset = offset;
1300  return member;
1301  }
1302  offset += get_member_size_in_bytes(sdna, member);
1303  }
1304  return NULL;
1305 }
1306 
1308 static void init_reconstruct_step_for_member(const SDNA *oldsdna,
1309  const SDNA *newsdna,
1310  const char *compare_flags,
1311  const SDNA_Struct *old_struct,
1312  const SDNA_StructMember *new_member,
1313  const int new_member_offset,
1314  ReconstructStep *r_step)
1315 {
1316 
1317  /* Find the matching old member. */
1318  int old_member_offset;
1319  const char *new_name = newsdna->names[new_member->name];
1321  oldsdna, old_struct, new_name, &old_member_offset);
1322 
1323  if (old_member == NULL) {
1324  /* No matching member has been found in the old struct. */
1325  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1326  return;
1327  }
1328 
1329  /* Determine the member category of the old an new members. */
1330  const eStructMemberCategory new_category = get_struct_member_category(newsdna, new_member);
1331  const eStructMemberCategory old_category = get_struct_member_category(oldsdna, old_member);
1332 
1333  if (new_category != old_category) {
1334  /* Can only reconstruct the new member based on the old member, when the belong to the same
1335  * category. */
1336  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1337  return;
1338  }
1339 
1340  const int new_array_length = newsdna->names_array_len[new_member->name];
1341  const int old_array_length = oldsdna->names_array_len[old_member->name];
1342  const int shared_array_length = MIN2(new_array_length, old_array_length);
1343 
1344  const char *new_type_name = newsdna->types[new_member->type];
1345  const char *old_type_name = oldsdna->types[old_member->type];
1346 
1347  switch (new_category) {
1349  if (STREQ(new_type_name, old_type_name)) {
1350  const int old_struct_nr = DNA_struct_find_nr(oldsdna, old_type_name);
1351  BLI_assert(old_struct_nr != -1);
1352  enum eSDNA_StructCompare compare_flag = compare_flags[old_struct_nr];
1353  BLI_assert(compare_flag != SDNA_CMP_REMOVED);
1354  if (compare_flag == SDNA_CMP_EQUAL) {
1355  /* The old and new members are identical, just do a memcpy. */
1356  r_step->type = RECONSTRUCT_STEP_MEMCPY;
1357  r_step->data.memcpy.new_offset = new_member_offset;
1358  r_step->data.memcpy.old_offset = old_member_offset;
1359  r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1360  }
1361  else {
1362  const int new_struct_nr = DNA_struct_find_nr(newsdna, new_type_name);
1363  BLI_assert(new_struct_nr != -1);
1364 
1365  /* The old and new members are different, use recursion to reconstruct the
1366  * nested struct. */
1367  BLI_assert(compare_flag == SDNA_CMP_NOT_EQUAL);
1368  r_step->type = RECONSTRUCT_STEP_SUBSTRUCT;
1369  r_step->data.substruct.new_offset = new_member_offset;
1370  r_step->data.substruct.old_offset = old_member_offset;
1371  r_step->data.substruct.array_len = shared_array_length;
1372  r_step->data.substruct.new_struct_nr = new_struct_nr;
1373  r_step->data.substruct.old_struct_nr = old_struct_nr;
1374  }
1375  }
1376  else {
1377  /* Cannot match structs that have different names. */
1378  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1379  }
1380  break;
1381  }
1383  if (STREQ(new_type_name, old_type_name)) {
1384  /* Primitives with the same name cannot be different, so just do a memcpy. */
1385  r_step->type = RECONSTRUCT_STEP_MEMCPY;
1386  r_step->data.memcpy.new_offset = new_member_offset;
1387  r_step->data.memcpy.old_offset = old_member_offset;
1388  r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1389  }
1390  else {
1391  /* The old and new primitive types are different, cast from the old to new type. */
1393  r_step->data.cast_primitive.array_len = shared_array_length;
1394  r_step->data.cast_primitive.new_offset = new_member_offset;
1395  r_step->data.cast_primitive.old_offset = old_member_offset;
1396  r_step->data.cast_primitive.new_type = new_member->type;
1397  r_step->data.cast_primitive.old_type = old_member->type;
1398  }
1399  break;
1400  }
1402  if (newsdna->pointer_size == oldsdna->pointer_size) {
1403  /* The pointer size is the same, so just do a memcpy. */
1404  r_step->type = RECONSTRUCT_STEP_MEMCPY;
1405  r_step->data.memcpy.new_offset = new_member_offset;
1406  r_step->data.memcpy.old_offset = old_member_offset;
1407  r_step->data.memcpy.size = newsdna->pointer_size * shared_array_length;
1408  }
1409  else if (newsdna->pointer_size == 8 && oldsdna->pointer_size == 4) {
1410  /* Need to convert from 32 bit to 64 bit pointers. */
1412  r_step->data.cast_pointer.new_offset = new_member_offset;
1413  r_step->data.cast_pointer.old_offset = old_member_offset;
1414  r_step->data.cast_pointer.array_len = shared_array_length;
1415  }
1416  else if (newsdna->pointer_size == 4 && oldsdna->pointer_size == 8) {
1417  /* Need to convert from 64 bit to 32 bit pointers. */
1419  r_step->data.cast_pointer.new_offset = new_member_offset;
1420  r_step->data.cast_pointer.old_offset = old_member_offset;
1421  r_step->data.cast_pointer.array_len = shared_array_length;
1422  }
1423  else {
1424  BLI_assert(!"invalid pointer size");
1425  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1426  }
1427  break;
1428  }
1429  }
1430 }
1431 
1433 static void print_reconstruct_step(ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
1434 {
1435  switch (step->type) {
1437  printf("init zero");
1438  break;
1439  }
1440  case RECONSTRUCT_STEP_MEMCPY: {
1441  printf("memcpy, size: %d, old offset: %d, new offset: %d",
1442  step->data.memcpy.size,
1443  step->data.memcpy.old_offset,
1444  step->data.memcpy.new_offset);
1445  break;
1446  }
1448  printf(
1449  "cast element, old type: %d ('%s'), new type: %d ('%s'), old offset: %d, new offset: "
1450  "%d, length: %d",
1451  (int)step->data.cast_primitive.old_type,
1452  oldsdna->types[step->data.cast_primitive.old_type],
1453  (int)step->data.cast_primitive.new_type,
1454  newsdna->types[step->data.cast_primitive.new_type],
1455  step->data.cast_primitive.old_offset,
1456  step->data.cast_primitive.new_offset,
1457  step->data.cast_primitive.array_len);
1458  break;
1459  }
1461  printf("pointer to 32, old offset: %d, new offset: %d, length: %d",
1462  step->data.cast_pointer.old_offset,
1463  step->data.cast_pointer.new_offset,
1464  step->data.cast_pointer.array_len);
1465  break;
1466  }
1468  printf("pointer to 64, old offset: %d, new offset: %d, length: %d",
1469  step->data.cast_pointer.old_offset,
1470  step->data.cast_pointer.new_offset,
1471  step->data.cast_pointer.array_len);
1472  break;
1473  }
1475  printf(
1476  "substruct, old offset: %d, new offset: %d, new struct: %d ('%s', size per struct: %d), "
1477  "length: %d",
1478  step->data.substruct.old_offset,
1479  step->data.substruct.new_offset,
1480  step->data.substruct.new_struct_nr,
1481  newsdna->types[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1482  newsdna->types_size[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1483  step->data.substruct.array_len);
1484  break;
1485  }
1486  }
1487 }
1488 
1494  const SDNA *newsdna,
1495  const char *compare_flags,
1496  const SDNA_Struct *old_struct,
1497  const SDNA_Struct *new_struct)
1498 {
1500  new_struct->members_len, sizeof(ReconstructStep), __func__);
1501 
1502  int new_member_offset = 0;
1503  for (int new_member_index = 0; new_member_index < new_struct->members_len; new_member_index++) {
1504  const SDNA_StructMember *new_member = &new_struct->members[new_member_index];
1506  newsdna,
1507  compare_flags,
1508  old_struct,
1509  new_member,
1510  new_member_offset,
1511  &steps[new_member_index]);
1512  new_member_offset += get_member_size_in_bytes(newsdna, new_member);
1513  }
1514 
1515  return steps;
1516 }
1517 
1519 static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
1520 {
1521  int new_step_count = 0;
1522  for (int a = 0; a < old_step_count; a++) {
1523  ReconstructStep *step = &steps[a];
1524  switch (step->type) {
1526  /* These steps are simply removed. */
1527  break;
1529  if (new_step_count > 0) {
1530  /* Try to merge this memcpy step with the previous one. */
1531  ReconstructStep *prev_step = &steps[new_step_count - 1];
1532  if (prev_step->type == RECONSTRUCT_STEP_MEMCPY) {
1533  /* Check if there are no bytes between the blocks to copy. */
1534  if (prev_step->data.memcpy.old_offset + prev_step->data.memcpy.size ==
1535  step->data.memcpy.old_offset &&
1536  prev_step->data.memcpy.new_offset + prev_step->data.memcpy.size ==
1537  step->data.memcpy.new_offset) {
1538  prev_step->data.memcpy.size += step->data.memcpy.size;
1539  break;
1540  }
1541  }
1542  }
1543  steps[new_step_count] = *step;
1544  new_step_count++;
1545  break;
1550  /* These steps are not changed at all for now. It should be possible to merge consecutive
1551  * steps of the same type, but it is not really worth it. */
1552  steps[new_step_count] = *step;
1553  new_step_count++;
1554  break;
1555  }
1556  }
1557  return new_step_count;
1558 }
1559 
1565  const SDNA *newsdna,
1566  const char *compare_flags)
1567 {
1568  DNA_ReconstructInfo *reconstruct_info = MEM_callocN(sizeof(DNA_ReconstructInfo), __func__);
1569  reconstruct_info->oldsdna = oldsdna;
1570  reconstruct_info->newsdna = newsdna;
1571  reconstruct_info->compare_flags = compare_flags;
1572  reconstruct_info->step_counts = MEM_malloc_arrayN(sizeof(int), newsdna->structs_len, __func__);
1573  reconstruct_info->steps = MEM_malloc_arrayN(
1574  sizeof(ReconstructStep *), newsdna->structs_len, __func__);
1575 
1576  /* Generate reconstruct steps for all structs. */
1577  for (int new_struct_nr = 0; new_struct_nr < newsdna->structs_len; new_struct_nr++) {
1578  const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1579  const char *new_struct_name = newsdna->types[new_struct->type];
1580  const int old_struct_nr = DNA_struct_find_nr(oldsdna, new_struct_name);
1581  if (old_struct_nr < 0) {
1582  reconstruct_info->steps[new_struct_nr] = NULL;
1583  reconstruct_info->step_counts[new_struct_nr] = 0;
1584  continue;
1585  }
1586  const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1588  oldsdna, newsdna, compare_flags, old_struct, new_struct);
1589 
1590  int steps_len = new_struct->members_len;
1591  /* Comment the line below to skip the compression for debugging purposes. */
1592  steps_len = compress_reconstruct_steps(steps, new_struct->members_len);
1593 
1594  reconstruct_info->steps[new_struct_nr] = steps;
1595  reconstruct_info->step_counts[new_struct_nr] = steps_len;
1596 
1597 /* This is useful when debugging the reconstruct steps. */
1598 #if 0
1599  printf("%s: \n", new_struct_name);
1600  for (int a = 0; a < steps_len; a++) {
1601  printf(" ");
1602  print_reconstruct_step(&steps[a], oldsdna, newsdna);
1603  printf("\n");
1604  }
1605 #endif
1607  }
1608 
1609  return reconstruct_info;
1610 }
1611 
1613 {
1614  for (int a = 0; a < reconstruct_info->newsdna->structs_len; a++) {
1615  if (reconstruct_info->steps[a] != NULL) {
1616  MEM_freeN(reconstruct_info->steps[a]);
1617  }
1618  }
1619  MEM_freeN(reconstruct_info->steps);
1620  MEM_freeN(reconstruct_info->step_counts);
1621  MEM_freeN(reconstruct_info);
1622 }
1623 
1628 int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
1629 {
1630  const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1631  BLI_assert(SDNAnr != -1);
1632  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1633  return elem_offset(sdna, vartype, name, spo);
1634 }
1635 
1636 bool DNA_struct_find(const SDNA *sdna, const char *stype)
1637 {
1638  return DNA_struct_find_nr(sdna, stype) != -1;
1639 }
1640 
1641 bool DNA_struct_elem_find(const SDNA *sdna,
1642  const char *stype,
1643  const char *vartype,
1644  const char *name)
1645 {
1646  const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1647 
1648  if (SDNAnr != -1) {
1649  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1650  const bool found = elem_exists(sdna, vartype, name, spo);
1651 
1652  if (found) {
1653  return true;
1654  }
1655  }
1656  return false;
1657 }
1658 
1661  const char *stype,
1662  const char *vartype,
1663  const char *name)
1664 {
1665  const int SDNAnr = DNA_struct_alias_find_nr(sdna, stype);
1666 
1667  if (SDNAnr != -1) {
1668  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1669  const bool found = elem_exists_alias(sdna, vartype, name, spo);
1670 
1671  if (found) {
1672  return true;
1673  }
1674  }
1675  return false;
1676 }
1677 
1681 int DNA_elem_type_size(const eSDNA_Type elem_nr)
1682 {
1683  /* should contain all enum types */
1684  switch (elem_nr) {
1685  case SDNA_TYPE_CHAR:
1686  case SDNA_TYPE_UCHAR:
1687  case SDNA_TYPE_INT8:
1688  return 1;
1689  case SDNA_TYPE_SHORT:
1690  case SDNA_TYPE_USHORT:
1691  return 2;
1692  case SDNA_TYPE_INT:
1693  case SDNA_TYPE_FLOAT:
1694  return 4;
1695  case SDNA_TYPE_DOUBLE:
1696  case SDNA_TYPE_INT64:
1697  case SDNA_TYPE_UINT64:
1698  return 8;
1699  }
1700 
1701  /* weak */
1702  return 8;
1703 }
1704 
1705 /* -------------------------------------------------------------------- */
1709 static bool DNA_sdna_patch_struct_nr(SDNA *sdna,
1710  const int struct_name_old_nr,
1711  const char *struct_name_new)
1712 {
1713  BLI_assert(DNA_struct_find_nr(DNA_sdna_current_get(), struct_name_new) != -1);
1714  const SDNA_Struct *struct_info = sdna->structs[struct_name_old_nr];
1715 #ifdef WITH_DNA_GHASH
1716  BLI_ghash_remove(sdna->structs_map, (void *)sdna->types[struct_info->type], NULL, NULL);
1718  sdna->structs_map, (void *)struct_name_new, POINTER_FROM_INT(struct_name_old_nr));
1719 #endif
1720  sdna->types[struct_info->type] = struct_name_new;
1721  return true;
1722 }
1726 bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new)
1727 {
1728  const int struct_name_old_nr = DNA_struct_find_nr(sdna, struct_name_old);
1729  if (struct_name_old_nr != -1) {
1730  return DNA_sdna_patch_struct_nr(sdna, struct_name_old_nr, struct_name_new);
1731  }
1732  return false;
1733 }
1734 
1735 /* Make public if called often with same struct (avoid duplicate lookups). */
1737  const int struct_name_nr,
1738  const char *elem_old,
1739  const char *elem_new)
1740 {
1741  /* These names aren't handled here (it's not used).
1742  * Ensure they are never used or we get out of sync arrays. */
1743  BLI_assert(sdna->alias.names == NULL);
1744  const int elem_old_len = strlen(elem_old);
1745  const int elem_new_len = strlen(elem_new);
1746  BLI_assert(elem_new != NULL);
1747  SDNA_Struct *sp = sdna->structs[struct_name_nr];
1748  for (int elem_index = sp->members_len; elem_index > 0; elem_index--) {
1749  SDNA_StructMember *member = &sp->members[elem_index];
1750  const char *elem_old_full = sdna->names[member->name];
1751  /* Start & end offsets in 'elem_old_full'. */
1752  uint elem_old_full_offset_start;
1753  if (DNA_elem_id_match(elem_old, elem_old_len, elem_old_full, &elem_old_full_offset_start)) {
1754  if (sdna->mem_arena == NULL) {
1756  }
1757  const char *elem_new_full = DNA_elem_id_rename(sdna->mem_arena,
1758  elem_old,
1759  elem_old_len,
1760  elem_new,
1761  elem_new_len,
1762  elem_old_full,
1763  strlen(elem_old_full),
1764  elem_old_full_offset_start);
1765 
1766  if (sdna->names_len == sdna->names_len_alloc) {
1767  sdna->names_len_alloc += 64;
1768  sdna->names = MEM_recallocN((void *)sdna->names,
1769  sizeof(*sdna->names) * sdna->names_len_alloc);
1771  (void *)sdna->names_array_len, sizeof(*sdna->names_array_len) * sdna->names_len_alloc);
1772  }
1773  const short name_nr_prev = member->name;
1774  member->name = sdna->names_len++;
1775  sdna->names[member->name] = elem_new_full;
1776  sdna->names_array_len[member->name] = sdna->names_array_len[name_nr_prev];
1777 
1778  return true;
1779  }
1780  }
1781  return false;
1782 }
1789  const char *struct_name,
1790  const char *elem_old,
1791  const char *elem_new)
1792 {
1793  const int struct_name_nr = DNA_struct_find_nr(sdna, struct_name);
1794  if (struct_name_nr != -1) {
1795  return DNA_sdna_patch_struct_member_nr(sdna, struct_name_nr, elem_old, elem_new);
1796  }
1797  return false;
1798 }
1799 
1802 /* -------------------------------------------------------------------- */
1814 static void sdna_expand_names(SDNA *sdna)
1815 {
1816  int names_expand_len = 0;
1817  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1818  const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1819  names_expand_len += struct_old->members_len;
1820  }
1821  const char **names_expand = MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__);
1822  short *names_array_len_expand = MEM_mallocN(sizeof(*names_array_len_expand) * names_expand_len,
1823  __func__);
1824 
1825  int names_expand_index = 0;
1826  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1827  /* We can't edit this memory 'sdna->structs' points to (readonly datatoc file). */
1828  const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1829 
1830  const int array_size = sizeof(short) * 2 + sizeof(SDNA_StructMember) * struct_old->members_len;
1831  SDNA_Struct *struct_new = BLI_memarena_alloc(sdna->mem_arena, array_size);
1832  memcpy(struct_new, struct_old, array_size);
1833  sdna->structs[struct_nr] = struct_new;
1834 
1835  for (int i = 0; i < struct_old->members_len; i++) {
1836  const SDNA_StructMember *member_old = &struct_old->members[i];
1837  SDNA_StructMember *member_new = &struct_new->members[i];
1838 
1839  names_expand[names_expand_index] = sdna->names[member_old->name];
1840  names_array_len_expand[names_expand_index] = sdna->names_array_len[member_old->name];
1841 
1842  BLI_assert(names_expand_index < SHRT_MAX);
1843  member_new->name = names_expand_index;
1844  names_expand_index++;
1845  }
1846  }
1847  MEM_freeN((void *)sdna->names);
1848  sdna->names = names_expand;
1849 
1850  MEM_freeN((void *)sdna->names_array_len);
1851  sdna->names_array_len = names_array_len_expand;
1852 
1853  sdna->names_len = names_expand_len;
1854 }
1855 
1858  const char *struct_name_static,
1859  const char *elem_static_full)
1860 {
1861  const int elem_static_full_len = strlen(elem_static_full);
1862  char *elem_static = alloca(elem_static_full_len + 1);
1863  const int elem_static_len = DNA_elem_id_strip_copy(elem_static, elem_static_full);
1864  const char *str_pair[2] = {struct_name_static, elem_static};
1865  const char *elem_alias = BLI_ghash_lookup(elem_map_alias_from_static, str_pair);
1866  if (elem_alias) {
1867  return DNA_elem_id_rename(sdna->mem_arena,
1868  elem_static,
1869  elem_static_len,
1870  elem_alias,
1871  strlen(elem_alias),
1872  elem_static_full,
1873  elem_static_full_len,
1874  DNA_elem_id_offset_start(elem_static_full));
1875  }
1876  return NULL;
1877 }
1878 
1880 {
1881  /* We may want this to be optional later. */
1882  const bool use_legacy_hack = true;
1883 
1884  if (sdna->mem_arena == NULL) {
1886  }
1887 
1890 
1893 
1894  if (sdna->alias.types == NULL) {
1895  sdna->alias.types = MEM_mallocN(sizeof(*sdna->alias.types) * sdna->types_len, __func__);
1896  for (int type_nr = 0; type_nr < sdna->types_len; type_nr++) {
1897  const char *struct_name_static = sdna->types[type_nr];
1898 
1899  if (use_legacy_hack) {
1900  struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1901  }
1902 
1903  sdna->alias.types[type_nr] = BLI_ghash_lookup_default(
1904  struct_map_alias_from_static, struct_name_static, (void *)struct_name_static);
1905  }
1906  }
1907 
1908  if (sdna->alias.names == NULL) {
1909  sdna_expand_names(sdna);
1910  sdna->alias.names = MEM_mallocN(sizeof(*sdna->alias.names) * sdna->names_len, __func__);
1911  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1912  const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1913  const char *struct_name_static = sdna->types[struct_info->type];
1914 
1915  if (use_legacy_hack) {
1916  struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1917  }
1918 
1919  for (int a = 0; a < struct_info->members_len; a++) {
1920  const SDNA_StructMember *member = &struct_info->members[a];
1921  const char *elem_alias_full = dna_sdna_alias_from_static_elem_full(
1922  sdna, elem_map_alias_from_static, struct_name_static, sdna->names[member->name]);
1923  if (elem_alias_full != NULL) {
1924  sdna->alias.names[member->name] = elem_alias_full;
1925  }
1926  else {
1927  sdna->alias.names[member->name] = sdna->names[member->name];
1928  }
1929  }
1930  }
1931  }
1934 }
1935 
1941 {
1943 #ifdef WITH_DNA_GHASH
1944  /* create a ghash lookup to speed up */
1945  struct GHash *structs_map = BLI_ghash_str_new_ex(__func__, sdna->structs_len);
1946  for (intptr_t nr = 0; nr < sdna->structs_len; nr++) {
1947  const SDNA_Struct *struct_info = sdna->structs[nr];
1949  structs_map, (void *)sdna->alias.types[struct_info->type], POINTER_FROM_INT(nr));
1950  }
1951  sdna->alias.structs_map = structs_map;
1952 #else
1953  UNUSED_VARS(sdna);
1954 #endif
1955 }
1956 
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
void BLI_endian_switch_int32_array(int *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:45
void BLI_endian_switch_uint64_array(uint64_t *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:85
void BLI_endian_switch_int64_array(int64_t *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:75
BLI_INLINE void BLI_endian_switch_int32(int *val) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_int16(short *val) ATTR_NONNULL(1)
void BLI_endian_switch_int16_array(short *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:25
GHash * BLI_ghash_str_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:813
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:900
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:830
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
#define BLI_MEMARENA_STD_BUFSIZE
Definition: BLI_memarena.h:36
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:131
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
unsigned short ushort
Definition: BLI_sys_types.h:84
#define UNUSED_VARS(...)
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define MIN2(a, b)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
blenloader genfile private function prototypes
#define SDNA_TYPE_VOID
Definition: DNA_genfile.h:63
eSDNA_Type
Definition: DNA_genfile.h:51
@ SDNA_TYPE_CHAR
Definition: DNA_genfile.h:52
@ SDNA_TYPE_INT
Definition: DNA_genfile.h:56
@ SDNA_TYPE_UINT64
Definition: DNA_genfile.h:65
@ SDNA_TYPE_DOUBLE
Definition: DNA_genfile.h:60
@ SDNA_TYPE_SHORT
Definition: DNA_genfile.h:54
@ SDNA_TYPE_UCHAR
Definition: DNA_genfile.h:53
@ SDNA_TYPE_INT8
Definition: DNA_genfile.h:66
@ SDNA_TYPE_INT64
Definition: DNA_genfile.h:64
@ SDNA_TYPE_FLOAT
Definition: DNA_genfile.h:59
@ SDNA_TYPE_USHORT
Definition: DNA_genfile.h:55
const unsigned char DNAstr[]
const int DNAlen
eSDNA_StructCompare
Definition: DNA_genfile.h:72
@ SDNA_CMP_EQUAL
Definition: DNA_genfile.h:78
@ SDNA_CMP_REMOVED
Definition: DNA_genfile.h:75
@ SDNA_CMP_UNKNOWN
Definition: DNA_genfile.h:83
@ SDNA_CMP_NOT_EQUAL
Definition: DNA_genfile.h:81
struct SDNA_StructMember SDNA_StructMember
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
Definition: dna_genfile.c:332
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)
Definition: dna_genfile.c:1856
struct ReconstructStep ReconstructStep
SDNA * DNA_sdna_from_data(const void *data, const int data_len, bool do_endian_swap, bool data_alloc, const char **r_error_message)
Definition: dna_genfile.c:550
int DNA_elem_size_nr(const SDNA *sdna, short type, short name)
Definition: dna_genfile.c:187
static bool DNA_sdna_patch_struct_member_nr(SDNA *sdna, const int struct_name_nr, const char *elem_old, const char *elem_new)
Definition: dna_genfile.c:1736
eReconstructStepType
Definition: dna_genfile.c:1119
@ RECONSTRUCT_STEP_CAST_POINTER_TO_32
Definition: dna_genfile.c:1122
@ RECONSTRUCT_STEP_CAST_POINTER_TO_64
Definition: dna_genfile.c:1123
@ RECONSTRUCT_STEP_INIT_ZERO
Definition: dna_genfile.c:1125
@ RECONSTRUCT_STEP_SUBSTRUCT
Definition: dna_genfile.c:1124
@ RECONSTRUCT_STEP_CAST_PRIMITIVE
Definition: dna_genfile.c:1121
@ RECONSTRUCT_STEP_MEMCPY
Definition: dna_genfile.c:1120
int DNA_elem_type_size(const eSDNA_Type elem_nr)
Definition: dna_genfile.c:1681
static void 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)
Definition: dna_genfile.c:1236
static bool ispointer(const char *name)
Definition: dna_genfile.c:174
bool DNA_struct_find(const SDNA *sdna, const char *stype)
Definition: dna_genfile.c:1636
static bool elem_exists_impl(const char **types, const char **names, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:919
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)
Definition: dna_genfile.c:744
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)
Definition: dna_genfile.c:1308
bool DNA_struct_alias_elem_find(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1660
static void cast_pointer_64_to_32(const int array_len, const uint64_t *old_data, uint32_t *new_data)
Definition: dna_genfile.c:876
static void sdna_expand_names(SDNA *sdna)
Definition: dna_genfile.c:1814
BLI_INLINE const char * pad_up_4(const char *ptr)
Definition: dna_genfile.c:324
static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
Definition: dna_genfile.c:1033
static bool DNA_sdna_patch_struct_nr(SDNA *sdna, const int struct_name_old_nr, const char *struct_name_new)
Definition: dna_genfile.c:1709
static void print_reconstruct_step(ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
Definition: dna_genfile.c:1433
#define MAKE_ID(a, b, c, d)
Definition: dna_genfile.c:134
static bool elem_exists_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:959
static bool elem_exists(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:944
void DNA_sdna_current_free(void)
Definition: dna_genfile.c:603
static eStructMemberCategory get_struct_member_category(const SDNA *sdna, const SDNA_StructMember *member)
Definition: dna_genfile.c:1019
static void set_compare_flags_for_struct(const SDNA *oldsdna, const SDNA *newsdna, char *compare_flags, const int old_struct_index)
Definition: dna_genfile.c:617
void DNA_sdna_current_init(void)
Definition: dna_genfile.c:592
void DNA_reconstruct_info_free(DNA_ReconstructInfo *reconstruct_info)
Definition: dna_genfile.c:1612
bool DNA_struct_elem_find(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1641
void DNA_sdna_alias_data_ensure(SDNA *sdna)
Definition: dna_genfile.c:1879
static const SDNA_StructMember * find_member_with_matching_name(const SDNA *sdna, const SDNA_Struct *struct_info, const char *name, int *r_offset)
Definition: dna_genfile.c:1289
static int dna_struct_find_nr_ex_impl(const char **types, const int UNUSED(types_len), SDNA_Struct **const structs, const int structs_len, const char *str, unsigned int *index_last)
Definition: dna_genfile.c:225
eStructMemberCategory
Definition: dna_genfile.c:1013
@ STRUCT_MEMBER_CATEGORY_STRUCT
Definition: dna_genfile.c:1014
@ STRUCT_MEMBER_CATEGORY_POINTER
Definition: dna_genfile.c:1016
@ STRUCT_MEMBER_CATEGORY_PRIMITIVE
Definition: dna_genfile.c:1015
static int elem_offset(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:988
DNA_ReconstructInfo * DNA_reconstruct_info_create(const SDNA *oldsdna, const SDNA *newsdna, const char *compare_flags)
Definition: dna_genfile.c:1564
static void cast_pointer_32_to_64(const int array_len, const uint32_t *old_data, uint64_t *new_data)
Definition: dna_genfile.c:867
int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
Definition: dna_genfile.c:288
void DNA_sdna_free(SDNA *sdna)
Definition: dna_genfile.c:139
static bool elem_streq(const char *name, const char *oname)
Definition: dna_genfile.c:891
struct DNA_ReconstructInfo DNA_ReconstructInfo
void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
Definition: dna_genfile.c:1051
bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new)
Definition: dna_genfile.c:1726
void DNA_sdna_alias_data_ensure_structs_map(SDNA *sdna)
Definition: dna_genfile.c:1940
void * DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info, int old_struct_nr, int blocks, const void *old_blocks)
Definition: dna_genfile.c:1263
int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
Definition: dna_genfile.c:314
int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1628
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)
Definition: dna_genfile.c:1493
static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info, const int new_struct_nr, const char *old_block, char *new_block)
Definition: dna_genfile.c:1183
static SDNA * g_sdna
Definition: dna_genfile.c:590
const char * DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
Definition: dna_genfile.c:698
int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
Definition: dna_genfile.c:271
const struct SDNA * DNA_sdna_current_get(void)
Definition: dna_genfile.c:597
bool DNA_sdna_patch_struct_member(SDNA *sdna, const char *struct_name, const char *elem_old, const char *elem_new)
Definition: dna_genfile.c:1788
static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
Definition: dna_genfile.c:1519
int DNA_struct_find_nr(const SDNA *sdna, const char *str)
Definition: dna_genfile.c:307
const char * DNA_struct_rename_legacy_hack_static_from_alias(const char *name)
Definition: dna_utils.c:311
char * DNA_elem_id_rename(struct MemArena *mem_arena, const char *elem_src, const int elem_src_len, const char *elem_dst, const int elem_dst_len, const char *elem_src_full, const int elem_src_full_len, const uint elem_src_full_offset_len)
Definition: dna_utils.c:157
void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash **r_elem_map)
Definition: dna_utils.c:210
uint DNA_elem_id_offset_start(const char *elem_full)
Definition: dna_utils.c:91
bool DNA_elem_id_match(const char *elem_search, const int elem_search_len, const char *elem_full, uint *r_elem_full_offset)
Definition: dna_utils.c:136
const char * DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
Definition: dna_utils.c:327
uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src)
Definition: dna_utils.c:112
int DNA_elem_array_size(const char *str)
Definition: dna_utils.c:46
@ DNA_RENAME_ALIAS_FROM_STATIC
Definition: dna_utils.h:52
#define str(s)
#define UINT_MAX
Definition: hash_md5.c:58
static int types_len
Definition: makesdna.c:159
static char ** names
Definition: makesdna.c:162
static int structs_len
Definition: makesdna.c:160
static char ** types
Definition: makesdna.c:164
static short ** structs
Definition: makesdna.c:181
GHash * elem_map_alias_from_static
Definition: makesdna.c:187
GHash * struct_map_alias_from_static
Definition: makesdna.c:185
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
static const int steps
Definition: sky_nishita.cpp:28
signed short int16_t
Definition: stdint.h:79
_W64 unsigned int uintptr_t
Definition: stdint.h:122
unsigned int uint32_t
Definition: stdint.h:83
__int64 int64_t
Definition: stdint.h:92
_W64 int intptr_t
Definition: stdint.h:121
signed int int32_t
Definition: stdint.h:80
unsigned __int64 uint64_t
Definition: stdint.h:93
signed char int8_t
Definition: stdint.h:78
ReconstructStep ** steps
Definition: dna_genfile.c:1164
const SDNA * newsdna
Definition: dna_genfile.c:1160
const SDNA * oldsdna
Definition: dna_genfile.c:1159
const char * compare_flags
Definition: dna_genfile.c:1161
union ReconstructStep::@1090 data
eSDNA_Type old_type
Definition: dna_genfile.c:1140
eReconstructStepType type
Definition: dna_genfile.c:1129
struct ReconstructStep::@1090::@1094 substruct
struct ReconstructStep::@1090::@1092 cast_primitive
struct ReconstructStep::@1090::@1091 memcpy
eSDNA_Type new_type
Definition: dna_genfile.c:1141
struct ReconstructStep::@1090::@1093 cast_pointer
short members_len
SDNA_StructMember members[]
int types_len
struct GHash * structs_map
short * names_array_len
int structs_len
short * types_size
int names_len_alloc
SDNA_Struct ** structs
int names_len
int data_len
struct MemArena * mem_arena
const char ** types
int pointer_size
const char * data
bool data_alloc
const char ** names
struct SDNA::@1007 alias
uint len
PointerRNA * ptr
Definition: wm_files.c:3157