Blender  V3.3
dna_genfile.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
14 #include <limits.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "MEM_guardedalloc.h" /* for MEM_freeN MEM_mallocN MEM_callocN */
20 
21 #include "BLI_endian_switch.h"
22 #include "BLI_memarena.h"
23 #include "BLI_string.h"
24 #include "BLI_utildefines.h"
25 
26 #include "BLI_ghash.h"
27 
28 #include "DNA_genfile.h"
29 #include "DNA_sdna_types.h" /* for SDNA ;-) */
30 
113 #ifdef __BIG_ENDIAN__
114 /* Big Endian */
115 # define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
116 #else
117 /* Little Endian */
118 # define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
119 #endif
120 
121 /* ************************* DIV ********************** */
122 
123 void DNA_sdna_free(SDNA *sdna)
124 {
125  if (sdna->data_alloc) {
126  MEM_freeN((void *)sdna->data);
127  }
128 
129  MEM_freeN((void *)sdna->names);
130  MEM_freeN((void *)sdna->names_array_len);
131  MEM_freeN((void *)sdna->types);
132  MEM_freeN(sdna->structs);
133 
134 #ifdef WITH_DNA_GHASH
135  if (sdna->structs_map) {
137  }
138 #endif
139 
140  if (sdna->mem_arena) {
142  }
143 
144  MEM_SAFE_FREE(sdna->alias.names);
145  MEM_SAFE_FREE(sdna->alias.types);
146 #ifdef WITH_DNA_GHASH
147  if (sdna->alias.structs_map) {
149  }
150 #endif
151 
152  MEM_freeN(sdna);
153 }
154 
158 static bool ispointer(const char *name)
159 {
160  /* check if pointer or function pointer */
161  return (name[0] == '*' || (name[0] == '(' && name[1] == '*'));
162 }
163 
164 int DNA_elem_size_nr(const SDNA *sdna, short type, short name)
165 {
166  const char *cp = sdna->names[name];
167  int len = 0;
168 
169  /* is it a pointer or function pointer? */
170  if (ispointer(cp)) {
171  /* has the name an extra length? (array) */
172  len = sdna->pointer_size * sdna->names_array_len[name];
173  }
174  else if (sdna->types_size[type]) {
175  /* has the name an extra length? (array) */
176  len = (int)sdna->types_size[type] * sdna->names_array_len[name];
177  }
178 
179  return len;
180 }
181 
182 #if 0
183 static void printstruct(SDNA *sdna, short strnr)
184 {
185  /* is for debug */
186 
187  SDNA_Struct *struct_info = sdna->structs[strnr];
188  printf("struct %s\n", sdna->types[struct_info->type]);
189 
190  for (int b = 0; b < struct_info->members_len; b++) {
191  SDNA_StructMember *struct_member = &struct_info->members[b];
192  printf(" %s %s\n",
193  sdna->types[struct_member->type],
194  sdna->names[struct_member->name]);
195  }
196 }
197 #endif
198 
203  /* From SDNA struct. */
204  const char **types,
205  const int UNUSED(types_len),
206  SDNA_Struct **const structs,
207  const int structs_len,
208 #ifdef WITH_DNA_GHASH
209  GHash *structs_map,
210 #endif
211  /* Regular args. */
212  const char *str,
213  unsigned int *index_last)
214 {
215  if (*index_last < structs_len) {
216  const SDNA_Struct *struct_info = structs[*index_last];
217  if (STREQ(types[struct_info->type], str)) {
218  return *index_last;
219  }
220  }
221 
222 #ifdef WITH_DNA_GHASH
223  {
224  void **index_p = BLI_ghash_lookup_p(structs_map, str);
225  if (index_p) {
226  const int index = POINTER_AS_INT(*index_p);
227  *index_last = index;
228  return index;
229  }
230  }
231 #else
232  {
233  for (int index = 0; index < structs_len; index++) {
234  const SDNA_Struct *struct_info = structs[index];
235  if (STREQ(types[struct_info->type], str)) {
236  *index_last = index;
237  return index;
238  }
239  }
240  }
241 #endif
242  return -1;
243 }
244 
245 int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
246 {
248  /* Expand SDNA. */
249  sdna->types,
250  sdna->types_len,
251  sdna->structs,
252  sdna->structs_len,
253 #ifdef WITH_DNA_GHASH
254  sdna->structs_map,
255 #endif
256  /* Regular args. */
257  str,
258  index_last);
259 }
260 
261 int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
262 {
263 #ifdef WITH_DNA_GHASH
264  BLI_assert(sdna->alias.structs_map != NULL);
265 #endif
267  /* Expand SDNA. */
268  sdna->alias.types,
269  sdna->types_len,
270  sdna->structs,
271  sdna->structs_len,
272 #ifdef WITH_DNA_GHASH
273  sdna->alias.structs_map,
274 #endif
275  /* Regular args. */
276  str,
277  index_last);
278 }
279 
280 int DNA_struct_find_nr(const SDNA *sdna, const char *str)
281 {
282  unsigned int index_last_dummy = UINT_MAX;
283  return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy);
284 }
285 
286 int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
287 {
288  unsigned int index_last_dummy = UINT_MAX;
289  return DNA_struct_alias_find_nr_ex(sdna, str, &index_last_dummy);
290 }
291 
292 /* ************************* END DIV ********************** */
293 
294 /* ************************* READ DNA ********************** */
295 
296 BLI_INLINE const char *pad_up_4(const char *ptr)
297 {
298  return (const char *)((((uintptr_t)ptr) + 3) & ~3);
299 }
300 
304 static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
305 {
306  int gravity_fix = -1;
307 
308  int *data = (int *)sdna->data;
309 
310  /* Clear pointers in case of error. */
311  sdna->names = NULL;
312  sdna->types = NULL;
313  sdna->structs = NULL;
314 #ifdef WITH_DNA_GHASH
315  sdna->structs_map = NULL;
316 #endif
317  sdna->mem_arena = NULL;
318 
319  /* Lazy initialize. */
320  memset(&sdna->alias, 0, sizeof(sdna->alias));
321 
322  /* Struct DNA ('SDNA') */
323  if (*data != MAKE_ID('S', 'D', 'N', 'A')) {
324  *r_error_message = "SDNA error in SDNA file";
325  return false;
326  }
327 
328  const char *cp;
329 
330  data++;
331  /* Names array ('NAME') */
332  if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
333  data++;
334 
335  sdna->names_len = *data;
336  if (do_endian_swap) {
338  }
339  sdna->names_len_alloc = sdna->names_len;
340 
341  data++;
342  sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames");
343  }
344  else {
345  *r_error_message = "NAME error in SDNA file";
346  return false;
347  }
348 
349  cp = (char *)data;
350  for (int nr = 0; nr < sdna->names_len; nr++) {
351  sdna->names[nr] = cp;
352 
353  /* "float gravity [3]" was parsed wrong giving both "gravity" and
354  * "[3]" members. we rename "[3]", and later set the type of
355  * "gravity" to "void" so the offsets work out correct */
356  if (*cp == '[' && STREQ(cp, "[3]")) {
357  if (nr && STREQ(sdna->names[nr - 1], "Cvi")) {
358  sdna->names[nr] = "gravity[3]";
359  gravity_fix = nr;
360  }
361  }
362  while (*cp) {
363  cp++;
364  }
365  cp++;
366  }
367 
368  cp = pad_up_4(cp);
369 
370  /* Type names array ('TYPE') */
371  data = (int *)cp;
372  if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
373  data++;
374 
375  sdna->types_len = *data;
376  if (do_endian_swap) {
378  }
379 
380  data++;
381  sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes");
382  }
383  else {
384  *r_error_message = "TYPE error in SDNA file";
385  return false;
386  }
387 
388  cp = (char *)data;
389  for (int nr = 0; nr < sdna->types_len; nr++) {
390  /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */
392  while (*cp) {
393  cp++;
394  }
395  cp++;
396  }
397 
398  cp = pad_up_4(cp);
399 
400  /* Type lengths array ('TLEN') */
401  data = (int *)cp;
402  short *sp;
403  if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
404  data++;
405  sp = (short *)data;
406  sdna->types_size = sp;
407 
408  if (do_endian_swap) {
410  }
411 
412  sp += sdna->types_len;
413  }
414  else {
415  *r_error_message = "TLEN error in SDNA file";
416  return false;
417  }
418  /* prevent BUS error */
419  if (sdna->types_len & 1) {
420  sp++;
421  }
422 
423  /* Struct array ('STRC') */
424  data = (int *)sp;
425  if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
426  data++;
427 
428  sdna->structs_len = *data;
429  if (do_endian_swap) {
431  }
432 
433  data++;
434  sdna->structs = MEM_callocN(sizeof(SDNA_Struct *) * sdna->structs_len, "sdnastrcs");
435  }
436  else {
437  *r_error_message = "STRC error in SDNA file";
438  return false;
439  }
440 
441  sp = (short *)data;
442  for (int nr = 0; nr < sdna->structs_len; nr++) {
443  SDNA_Struct *struct_info = (SDNA_Struct *)sp;
444  sdna->structs[nr] = struct_info;
445 
446  if (do_endian_swap) {
447  BLI_endian_switch_int16(&struct_info->type);
448  BLI_endian_switch_int16(&struct_info->members_len);
449 
450  for (short a = 0; a < struct_info->members_len; a++) {
451  SDNA_StructMember *member = &struct_info->members[a];
452  BLI_endian_switch_int16(&member->type);
453  BLI_endian_switch_int16(&member->name);
454  }
455  }
456  sp += 2 + (sizeof(SDNA_StructMember) / sizeof(short)) * struct_info->members_len;
457  }
458 
459  {
460  /* second part of gravity problem, setting "gravity" type to void */
461  if (gravity_fix > -1) {
462  for (int nr = 0; nr < sdna->structs_len; nr++) {
463  sp = (short *)sdna->structs[nr];
464  if (STREQ(sdna->types[sp[0]], "ClothSimSettings")) {
465  sp[10] = SDNA_TYPE_VOID;
466  }
467  }
468  }
469  }
470 
471 #ifdef WITH_DNA_GHASH
472  {
473  /* create a ghash lookup to speed up */
474  sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->structs_len);
475 
476  for (intptr_t nr = 0; nr < sdna->structs_len; nr++) {
477  SDNA_Struct *struct_info = sdna->structs[nr];
479  sdna->structs_map, (void *)sdna->types[struct_info->type], POINTER_FROM_INT(nr));
480  }
481  }
482 #endif
483 
484  /* Calculate 'sdna->pointer_size' */
485  {
486  const int nr = DNA_struct_find_nr(sdna, "ListBase");
487 
488  /* should never happen, only with corrupt file for example */
489  if (UNLIKELY(nr == -1)) {
490  *r_error_message = "ListBase struct error! Not found.";
491  return false;
492  }
493 
494  /* finally pointer_size: use struct ListBase to test it, never change the size of it! */
495  SDNA_Struct *struct_info = sdna->structs[nr];
496  /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */
497 
498  sdna->pointer_size = sdna->types_size[struct_info->type] / 2;
499 
500  if (struct_info->members_len != 2 || (!ELEM(sdna->pointer_size, 4, 8))) {
501  *r_error_message = "ListBase struct error! Needs it to calculate pointerize.";
502  /* well, at least sizeof(ListBase) is error proof! (ton) */
503  return false;
504  }
505  }
506 
507  /* Cache name size. */
508  {
509  short *names_array_len = MEM_mallocN(sizeof(*names_array_len) * sdna->names_len, __func__);
510  for (int i = 0; i < sdna->names_len; i++) {
511  names_array_len[i] = DNA_elem_array_size(sdna->names[i]);
512  }
513  sdna->names_array_len = names_array_len;
514  }
515 
516  return true;
517 }
518 
520  const int data_len,
521  bool do_endian_swap,
522  bool data_alloc,
523  const char **r_error_message)
524 {
525  SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
526  const char *error_message = NULL;
527 
528  sdna->data_len = data_len;
529  if (data_alloc) {
530  char *data_copy = MEM_mallocN(data_len, "sdna_data");
531  memcpy(data_copy, data, data_len);
532  sdna->data = data_copy;
533  }
534  else {
535  sdna->data = data;
536  }
537  sdna->data_alloc = data_alloc;
538 
539  if (init_structDNA(sdna, do_endian_swap, &error_message)) {
540  return sdna;
541  }
542 
543  if (r_error_message == NULL) {
544  fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message);
545  }
546  else {
547  *r_error_message = error_message;
548  }
549  DNA_sdna_free(sdna);
550  return NULL;
551 }
552 
559 static SDNA *g_sdna = NULL;
560 
562 {
563  g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
564 }
565 
566 const struct SDNA *DNA_sdna_current_get(void)
567 {
568  BLI_assert(g_sdna != NULL);
569  return g_sdna;
570 }
571 
573 {
575  g_sdna = NULL;
576 }
577 
578 /* ******************** END READ DNA ********************** */
579 
580 /* ******************* HANDLE DNA ***************** */
581 
586 static void set_compare_flags_for_struct(const SDNA *oldsdna,
587  const SDNA *newsdna,
588  char *compare_flags,
589  const int old_struct_index)
590 {
591  if (compare_flags[old_struct_index] != SDNA_CMP_UNKNOWN) {
592  /* This flag has been initialized already. */
593  return;
594  }
595 
596  SDNA_Struct *old_struct = oldsdna->structs[old_struct_index];
597  const char *struct_name = oldsdna->types[old_struct->type];
598 
599  const int new_struct_index = DNA_struct_find_nr(newsdna, struct_name);
600  if (new_struct_index == -1) {
601  /* Didn't find a matching new struct, so it has been removed. */
602  compare_flags[old_struct_index] = SDNA_CMP_REMOVED;
603  return;
604  }
605 
606  SDNA_Struct *new_struct = newsdna->structs[new_struct_index];
607  if (old_struct->members_len != new_struct->members_len) {
608  /* Structs with a different amount of members are not equal. */
609  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
610  return;
611  }
612  if (oldsdna->types_size[old_struct->type] != newsdna->types_size[new_struct->type]) {
613  /* Structs that don't have the same size are not equal. */
614  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
615  return;
616  }
617 
618  /* Compare each member individually. */
619  for (int member_index = 0; member_index < old_struct->members_len; member_index++) {
620  SDNA_StructMember *old_member = &old_struct->members[member_index];
621  SDNA_StructMember *new_member = &new_struct->members[member_index];
622 
623  const char *old_type_name = oldsdna->types[old_member->type];
624  const char *new_type_name = newsdna->types[new_member->type];
625  if (!STREQ(old_type_name, new_type_name)) {
626  /* If two members have a different type in the same place, the structs are not equal. */
627  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
628  return;
629  }
630 
631  const char *old_member_name = oldsdna->names[old_member->name];
632  const char *new_member_name = newsdna->names[new_member->name];
633  if (!STREQ(old_member_name, new_member_name)) {
634  /* If two members have a different name in the same place, the structs are not equal. */
635  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
636  return;
637  }
638 
639  if (ispointer(old_member_name)) {
640  if (oldsdna->pointer_size != newsdna->pointer_size) {
641  /* When the struct contains a pointer, and the pointer sizes differ, the structs are not
642  * equal. */
643  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
644  return;
645  }
646  }
647  else {
648  const int old_member_struct_index = DNA_struct_find_nr(oldsdna, old_type_name);
649  if (old_member_struct_index >= 0) {
650  set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, old_member_struct_index);
651  if (compare_flags[old_member_struct_index] != SDNA_CMP_EQUAL) {
652  /* If an embedded struct is not equal, the parent struct cannot be equal either. */
653  compare_flags[old_struct_index] = SDNA_CMP_NOT_EQUAL;
654  return;
655  }
656  }
657  }
658  }
659 
660  compare_flags[old_struct_index] = SDNA_CMP_EQUAL;
661 }
662 
663 const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
664 {
665  if (oldsdna->structs_len == 0) {
666  printf("error: file without SDNA\n");
667  return NULL;
668  }
669 
670  char *compare_flags = MEM_mallocN(oldsdna->structs_len, "compare flags");
671  memset(compare_flags, SDNA_CMP_UNKNOWN, oldsdna->structs_len);
672 
673  /* Set correct flag for every struct. */
674  for (int a = 0; a < oldsdna->structs_len; a++) {
675  set_compare_flags_for_struct(oldsdna, newsdna, compare_flags, a);
676  BLI_assert(compare_flags[a] != SDNA_CMP_UNKNOWN);
677  }
678 
679  /* first struct in util.h is struct Link, this is skipped in compare_flags (als # 0).
680  * was a bug, and this way dirty patched! Solve this later....
681  */
682  compare_flags[0] = SDNA_CMP_EQUAL;
683 
684 /* This code can be enabled to see which structs have changed. */
685 #if 0
686  for (int a = 0; a < oldsdna->structs_len; a++) {
687  if (compare_flags[a] == SDNA_CMP_NOT_EQUAL) {
688  SDNA_Struct *struct_info = oldsdna->structs[a];
689  printf("changed: %s\n", oldsdna->types[struct_info->type]);
690  }
691  }
692 #endif
693 
694  return compare_flags;
695 }
696 
709 static void cast_primitive_type(const eSDNA_Type old_type,
710  const eSDNA_Type new_type,
711  const int array_len,
712  const char *old_data,
713  char *new_data)
714 {
715  /* define lengths */
716  const int oldlen = DNA_elem_type_size(old_type);
717  const int curlen = DNA_elem_type_size(new_type);
718 
719  double old_value_f = 0.0;
720  /* Intentionally overflow signed values into an unsigned type.
721  * Casting back to a signed value preserves the sign (when the new value is signed). */
722  uint64_t old_value_i = 0;
723 
724  for (int a = 0; a < array_len; a++) {
725  switch (old_type) {
726  case SDNA_TYPE_CHAR: {
727  const char value = *old_data;
728  old_value_i = value;
729  old_value_f = (double)value;
730  break;
731  }
732  case SDNA_TYPE_UCHAR: {
733  const uchar value = *((uchar *)old_data);
734  old_value_i = value;
735  old_value_f = (double)value;
736  break;
737  }
738  case SDNA_TYPE_SHORT: {
739  const short value = *((short *)old_data);
740  old_value_i = value;
741  old_value_f = (double)value;
742  break;
743  }
744  case SDNA_TYPE_USHORT: {
745  const ushort value = *((unsigned short *)old_data);
746  old_value_i = value;
747  old_value_f = (double)value;
748  break;
749  }
750  case SDNA_TYPE_INT: {
751  const int value = *((int *)old_data);
752  old_value_i = value;
753  old_value_f = (double)value;
754  break;
755  }
756  case SDNA_TYPE_FLOAT: {
757  const float value = *((float *)old_data);
758  /* `int64_t` range stored in a `uint64_t`. */
759  old_value_i = (uint64_t)(int64_t)value;
760  old_value_f = value;
761  break;
762  }
763  case SDNA_TYPE_DOUBLE: {
764  const double value = *((double *)old_data);
765  /* `int64_t` range stored in a `uint64_t`. */
766  old_value_i = (uint64_t)(int64_t)value;
767  old_value_f = value;
768  break;
769  }
770  case SDNA_TYPE_INT64: {
771  const int64_t value = *((int64_t *)old_data);
772  old_value_i = (uint64_t)value;
773  old_value_f = (double)value;
774  break;
775  }
776  case SDNA_TYPE_UINT64: {
777  const uint64_t value = *((uint64_t *)old_data);
778  old_value_i = value;
779  old_value_f = (double)value;
780  break;
781  }
782  case SDNA_TYPE_INT8: {
783  const int8_t value = *((int8_t *)old_data);
784  old_value_i = (uint64_t)value;
785  old_value_f = (double)value;
786  }
787  }
788 
789  switch (new_type) {
790  case SDNA_TYPE_CHAR:
791  *new_data = (char)old_value_i;
792  break;
793  case SDNA_TYPE_UCHAR:
794  *((unsigned char *)new_data) = (unsigned char)old_value_i;
795  break;
796  case SDNA_TYPE_SHORT:
797  *((short *)new_data) = (short)old_value_i;
798  break;
799  case SDNA_TYPE_USHORT:
800  *((unsigned short *)new_data) = (unsigned short)old_value_i;
801  break;
802  case SDNA_TYPE_INT:
803  *((int *)new_data) = (int)old_value_i;
804  break;
805  case SDNA_TYPE_FLOAT:
806  if (old_type < 2) {
807  old_value_f /= 255.0;
808  }
809  *((float *)new_data) = old_value_f;
810  break;
811  case SDNA_TYPE_DOUBLE:
812  if (old_type < 2) {
813  old_value_f /= 255.0;
814  }
815  *((double *)new_data) = old_value_f;
816  break;
817  case SDNA_TYPE_INT64:
818  *((int64_t *)new_data) = (int64_t)old_value_i;
819  break;
820  case SDNA_TYPE_UINT64:
821  *((uint64_t *)new_data) = old_value_i;
822  break;
823  case SDNA_TYPE_INT8:
824  *((int8_t *)new_data) = (int8_t)old_value_i;
825  break;
826  }
827 
828  old_data += oldlen;
829  new_data += curlen;
830  }
831 }
832 
833 static void cast_pointer_32_to_64(const int array_len,
834  const uint32_t *old_data,
835  uint64_t *new_data)
836 {
837  for (int a = 0; a < array_len; a++) {
838  new_data[a] = old_data[a];
839  }
840 }
841 
842 static void cast_pointer_64_to_32(const int array_len,
843  const uint64_t *old_data,
844  uint32_t *new_data)
845 {
846  /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
847  * pointers may lose uniqueness on truncation! (Hopefully this won't
848  * happen unless/until we ever get to multi-gigabyte .blend files...) */
849  for (int a = 0; a < array_len; a++) {
850  new_data[a] = old_data[a] >> 3;
851  }
852 }
853 
857 static bool elem_streq(const char *name, const char *oname)
858 {
859  int a = 0;
860 
861  while (1) {
862  if (name[a] != oname[a]) {
863  return false;
864  }
865  if (name[a] == '[' || oname[a] == '[') {
866  break;
867  }
868  if (name[a] == 0 || oname[a] == 0) {
869  break;
870  }
871  a++;
872  }
873  return true;
874 }
875 
885 static bool elem_exists_impl(
886  /* Expand SDNA. */
887  const char **types,
888  const char **names,
889  /* Regular args. */
890  const char *type,
891  const char *name,
892  const SDNA_Struct *old)
893 {
894  /* in old is the old struct */
895  for (int a = 0; a < old->members_len; a++) {
896  const SDNA_StructMember *member = &old->members[a];
897  const char *otype = types[member->type];
898  const char *oname = names[member->name];
899 
900  if (elem_streq(name, oname)) { /* name equal */
901  return STREQ(type, otype); /* type equal */
902  }
903  }
904  return false;
905 }
906 
910 static bool elem_exists(const SDNA *sdna,
911  const char *type,
912  const char *name,
913  const SDNA_Struct *old)
914 {
915  return elem_exists_impl(
916  /* Expand SDNA. */
917  sdna->types,
918  sdna->names,
919  /* Regular args. */
920  type,
921  name,
922  old);
923 }
924 
925 static bool elem_exists_alias(const SDNA *sdna,
926  const char *type,
927  const char *name,
928  const SDNA_Struct *old)
929 {
930  return elem_exists_impl(
931  /* Expand SDNA. */
932  sdna->alias.types,
933  sdna->alias.names,
934  /* Regular args. */
935  type,
936  name,
937  old);
938 }
939 
954 static int elem_offset(const SDNA *sdna,
955  const char *type,
956  const char *name,
957  const SDNA_Struct *old)
958 {
959  /* without arraypart, so names can differ: return old namenr and type */
960 
961  /* in old is the old struct */
962  int offset = 0;
963  for (int a = 0; a < old->members_len; a++) {
964  const SDNA_StructMember *member = &old->members[a];
965  const char *otype = sdna->types[member->type];
966  const char *oname = sdna->names[member->name];
967  if (elem_streq(name, oname)) { /* name equal */
968  if (STREQ(type, otype)) { /* type equal */
969  return offset;
970  }
971  break; /* Fail below. */
972  }
973  offset += DNA_elem_size_nr(sdna, member->type, member->name);
974  }
975  return -1;
976 }
977 
978 /* Each struct member belongs to one of the categories below. */
979 typedef enum eStructMemberCategory {
984 
986  const SDNA_StructMember *member)
987 {
988  const char *member_name = sdna->names[member->name];
989  if (ispointer(member_name)) {
991  }
992  const char *member_type_name = sdna->types[member->type];
993  if (DNA_struct_find(sdna, member_type_name)) {
995  }
997 }
998 
999 static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
1000 {
1001  const char *name = sdna->names[member->name];
1002  const int array_length = sdna->names_array_len[member->name];
1003  if (ispointer(name)) {
1004  return sdna->pointer_size * array_length;
1005  }
1006  const int type_size = sdna->types_size[member->type];
1007  return type_size * array_length;
1008 }
1009 
1010 void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
1011 {
1012  if (struct_nr == -1) {
1013  return;
1014  }
1015 
1016  const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1017 
1018  int offset_in_bytes = 0;
1019  for (int member_index = 0; member_index < struct_info->members_len; member_index++) {
1020  const SDNA_StructMember *member = &struct_info->members[member_index];
1021  const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
1022  char *member_data = data + offset_in_bytes;
1023  const char *member_type_name = sdna->types[member->type];
1024  const int member_array_length = sdna->names_array_len[member->name];
1025 
1026  switch (member_category) {
1028  const int substruct_size = sdna->types_size[member->type];
1029  const int substruct_nr = DNA_struct_find_nr(sdna, member_type_name);
1030  BLI_assert(substruct_nr != -1);
1031  for (int a = 0; a < member_array_length; a++) {
1032  DNA_struct_switch_endian(sdna, substruct_nr, member_data + a * substruct_size);
1033  }
1034  break;
1035  }
1037  switch (member->type) {
1038  case SDNA_TYPE_SHORT:
1039  case SDNA_TYPE_USHORT: {
1040  BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
1041  break;
1042  }
1043  case SDNA_TYPE_INT:
1044  case SDNA_TYPE_FLOAT: {
1045  /* NOTE: intentionally ignore long/ulong, because these could be 4 or 8 bytes.
1046  * Fortunately, we only use these types for runtime variables and only once for a
1047  * struct type that is no longer used. */
1048  BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
1049  break;
1050  }
1051  case SDNA_TYPE_INT64:
1052  case SDNA_TYPE_UINT64:
1053  case SDNA_TYPE_DOUBLE: {
1054  BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
1055  break;
1056  }
1057  default: {
1058  break;
1059  }
1060  }
1061  break;
1062  }
1064  /* See readfile.c (#bh4_from_bh8 swap endian argument),
1065  * this is only done when reducing the size of a pointer from 4 to 8. */
1066  if (sizeof(void *) < 8) {
1067  if (sdna->pointer_size == 8) {
1068  BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
1069  }
1070  }
1071  break;
1072  }
1073  }
1074  offset_in_bytes += get_member_size_in_bytes(sdna, member);
1075  }
1076 }
1077 
1078 typedef enum eReconstructStepType {
1086 
1087 typedef struct ReconstructStep {
1089  union {
1090  struct {
1093  int size;
1095  struct {
1096  int old_offset;
1097  int new_offset;
1102  struct {
1103  int old_offset;
1104  int new_offset;
1105  int array_len;
1107  struct {
1108  int old_offset;
1109  int new_offset;
1110  int array_len;
1114  } data;
1116 
1117 typedef struct DNA_ReconstructInfo {
1118  const SDNA *oldsdna;
1119  const SDNA *newsdna;
1120  const char *compare_flags;
1121 
1125 
1126 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1127  const int blocks,
1128  const int old_struct_nr,
1129  const int new_struct_nr,
1130  const char *old_blocks,
1131  char *new_blocks);
1132 
1142 static void reconstruct_struct(const DNA_ReconstructInfo *reconstruct_info,
1143  const int new_struct_nr,
1144  const char *old_block,
1145  char *new_block)
1146 {
1147  const ReconstructStep *steps = reconstruct_info->steps[new_struct_nr];
1148  const int step_count = reconstruct_info->step_counts[new_struct_nr];
1149 
1150  /* Execute all preprocessed steps. */
1151  for (int a = 0; a < step_count; a++) {
1152  const ReconstructStep *step = &steps[a];
1153  switch (step->type) {
1155  memcpy(new_block + step->data.memcpy.new_offset,
1156  old_block + step->data.memcpy.old_offset,
1157  step->data.memcpy.size);
1158  break;
1160  cast_primitive_type(step->data.cast_primitive.old_type,
1161  step->data.cast_primitive.new_type,
1162  step->data.cast_primitive.array_len,
1163  old_block + step->data.cast_primitive.old_offset,
1164  new_block + step->data.cast_primitive.new_offset);
1165  break;
1167  cast_pointer_64_to_32(step->data.cast_pointer.array_len,
1168  (const uint64_t *)(old_block + step->data.cast_pointer.old_offset),
1169  (uint32_t *)(new_block + step->data.cast_pointer.new_offset));
1170  break;
1172  cast_pointer_32_to_64(step->data.cast_pointer.array_len,
1173  (const uint32_t *)(old_block + step->data.cast_pointer.old_offset),
1174  (uint64_t *)(new_block + step->data.cast_pointer.new_offset));
1175  break;
1177  reconstruct_structs(reconstruct_info,
1178  step->data.substruct.array_len,
1179  step->data.substruct.old_struct_nr,
1180  step->data.substruct.new_struct_nr,
1181  old_block + step->data.substruct.old_offset,
1182  new_block + step->data.substruct.new_offset);
1183  break;
1185  /* Do nothing, because the memory block are zeroed (from #MEM_callocN).
1186  *
1187  * Note that the struct could be initialized with the default struct,
1188  * however this complicates versioning, especially with flags, see: D4500. */
1189  break;
1190  }
1191  }
1192 }
1193 
1195 static void reconstruct_structs(const DNA_ReconstructInfo *reconstruct_info,
1196  const int blocks,
1197  const int old_struct_nr,
1198  const int new_struct_nr,
1199  const char *old_blocks,
1200  char *new_blocks)
1201 {
1202  const SDNA_Struct *old_struct = reconstruct_info->oldsdna->structs[old_struct_nr];
1203  const SDNA_Struct *new_struct = reconstruct_info->newsdna->structs[new_struct_nr];
1204 
1205  const int old_block_size = reconstruct_info->oldsdna->types_size[old_struct->type];
1206  const int new_block_size = reconstruct_info->newsdna->types_size[new_struct->type];
1207 
1208  for (int a = 0; a < blocks; a++) {
1209  const char *old_block = old_blocks + a * old_block_size;
1210  char *new_block = new_blocks + a * new_block_size;
1211  reconstruct_struct(reconstruct_info, new_struct_nr, old_block, new_block);
1212  }
1213 }
1214 
1215 void *DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info,
1216  int old_struct_nr,
1217  int blocks,
1218  const void *old_blocks)
1219 {
1220  const SDNA *oldsdna = reconstruct_info->oldsdna;
1221  const SDNA *newsdna = reconstruct_info->newsdna;
1222 
1223  const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1224  const char *type_name = oldsdna->types[old_struct->type];
1225  const int new_struct_nr = DNA_struct_find_nr(newsdna, type_name);
1226 
1227  if (new_struct_nr == -1) {
1228  return NULL;
1229  }
1230 
1231  const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1232  const int new_block_size = newsdna->types_size[new_struct->type];
1233 
1234  char *new_blocks = MEM_callocN(blocks * new_block_size, "reconstruct");
1236  reconstruct_info, blocks, old_struct_nr, new_struct_nr, old_blocks, new_blocks);
1237  return new_blocks;
1238 }
1239 
1242  const SDNA_Struct *struct_info,
1243  const char *name,
1244  int *r_offset)
1245 {
1246  int offset = 0;
1247  for (int a = 0; a < struct_info->members_len; a++) {
1248  const SDNA_StructMember *member = &struct_info->members[a];
1249  const char *member_name = sdna->names[member->name];
1250  if (elem_streq(name, member_name)) {
1251  *r_offset = offset;
1252  return member;
1253  }
1254  offset += get_member_size_in_bytes(sdna, member);
1255  }
1256  return NULL;
1257 }
1258 
1260 static void init_reconstruct_step_for_member(const SDNA *oldsdna,
1261  const SDNA *newsdna,
1262  const char *compare_flags,
1263  const SDNA_Struct *old_struct,
1264  const SDNA_StructMember *new_member,
1265  const int new_member_offset,
1266  ReconstructStep *r_step)
1267 {
1268 
1269  /* Find the matching old member. */
1270  int old_member_offset;
1271  const char *new_name = newsdna->names[new_member->name];
1273  oldsdna, old_struct, new_name, &old_member_offset);
1274 
1275  if (old_member == NULL) {
1276  /* No matching member has been found in the old struct. */
1277  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1278  return;
1279  }
1280 
1281  /* Determine the member category of the old an new members. */
1282  const eStructMemberCategory new_category = get_struct_member_category(newsdna, new_member);
1283  const eStructMemberCategory old_category = get_struct_member_category(oldsdna, old_member);
1284 
1285  if (new_category != old_category) {
1286  /* Can only reconstruct the new member based on the old member, when the belong to the same
1287  * category. */
1288  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1289  return;
1290  }
1291 
1292  const int new_array_length = newsdna->names_array_len[new_member->name];
1293  const int old_array_length = oldsdna->names_array_len[old_member->name];
1294  const int shared_array_length = MIN2(new_array_length, old_array_length);
1295 
1296  const char *new_type_name = newsdna->types[new_member->type];
1297  const char *old_type_name = oldsdna->types[old_member->type];
1298 
1299  switch (new_category) {
1301  if (STREQ(new_type_name, old_type_name)) {
1302  const int old_struct_nr = DNA_struct_find_nr(oldsdna, old_type_name);
1303  BLI_assert(old_struct_nr != -1);
1304  enum eSDNA_StructCompare compare_flag = compare_flags[old_struct_nr];
1305  BLI_assert(compare_flag != SDNA_CMP_REMOVED);
1306  if (compare_flag == SDNA_CMP_EQUAL) {
1307  /* The old and new members are identical, just do a memcpy. */
1308  r_step->type = RECONSTRUCT_STEP_MEMCPY;
1309  r_step->data.memcpy.new_offset = new_member_offset;
1310  r_step->data.memcpy.old_offset = old_member_offset;
1311  r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1312  }
1313  else {
1314  const int new_struct_nr = DNA_struct_find_nr(newsdna, new_type_name);
1315  BLI_assert(new_struct_nr != -1);
1316 
1317  /* The old and new members are different, use recursion to reconstruct the
1318  * nested struct. */
1319  BLI_assert(compare_flag == SDNA_CMP_NOT_EQUAL);
1320  r_step->type = RECONSTRUCT_STEP_SUBSTRUCT;
1321  r_step->data.substruct.new_offset = new_member_offset;
1322  r_step->data.substruct.old_offset = old_member_offset;
1323  r_step->data.substruct.array_len = shared_array_length;
1324  r_step->data.substruct.new_struct_nr = new_struct_nr;
1325  r_step->data.substruct.old_struct_nr = old_struct_nr;
1326  }
1327  }
1328  else {
1329  /* Cannot match structs that have different names. */
1330  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1331  }
1332  break;
1333  }
1335  if (STREQ(new_type_name, old_type_name)) {
1336  /* Primitives with the same name cannot be different, so just do a memcpy. */
1337  r_step->type = RECONSTRUCT_STEP_MEMCPY;
1338  r_step->data.memcpy.new_offset = new_member_offset;
1339  r_step->data.memcpy.old_offset = old_member_offset;
1340  r_step->data.memcpy.size = newsdna->types_size[new_member->type] * shared_array_length;
1341  }
1342  else {
1343  /* The old and new primitive types are different, cast from the old to new type. */
1345  r_step->data.cast_primitive.array_len = shared_array_length;
1346  r_step->data.cast_primitive.new_offset = new_member_offset;
1347  r_step->data.cast_primitive.old_offset = old_member_offset;
1348  r_step->data.cast_primitive.new_type = new_member->type;
1349  r_step->data.cast_primitive.old_type = old_member->type;
1350  }
1351  break;
1352  }
1354  if (newsdna->pointer_size == oldsdna->pointer_size) {
1355  /* The pointer size is the same, so 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->pointer_size * shared_array_length;
1360  }
1361  else if (newsdna->pointer_size == 8 && oldsdna->pointer_size == 4) {
1362  /* Need to convert from 32 bit to 64 bit pointers. */
1364  r_step->data.cast_pointer.new_offset = new_member_offset;
1365  r_step->data.cast_pointer.old_offset = old_member_offset;
1366  r_step->data.cast_pointer.array_len = shared_array_length;
1367  }
1368  else if (newsdna->pointer_size == 4 && oldsdna->pointer_size == 8) {
1369  /* Need to convert from 64 bit to 32 bit pointers. */
1371  r_step->data.cast_pointer.new_offset = new_member_offset;
1372  r_step->data.cast_pointer.old_offset = old_member_offset;
1373  r_step->data.cast_pointer.array_len = shared_array_length;
1374  }
1375  else {
1376  BLI_assert_msg(0, "invalid pointer size");
1377  r_step->type = RECONSTRUCT_STEP_INIT_ZERO;
1378  }
1379  break;
1380  }
1381  }
1382 }
1383 
1385 static void print_reconstruct_step(ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
1386 {
1387  switch (step->type) {
1389  printf("init zero");
1390  break;
1391  }
1392  case RECONSTRUCT_STEP_MEMCPY: {
1393  printf("memcpy, size: %d, old offset: %d, new offset: %d",
1394  step->data.memcpy.size,
1395  step->data.memcpy.old_offset,
1396  step->data.memcpy.new_offset);
1397  break;
1398  }
1400  printf(
1401  "cast element, old type: %d ('%s'), new type: %d ('%s'), old offset: %d, new offset: "
1402  "%d, length: %d",
1403  (int)step->data.cast_primitive.old_type,
1404  oldsdna->types[step->data.cast_primitive.old_type],
1405  (int)step->data.cast_primitive.new_type,
1406  newsdna->types[step->data.cast_primitive.new_type],
1407  step->data.cast_primitive.old_offset,
1408  step->data.cast_primitive.new_offset,
1409  step->data.cast_primitive.array_len);
1410  break;
1411  }
1413  printf("pointer to 32, old offset: %d, new offset: %d, length: %d",
1414  step->data.cast_pointer.old_offset,
1415  step->data.cast_pointer.new_offset,
1416  step->data.cast_pointer.array_len);
1417  break;
1418  }
1420  printf("pointer to 64, old offset: %d, new offset: %d, length: %d",
1421  step->data.cast_pointer.old_offset,
1422  step->data.cast_pointer.new_offset,
1423  step->data.cast_pointer.array_len);
1424  break;
1425  }
1427  printf(
1428  "substruct, old offset: %d, new offset: %d, new struct: %d ('%s', size per struct: %d), "
1429  "length: %d",
1430  step->data.substruct.old_offset,
1431  step->data.substruct.new_offset,
1432  step->data.substruct.new_struct_nr,
1433  newsdna->types[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1434  newsdna->types_size[newsdna->structs[step->data.substruct.new_struct_nr]->type],
1435  step->data.substruct.array_len);
1436  break;
1437  }
1438  }
1439 }
1440 
1446  const SDNA *newsdna,
1447  const char *compare_flags,
1448  const SDNA_Struct *old_struct,
1449  const SDNA_Struct *new_struct)
1450 {
1452  new_struct->members_len, sizeof(ReconstructStep), __func__);
1453 
1454  int new_member_offset = 0;
1455  for (int new_member_index = 0; new_member_index < new_struct->members_len; new_member_index++) {
1456  const SDNA_StructMember *new_member = &new_struct->members[new_member_index];
1458  newsdna,
1459  compare_flags,
1460  old_struct,
1461  new_member,
1462  new_member_offset,
1463  &steps[new_member_index]);
1464  new_member_offset += get_member_size_in_bytes(newsdna, new_member);
1465  }
1466 
1467  return steps;
1468 }
1469 
1471 static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
1472 {
1473  int new_step_count = 0;
1474  for (int a = 0; a < old_step_count; a++) {
1475  ReconstructStep *step = &steps[a];
1476  switch (step->type) {
1478  /* These steps are simply removed. */
1479  break;
1481  if (new_step_count > 0) {
1482  /* Try to merge this memcpy step with the previous one. */
1483  ReconstructStep *prev_step = &steps[new_step_count - 1];
1484  if (prev_step->type == RECONSTRUCT_STEP_MEMCPY) {
1485  /* Check if there are no bytes between the blocks to copy. */
1486  if (prev_step->data.memcpy.old_offset + prev_step->data.memcpy.size ==
1487  step->data.memcpy.old_offset &&
1488  prev_step->data.memcpy.new_offset + prev_step->data.memcpy.size ==
1489  step->data.memcpy.new_offset) {
1490  prev_step->data.memcpy.size += step->data.memcpy.size;
1491  break;
1492  }
1493  }
1494  }
1495  steps[new_step_count] = *step;
1496  new_step_count++;
1497  break;
1502  /* These steps are not changed at all for now. It should be possible to merge consecutive
1503  * steps of the same type, but it is not really worth it. */
1504  steps[new_step_count] = *step;
1505  new_step_count++;
1506  break;
1507  }
1508  }
1509  return new_step_count;
1510 }
1511 
1513  const SDNA *newsdna,
1514  const char *compare_flags)
1515 {
1516  DNA_ReconstructInfo *reconstruct_info = MEM_callocN(sizeof(DNA_ReconstructInfo), __func__);
1517  reconstruct_info->oldsdna = oldsdna;
1518  reconstruct_info->newsdna = newsdna;
1519  reconstruct_info->compare_flags = compare_flags;
1520  reconstruct_info->step_counts = MEM_malloc_arrayN(newsdna->structs_len, sizeof(int), __func__);
1521  reconstruct_info->steps = MEM_malloc_arrayN(
1522  newsdna->structs_len, sizeof(ReconstructStep *), __func__);
1523 
1524  /* Generate reconstruct steps for all structs. */
1525  for (int new_struct_nr = 0; new_struct_nr < newsdna->structs_len; new_struct_nr++) {
1526  const SDNA_Struct *new_struct = newsdna->structs[new_struct_nr];
1527  const char *new_struct_name = newsdna->types[new_struct->type];
1528  const int old_struct_nr = DNA_struct_find_nr(oldsdna, new_struct_name);
1529  if (old_struct_nr < 0) {
1530  reconstruct_info->steps[new_struct_nr] = NULL;
1531  reconstruct_info->step_counts[new_struct_nr] = 0;
1532  continue;
1533  }
1534  const SDNA_Struct *old_struct = oldsdna->structs[old_struct_nr];
1536  oldsdna, newsdna, compare_flags, old_struct, new_struct);
1537 
1538  /* Comment the line below to skip the compression for debugging purposes. */
1539  const int steps_len = compress_reconstruct_steps(steps, new_struct->members_len);
1540 
1541  reconstruct_info->steps[new_struct_nr] = steps;
1542  reconstruct_info->step_counts[new_struct_nr] = steps_len;
1543 
1544 /* This is useful when debugging the reconstruct steps. */
1545 #if 0
1546  printf("%s: \n", new_struct_name);
1547  for (int a = 0; a < steps_len; a++) {
1548  printf(" ");
1549  print_reconstruct_step(&steps[a], oldsdna, newsdna);
1550  printf("\n");
1551  }
1552 #endif
1554  }
1555 
1556  return reconstruct_info;
1557 }
1558 
1560 {
1561  for (int a = 0; a < reconstruct_info->newsdna->structs_len; a++) {
1562  if (reconstruct_info->steps[a] != NULL) {
1563  MEM_freeN(reconstruct_info->steps[a]);
1564  }
1565  }
1566  MEM_freeN(reconstruct_info->steps);
1567  MEM_freeN(reconstruct_info->step_counts);
1568  MEM_freeN(reconstruct_info);
1569 }
1570 
1571 int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
1572 {
1573  const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1574  BLI_assert(SDNAnr != -1);
1575  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1576  return elem_offset(sdna, vartype, name, spo);
1577 }
1578 
1579 bool DNA_struct_find(const SDNA *sdna, const char *stype)
1580 {
1581  return DNA_struct_find_nr(sdna, stype) != -1;
1582 }
1583 
1584 bool DNA_struct_elem_find(const SDNA *sdna,
1585  const char *stype,
1586  const char *vartype,
1587  const char *name)
1588 {
1589  const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1590 
1591  if (SDNAnr != -1) {
1592  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1593  const bool found = elem_exists(sdna, vartype, name, spo);
1594 
1595  if (found) {
1596  return true;
1597  }
1598  }
1599  return false;
1600 }
1601 
1603  const char *stype,
1604  const char *vartype,
1605  const char *name)
1606 {
1607  const int SDNAnr = DNA_struct_alias_find_nr(sdna, stype);
1608 
1609  if (SDNAnr != -1) {
1610  const SDNA_Struct *const spo = sdna->structs[SDNAnr];
1611  const bool found = elem_exists_alias(sdna, vartype, name, spo);
1612 
1613  if (found) {
1614  return true;
1615  }
1616  }
1617  return false;
1618 }
1619 
1620 int DNA_elem_type_size(const eSDNA_Type elem_nr)
1621 {
1622  /* should contain all enum types */
1623  switch (elem_nr) {
1624  case SDNA_TYPE_CHAR:
1625  case SDNA_TYPE_UCHAR:
1626  case SDNA_TYPE_INT8:
1627  return 1;
1628  case SDNA_TYPE_SHORT:
1629  case SDNA_TYPE_USHORT:
1630  return 2;
1631  case SDNA_TYPE_INT:
1632  case SDNA_TYPE_FLOAT:
1633  return 4;
1634  case SDNA_TYPE_DOUBLE:
1635  case SDNA_TYPE_INT64:
1636  case SDNA_TYPE_UINT64:
1637  return 8;
1638  }
1639 
1640  /* weak */
1641  return 8;
1642 }
1643 
1644 /* -------------------------------------------------------------------- */
1648 static bool DNA_sdna_patch_struct_nr(SDNA *sdna,
1649  const int struct_name_old_nr,
1650  const char *struct_name_new)
1651 {
1652  BLI_assert(DNA_struct_find_nr(DNA_sdna_current_get(), struct_name_new) != -1);
1653  const SDNA_Struct *struct_info = sdna->structs[struct_name_old_nr];
1654 #ifdef WITH_DNA_GHASH
1655  BLI_ghash_remove(sdna->structs_map, (void *)sdna->types[struct_info->type], NULL, NULL);
1657  sdna->structs_map, (void *)struct_name_new, POINTER_FROM_INT(struct_name_old_nr));
1658 #endif
1659  sdna->types[struct_info->type] = struct_name_new;
1660  return true;
1661 }
1662 bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new)
1663 {
1664  const int struct_name_old_nr = DNA_struct_find_nr(sdna, struct_name_old);
1665  if (struct_name_old_nr != -1) {
1666  return DNA_sdna_patch_struct_nr(sdna, struct_name_old_nr, struct_name_new);
1667  }
1668  return false;
1669 }
1670 
1671 /* Make public if called often with same struct (avoid duplicate lookups). */
1673  const int struct_name_nr,
1674  const char *elem_old,
1675  const char *elem_new)
1676 {
1677  /* These names aren't handled here (it's not used).
1678  * Ensure they are never used or we get out of sync arrays. */
1679  BLI_assert(sdna->alias.names == NULL);
1680  const int elem_old_len = strlen(elem_old);
1681  const int elem_new_len = strlen(elem_new);
1682  BLI_assert(elem_new != NULL);
1683  SDNA_Struct *sp = sdna->structs[struct_name_nr];
1684  for (int elem_index = sp->members_len; elem_index > 0; elem_index--) {
1685  SDNA_StructMember *member = &sp->members[elem_index];
1686  const char *elem_old_full = sdna->names[member->name];
1687  /* Start & end offsets in 'elem_old_full'. */
1688  uint elem_old_full_offset_start;
1689  if (DNA_elem_id_match(elem_old, elem_old_len, elem_old_full, &elem_old_full_offset_start)) {
1690  if (sdna->mem_arena == NULL) {
1692  }
1693  const char *elem_new_full = DNA_elem_id_rename(sdna->mem_arena,
1694  elem_old,
1695  elem_old_len,
1696  elem_new,
1697  elem_new_len,
1698  elem_old_full,
1699  strlen(elem_old_full),
1700  elem_old_full_offset_start);
1701 
1702  if (sdna->names_len == sdna->names_len_alloc) {
1703  sdna->names_len_alloc += 64;
1704  sdna->names = MEM_recallocN((void *)sdna->names,
1705  sizeof(*sdna->names) * sdna->names_len_alloc);
1707  (void *)sdna->names_array_len, sizeof(*sdna->names_array_len) * sdna->names_len_alloc);
1708  }
1709  const short name_nr_prev = member->name;
1710  member->name = sdna->names_len++;
1711  sdna->names[member->name] = elem_new_full;
1712  sdna->names_array_len[member->name] = sdna->names_array_len[name_nr_prev];
1713 
1714  return true;
1715  }
1716  }
1717  return false;
1718 }
1720  const char *struct_name,
1721  const char *elem_old,
1722  const char *elem_new)
1723 {
1724  const int struct_name_nr = DNA_struct_find_nr(sdna, struct_name);
1725  if (struct_name_nr != -1) {
1726  return DNA_sdna_patch_struct_member_nr(sdna, struct_name_nr, elem_old, elem_new);
1727  }
1728  return false;
1729 }
1730 
1733 /* -------------------------------------------------------------------- */
1745 static void sdna_expand_names(SDNA *sdna)
1746 {
1747  int names_expand_len = 0;
1748  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1749  const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1750  names_expand_len += struct_old->members_len;
1751  }
1752  const char **names_expand = MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__);
1753  short *names_array_len_expand = MEM_mallocN(sizeof(*names_array_len_expand) * names_expand_len,
1754  __func__);
1755 
1756  int names_expand_index = 0;
1757  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1758  /* We can't edit this memory 'sdna->structs' points to (read-only `datatoc` file). */
1759  const SDNA_Struct *struct_old = sdna->structs[struct_nr];
1760 
1761  const int array_size = sizeof(short) * 2 + sizeof(SDNA_StructMember) * struct_old->members_len;
1762  SDNA_Struct *struct_new = BLI_memarena_alloc(sdna->mem_arena, array_size);
1763  memcpy(struct_new, struct_old, array_size);
1764  sdna->structs[struct_nr] = struct_new;
1765 
1766  for (int i = 0; i < struct_old->members_len; i++) {
1767  const SDNA_StructMember *member_old = &struct_old->members[i];
1768  SDNA_StructMember *member_new = &struct_new->members[i];
1769 
1770  names_expand[names_expand_index] = sdna->names[member_old->name];
1771  names_array_len_expand[names_expand_index] = sdna->names_array_len[member_old->name];
1772 
1773  BLI_assert(names_expand_index < SHRT_MAX);
1774  member_new->name = names_expand_index;
1775  names_expand_index++;
1776  }
1777  }
1778  MEM_freeN((void *)sdna->names);
1779  sdna->names = names_expand;
1780 
1781  MEM_freeN((void *)sdna->names_array_len);
1782  sdna->names_array_len = names_array_len_expand;
1783 
1784  sdna->names_len = names_expand_len;
1785 }
1786 
1789  const char *struct_name_static,
1790  const char *elem_static_full)
1791 {
1792  const int elem_static_full_len = strlen(elem_static_full);
1793  char *elem_static = alloca(elem_static_full_len + 1);
1794  const int elem_static_len = DNA_elem_id_strip_copy(elem_static, elem_static_full);
1795  const char *str_pair[2] = {struct_name_static, elem_static};
1796  const char *elem_alias = BLI_ghash_lookup(elem_map_alias_from_static, str_pair);
1797  if (elem_alias) {
1798  return DNA_elem_id_rename(sdna->mem_arena,
1799  elem_static,
1800  elem_static_len,
1801  elem_alias,
1802  strlen(elem_alias),
1803  elem_static_full,
1804  elem_static_full_len,
1805  DNA_elem_id_offset_start(elem_static_full));
1806  }
1807  return NULL;
1808 }
1809 
1811 {
1812  /* We may want this to be optional later. */
1813  const bool use_legacy_hack = true;
1814 
1815  if (sdna->mem_arena == NULL) {
1817  }
1818 
1821 
1824 
1825  if (sdna->alias.types == NULL) {
1826  sdna->alias.types = MEM_mallocN(sizeof(*sdna->alias.types) * sdna->types_len, __func__);
1827  for (int type_nr = 0; type_nr < sdna->types_len; type_nr++) {
1828  const char *struct_name_static = sdna->types[type_nr];
1829 
1830  if (use_legacy_hack) {
1831  struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1832  }
1833 
1834  sdna->alias.types[type_nr] = BLI_ghash_lookup_default(
1835  struct_map_alias_from_static, struct_name_static, (void *)struct_name_static);
1836  }
1837  }
1838 
1839  if (sdna->alias.names == NULL) {
1840  sdna_expand_names(sdna);
1841  sdna->alias.names = MEM_mallocN(sizeof(*sdna->alias.names) * sdna->names_len, __func__);
1842  for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) {
1843  const SDNA_Struct *struct_info = sdna->structs[struct_nr];
1844  const char *struct_name_static = sdna->types[struct_info->type];
1845 
1846  if (use_legacy_hack) {
1847  struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static);
1848  }
1849 
1850  for (int a = 0; a < struct_info->members_len; a++) {
1851  const SDNA_StructMember *member = &struct_info->members[a];
1852  const char *elem_alias_full = dna_sdna_alias_from_static_elem_full(
1853  sdna, elem_map_alias_from_static, struct_name_static, sdna->names[member->name]);
1854  if (elem_alias_full != NULL) {
1855  sdna->alias.names[member->name] = elem_alias_full;
1856  }
1857  else {
1858  sdna->alias.names[member->name] = sdna->names[member->name];
1859  }
1860  }
1861  }
1862  }
1865 }
1866 
1868 {
1870 #ifdef WITH_DNA_GHASH
1871  /* create a ghash lookup to speed up */
1872  struct GHash *structs_map = BLI_ghash_str_new_ex(__func__, sdna->structs_len);
1873  for (intptr_t nr = 0; nr < sdna->structs_len; nr++) {
1874  const SDNA_Struct *struct_info = sdna->structs[nr];
1876  structs_map, (void *)sdna->alias.types[struct_info->type], POINTER_FROM_INT(nr));
1877  }
1878  sdna->alias.structs_map = structs_map;
1879 #else
1880  UNUSED_VARS(sdna);
1881 #endif
1882 }
1883 
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#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)
Definition: endian_switch.c:31
void BLI_endian_switch_uint64_array(uint64_t *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:71
void BLI_endian_switch_int64_array(int64_t *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:61
void BLI_endian_switch_int16_array(short *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:11
BLI_INLINE void BLI_endian_switch_int16(short *val) ATTR_NONNULL(1)
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
void * BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:741
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:748
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:94
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:64
#define BLI_MEMARENA_STD_BUFSIZE
Definition: BLI_memarena.h:20
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:116
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
unsigned short ushort
Definition: BLI_sys_types.h:68
#define UNUSED_VARS(...)
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#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:47
eSDNA_Type
Definition: DNA_genfile.h:35
@ SDNA_TYPE_CHAR
Definition: DNA_genfile.h:36
@ SDNA_TYPE_INT
Definition: DNA_genfile.h:40
@ SDNA_TYPE_UINT64
Definition: DNA_genfile.h:49
@ SDNA_TYPE_DOUBLE
Definition: DNA_genfile.h:44
@ SDNA_TYPE_SHORT
Definition: DNA_genfile.h:38
@ SDNA_TYPE_UCHAR
Definition: DNA_genfile.h:37
@ SDNA_TYPE_INT8
Definition: DNA_genfile.h:50
@ SDNA_TYPE_INT64
Definition: DNA_genfile.h:48
@ SDNA_TYPE_FLOAT
Definition: DNA_genfile.h:43
@ SDNA_TYPE_USHORT
Definition: DNA_genfile.h:39
const unsigned char DNAstr[]
const int DNAlen
eSDNA_StructCompare
Definition: DNA_genfile.h:56
@ SDNA_CMP_EQUAL
Definition: DNA_genfile.h:62
@ SDNA_CMP_REMOVED
Definition: DNA_genfile.h:59
@ SDNA_CMP_UNKNOWN
Definition: DNA_genfile.h:67
@ SDNA_CMP_NOT_EQUAL
Definition: DNA_genfile.h:65
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:304
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:1787
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:519
int DNA_elem_size_nr(const SDNA *sdna, short type, short name)
Definition: dna_genfile.c:164
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:1672
eReconstructStepType
Definition: dna_genfile.c:1078
@ RECONSTRUCT_STEP_CAST_POINTER_TO_32
Definition: dna_genfile.c:1081
@ RECONSTRUCT_STEP_CAST_POINTER_TO_64
Definition: dna_genfile.c:1082
@ RECONSTRUCT_STEP_INIT_ZERO
Definition: dna_genfile.c:1084
@ RECONSTRUCT_STEP_SUBSTRUCT
Definition: dna_genfile.c:1083
@ RECONSTRUCT_STEP_CAST_PRIMITIVE
Definition: dna_genfile.c:1080
@ RECONSTRUCT_STEP_MEMCPY
Definition: dna_genfile.c:1079
int DNA_elem_type_size(const eSDNA_Type elem_nr)
Definition: dna_genfile.c:1620
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:1195
static bool ispointer(const char *name)
Definition: dna_genfile.c:158
bool DNA_struct_find(const SDNA *sdna, const char *stype)
Definition: dna_genfile.c:1579
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:885
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:709
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:1260
bool DNA_struct_alias_elem_find(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1602
static void cast_pointer_64_to_32(const int array_len, const uint64_t *old_data, uint32_t *new_data)
Definition: dna_genfile.c:842
static void sdna_expand_names(SDNA *sdna)
Definition: dna_genfile.c:1745
BLI_INLINE const char * pad_up_4(const char *ptr)
Definition: dna_genfile.c:296
static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
Definition: dna_genfile.c:999
static bool DNA_sdna_patch_struct_nr(SDNA *sdna, const int struct_name_old_nr, const char *struct_name_new)
Definition: dna_genfile.c:1648
static void print_reconstruct_step(ReconstructStep *step, const SDNA *oldsdna, const SDNA *newsdna)
Definition: dna_genfile.c:1385
#define MAKE_ID(a, b, c, d)
Definition: dna_genfile.c:118
static bool elem_exists_alias(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:925
static bool elem_exists(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:910
void DNA_sdna_current_free(void)
Definition: dna_genfile.c:572
static eStructMemberCategory get_struct_member_category(const SDNA *sdna, const SDNA_StructMember *member)
Definition: dna_genfile.c:985
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:586
void DNA_sdna_current_init(void)
Definition: dna_genfile.c:561
void DNA_reconstruct_info_free(DNA_ReconstructInfo *reconstruct_info)
Definition: dna_genfile.c:1559
bool DNA_struct_elem_find(const SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1584
void DNA_sdna_alias_data_ensure(SDNA *sdna)
Definition: dna_genfile.c:1810
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:1241
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:202
eStructMemberCategory
Definition: dna_genfile.c:979
@ STRUCT_MEMBER_CATEGORY_STRUCT
Definition: dna_genfile.c:980
@ STRUCT_MEMBER_CATEGORY_POINTER
Definition: dna_genfile.c:982
@ STRUCT_MEMBER_CATEGORY_PRIMITIVE
Definition: dna_genfile.c:981
static int elem_offset(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:954
DNA_ReconstructInfo * DNA_reconstruct_info_create(const SDNA *oldsdna, const SDNA *newsdna, const char *compare_flags)
Definition: dna_genfile.c:1512
static void cast_pointer_32_to_64(const int array_len, const uint32_t *old_data, uint64_t *new_data)
Definition: dna_genfile.c:833
int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
Definition: dna_genfile.c:261
void DNA_sdna_free(SDNA *sdna)
Definition: dna_genfile.c:123
static bool elem_streq(const char *name, const char *oname)
Definition: dna_genfile.c:857
struct DNA_ReconstructInfo DNA_ReconstructInfo
void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
Definition: dna_genfile.c:1010
bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new)
Definition: dna_genfile.c:1662
void DNA_sdna_alias_data_ensure_structs_map(SDNA *sdna)
Definition: dna_genfile.c:1867
void * DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info, int old_struct_nr, int blocks, const void *old_blocks)
Definition: dna_genfile.c:1215
int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
Definition: dna_genfile.c:286
int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
Definition: dna_genfile.c:1571
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:1445
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:1142
static SDNA * g_sdna
Definition: dna_genfile.c:559
const char * DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna)
Definition: dna_genfile.c:663
int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
Definition: dna_genfile.c:245
const struct SDNA * DNA_sdna_current_get(void)
Definition: dna_genfile.c:566
bool DNA_sdna_patch_struct_member(SDNA *sdna, const char *struct_name, const char *elem_old, const char *elem_new)
Definition: dna_genfile.c:1719
static int compress_reconstruct_steps(ReconstructStep *steps, const int old_step_count)
Definition: dna_genfile.c:1471
int DNA_struct_find_nr(const SDNA *sdna, const char *str)
Definition: dna_genfile.c:280
const char * DNA_struct_rename_legacy_hack_static_from_alias(const char *name)
Definition: dna_utils.c:271
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:128
void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash **r_elem_map)
Definition: dna_utils.c:181
uint DNA_elem_id_offset_start(const char *elem_full)
Definition: dna_utils.c:72
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:110
const char * DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
Definition: dna_utils.c:294
uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src)
Definition: dna_utils.c:90
int DNA_elem_array_size(const char *str)
Definition: dna_utils.c:27
@ DNA_RENAME_ALIAS_FROM_STATIC
Definition: dna_utils.h:54
int len
Definition: draw_manager.c:108
#define str(s)
#define UINT_MAX
Definition: hash_md5.c:43
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
static int types_len
Definition: makesdna.c:62
static char ** names
Definition: makesdna.c:65
static int structs_len
Definition: makesdna.c:63
static char ** types
Definition: makesdna.c:67
static short ** structs
Definition: makesdna.c:84
GHash * elem_map_alias_from_static
Definition: makesdna.c:90
GHash * struct_map_alias_from_static
Definition: makesdna.c:88
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const int steps
Definition: sky_nishita.cpp:19
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
Definition: dna_genfile.c:1123
const SDNA * newsdna
Definition: dna_genfile.c:1119
const SDNA * oldsdna
Definition: dna_genfile.c:1118
const char * compare_flags
Definition: dna_genfile.c:1120
eSDNA_Type old_type
Definition: dna_genfile.c:1099
struct ReconstructStep::@1138::@1142 substruct
eReconstructStepType type
Definition: dna_genfile.c:1088
struct ReconstructStep::@1138::@1141 cast_pointer
union ReconstructStep::@1138 data
struct ReconstructStep::@1138::@1140 cast_primitive
eSDNA_Type new_type
Definition: dna_genfile.c:1100
struct ReconstructStep::@1138::@1139 memcpy
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
struct SDNA::@1048 alias
int data_len
struct MemArena * mem_arena
const char ** types
int pointer_size
const char * data
bool data_alloc
const char ** names
PointerRNA * ptr
Definition: wm_files.c:3480