99ab29fbdcc6bedc45e61378fbf771d102e06ace
[blender.git] / source / blender / makesdna / intern / dna_genfile.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * DNA handling
27  */
28
29 /** \file blender/makesdna/intern/dna_genfile.c
30  *  \ingroup DNA
31  *
32  * Lowest-level functions for decoding the parts of a saved .blend
33  * file, including interpretation of its SDNA block and conversion of
34  * contents of other parts according to the differences between that
35  * SDNA and the SDNA of the current (running) version of Blender.
36  */
37
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN
44
45 #include "BLI_utildefines.h"
46 #include "BLI_endian_switch.h"
47
48 #ifdef WITH_DNA_GHASH
49 #  include "BLI_ghash.h"
50 #endif
51
52 #include "DNA_genfile.h"
53 #include "DNA_sdna_types.h" // for SDNA ;-)
54
55 /**
56  * \section dna_genfile Overview
57  *
58  * - please note: no builtin security to detect input of double structs
59  * - if you want a struct not to be in DNA file: add two hash marks above it (#<enter>#<enter>)
60  *
61  * Structure DNA data is added to each blender file and to each executable, this to detect
62  * in .blend files new variables in structs, changed array sizes, etc. It's also used for
63  * converting endian and pointer size (32-64 bits)
64  * As an extra, Python uses a call to detect run-time the contents of a blender struct.
65  *
66  * Create a structDNA: only needed when one of the input include (.h) files change.
67  * File Syntax:
68  * \code{.unparsed}
69  *     SDNA (4 bytes) (magic number)
70  *     NAME (4 bytes)
71  *     <nr> (4 bytes) amount of names (int)
72  *     <string>
73  *     <string>
74  *     ...
75  *     ...
76  *     TYPE (4 bytes)
77  *     <nr> amount of types (int)
78  *     <string>
79  *     <string>
80  *     ...
81  *     ...
82  *     TLEN (4 bytes)
83  *     <len> (short) the lengths of types
84  *     <len>
85  *     ...
86  *     ...
87  *     STRC (4 bytes)
88  *     <nr> amount of structs (int)
89  *     <typenr><nr_of_elems> <typenr><namenr> <typenr><namenr> ...
90  * \endcode
91  *
92  *  **Remember to read/write integer and short aligned!**
93  *
94  *  While writing a file, the names of a struct is indicated with a type number,
95  *  to be found with: ``type = DNA_struct_find_nr(SDNA *, const char *)``
96  *  The value of ``type`` corresponds with the index within the structs array
97  *
98  *  For the moment: the complete DNA file is included in a .blend file. For
99  *  the future we can think of smarter methods, like only included the used
100  *  structs. Only needed to keep a file short though...
101  *
102  * ALLOWED AND TESTED CHANGES IN STRUCTS:
103  *  - type change (a char to float will be divided by 255)
104  *  - location within a struct (everthing can be randomly mixed up)
105  *  - struct within struct (within struct etc), this is recursive
106  *  - adding new elements, will be default initialized zero
107  *  - removing elements
108  *  - change of array sizes
109  *  - change of a pointer type: when the name doesn't change the contents is copied
110  *
111  * NOT YET:
112  *  - array (``vec[3]``) to float struct (``vec3f``)
113  *
114  * DONE:
115  *  - endian compatibility
116  *  - pointer conversion (32-64 bits)
117  *
118  * IMPORTANT:
119  *  - do not use #defines in structs for array lengths, this cannot be read by the dna functions
120  *  - do not use uint, but unsigned int instead, ushort and ulong are allowed
121  *  - only use a long in Blender if you want this to be the size of a pointer. so it is
122  *    32 bits or 64 bits, dependent at the cpu architecture
123  *  - chars are always unsigned
124  *  - alignment of variables has to be done in such a way, that any system does
125  *    not create 'padding' (gaps) in structures. So make sure that:
126  *    - short: 2 aligned
127  *    - int: 4 aligned
128  *    - float: 4 aligned
129  *    - double: 8 aligned
130  *    - long: 8 aligned
131  *    - struct: 8 aligned
132  *  - the sdna functions have several error prints builtin, always check blender running from a console.
133  *
134  */
135
136 /* ************************* ENDIAN STUFF ********************** */
137
138 /**
139  * converts a short between big/little endian.
140  */
141 static short le_short(short temp)
142 {
143         short new;
144         char *rt = (char *)&temp, *rtn = (char *)&new;
145
146         rtn[0] = rt[1];
147         rtn[1] = rt[0];
148
149         return new;
150 }
151
152 /**
153  * converts an int between big/little endian.
154  */
155 static int le_int(int temp)
156 {
157         int new;
158         char *rt = (char *)&temp, *rtn = (char *)&new;
159
160         rtn[0] = rt[3];
161         rtn[1] = rt[2];
162         rtn[2] = rt[1];
163         rtn[3] = rt[0];
164
165         return new;
166 }
167
168
169 /* ************************* MAKE DNA ********************** */
170
171 /* allowed duplicate code from makesdna.c */
172
173 /**
174  * parses the "[n]" on the end of an array name and returns the number of array elements n.
175  */
176 int DNA_elem_array_size(const char *str)
177 {
178         int a, mul = 1;
179         const char *cp = NULL;
180
181         for (a = 0; str[a]; a++) {
182                 if (str[a] == '[') {
183                         cp = &(str[a + 1]);
184                 }
185                 else if (str[a] == ']' && cp) {
186                         mul *= atoi(cp);
187                 }
188         }
189
190         return mul;
191 }
192
193 /* ************************* END MAKE DNA ********************** */
194
195 /* ************************* DIV ********************** */
196
197 void DNA_sdna_free(SDNA *sdna)
198 {
199         MEM_freeN(sdna->data);
200         MEM_freeN((void *)sdna->names);
201         MEM_freeN(sdna->types);
202         MEM_freeN(sdna->structs);
203
204 #ifdef WITH_DNA_GHASH
205         BLI_ghash_free(sdna->structs_map, NULL, NULL);
206 #endif
207
208         MEM_freeN(sdna);
209 }
210
211 /**
212  * Return true if the name indicates a pointer of some kind.
213  */
214 static bool ispointer(const char *name)
215 {
216         /* check if pointer or function pointer */
217         return (name[0] == '*' || (name[0] == '(' && name[1] == '*'));
218 }
219
220 /**
221  * Returns the size of struct fields of the specified type and name.
222  *
223  * \param type  Index into sdna->types/typelens
224  * \param name  Index into sdna->names,
225  * needed to extract possible pointer/array information.
226  */
227 static int elementsize(const SDNA *sdna, short type, short name)
228 {
229         int mul, namelen, len;
230         const char *cp;
231         
232         cp = sdna->names[name];
233         len = 0;
234         
235         namelen = strlen(cp);
236         /* is it a pointer or function pointer? */
237         if (ispointer(cp)) {
238                 /* has the name an extra length? (array) */
239                 mul = 1;
240                 if (cp[namelen - 1] == ']') {
241                         mul = DNA_elem_array_size(cp);
242                 }
243                 
244                 len = sdna->pointerlen * mul;
245         }
246         else if (sdna->typelens[type]) {
247                 /* has the name an extra length? (array) */
248                 mul = 1;
249                 if (cp[namelen - 1] == ']') {
250                         mul = DNA_elem_array_size(cp);
251                 }
252                 
253                 len = mul * sdna->typelens[type];
254                 
255         }
256         
257         return len;
258 }
259
260 #if 0
261 static void printstruct(SDNA *sdna, short strnr)
262 {
263         /* is for debug */
264         int b, nr;
265         short *sp;
266         
267         sp = sdna->structs[strnr];
268         
269         printf("struct %s\n", sdna->types[sp[0]]);
270         nr = sp[1];
271         sp += 2;
272         
273         for (b = 0; b < nr; b++, sp += 2) {
274                 printf("   %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]);
275         }
276 }
277 #endif
278
279 /**
280  * Returns a pointer to the start of the struct info for the struct with the specified name.
281  */
282 static short *findstruct_name(SDNA *sdna, const char *str)
283 {
284         int a;
285         short *sp = NULL;
286
287
288         for (a = 0; a < sdna->nr_structs; a++) {
289
290                 sp = sdna->structs[a];
291                 
292                 if (strcmp(sdna->types[sp[0]], str) == 0) {
293                         return sp;
294                 }
295         }
296         
297         return NULL;
298 }
299
300 /**
301  * Returns the index of the struct info for the struct with the specified name.
302  */
303 int DNA_struct_find_nr(SDNA *sdna, const char *str)
304 {
305         const short *sp = NULL;
306
307         if (sdna->lastfind < sdna->nr_structs) {
308                 sp = sdna->structs[sdna->lastfind];
309                 if (strcmp(sdna->types[sp[0]], str) == 0) {
310                         return sdna->lastfind;
311                 }
312         }
313
314 #ifdef WITH_DNA_GHASH
315         {
316                 void **index_p;
317                 int a;
318
319                 index_p = BLI_ghash_lookup_p(sdna->structs_map, str);
320
321                 if (index_p) {
322                         a = GET_INT_FROM_POINTER(*index_p);
323                         sdna->lastfind = a;
324                 }
325                 else {
326                         a = -1;
327                 }
328                 return a;
329         }
330 #else
331         {
332                 int a;
333
334                 for (a = 0; a < sdna->nr_structs; a++) {
335
336                         sp = sdna->structs[a];
337
338                         if (strcmp(sdna->types[sp[0]], str) == 0) {
339                                 sdna->lastfind = a;
340                                 return a;
341                         }
342                 }
343         }
344         return -1;
345 #endif
346 }
347
348 /* ************************* END DIV ********************** */
349
350 /* ************************* READ DNA ********************** */
351
352 /**
353  * In sdna->data the data, now we convert that to something understandable
354  */
355 static void init_structDNA(SDNA *sdna, bool do_endian_swap)
356 {
357         int *data, *verg, gravity_fix = -1;
358         intptr_t nr;
359         short *sp;
360         char str[8], *cp;
361         
362         verg = (int *)str;
363         data = (int *)sdna->data;
364
365         strcpy(str, "SDNA");
366         if (*data == *verg) {
367         
368                 data++;
369                 
370                 /* load names array */
371                 strcpy(str, "NAME");
372                 if (*data == *verg) {
373                         data++;
374                         
375                         if (do_endian_swap) sdna->nr_names = le_int(*data);
376                         else sdna->nr_names = *data;
377                         
378                         data++;
379                         sdna->names = MEM_callocN(sizeof(void *) * sdna->nr_names, "sdnanames");
380                 }
381                 else {
382                         printf("NAME error in SDNA file\n");
383                         return;
384                 }
385                 
386                 nr = 0;
387                 cp = (char *)data;
388                 while (nr < sdna->nr_names) {
389                         sdna->names[nr] = cp;
390
391                         /* "float gravity [3]" was parsed wrong giving both "gravity" and
392                          * "[3]"  members. we rename "[3]", and later set the type of
393                          * "gravity" to "void" so the offsets work out correct */
394                         if (*cp == '[' && strcmp(cp, "[3]") == 0) {
395                                 if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) {
396                                         sdna->names[nr] = "gravity[3]";
397                                         gravity_fix = nr;
398                                 }
399                         }
400
401                         while (*cp) cp++;
402                         cp++;
403                         nr++;
404                 }
405                 nr = (intptr_t)cp;       /* prevent BUS error */
406                 nr = (nr + 3) & ~3;
407                 cp = (char *)nr;
408                 
409                 /* load type names array */
410                 data = (int *)cp;
411                 strcpy(str, "TYPE");
412                 if (*data == *verg) {
413                         data++;
414                         
415                         if (do_endian_swap) sdna->nr_types = le_int(*data);
416                         else sdna->nr_types = *data;
417                         
418                         data++;
419                         sdna->types = MEM_callocN(sizeof(void *) * sdna->nr_types, "sdnatypes");
420                 }
421                 else {
422                         printf("TYPE error in SDNA file\n");
423                         return;
424                 }
425                 
426                 nr = 0;
427                 cp = (char *)data;
428                 while (nr < sdna->nr_types) {
429                         sdna->types[nr] = cp;
430                         
431                         /* this is a patch, to change struct names without a conflict with SDNA */
432                         /* be careful to use it, in this case for a system-struct (opengl/X) */
433                         
434                         if (*cp == 'b') {
435                                 /* struct Screen was already used by X, 'bScreen' replaces the old IrisGL 'Screen' struct */
436                                 if (strcmp("bScreen", cp) == 0) sdna->types[nr] = cp + 1;
437                         }
438                         
439                         while (*cp) cp++;
440                         cp++;
441                         nr++;
442                 }
443                 nr = (intptr_t)cp;       /* prevent BUS error */
444                 nr = (nr + 3) & ~3;
445                 cp = (char *)nr;
446                 
447                 /* load typelen array */
448                 data = (int *)cp;
449                 strcpy(str, "TLEN");
450                 if (*data == *verg) {
451                         data++;
452                         sp = (short *)data;
453                         sdna->typelens = sp;
454                         
455                         if (do_endian_swap) {
456                                 short a, *spo = sp;
457                                 
458                                 a = sdna->nr_types;
459                                 while (a--) {
460                                         spo[0] = le_short(spo[0]);
461                                         spo++;
462                                 }
463                         }
464                         
465                         sp += sdna->nr_types;
466                 }
467                 else {
468                         printf("TLEN error in SDNA file\n");
469                         return;
470                 }
471                 if (sdna->nr_types & 1) sp++;   /* prevent BUS error */
472
473                 /* load struct array */
474                 data = (int *)sp;
475                 strcpy(str, "STRC");
476                 if (*data == *verg) {
477                         data++;
478                         
479                         if (do_endian_swap) sdna->nr_structs = le_int(*data);
480                         else sdna->nr_structs = *data;
481                         
482                         data++;
483                         sdna->structs = MEM_callocN(sizeof(void *) * sdna->nr_structs, "sdnastrcs");
484                 }
485                 else {
486                         printf("STRC error in SDNA file\n");
487                         return;
488                 }
489                 
490                 nr = 0;
491                 sp = (short *)data;
492                 while (nr < sdna->nr_structs) {
493                         sdna->structs[nr] = sp;
494                         
495                         if (do_endian_swap) {
496                                 short a;
497                                 
498                                 sp[0] = le_short(sp[0]);
499                                 sp[1] = le_short(sp[1]);
500                                 
501                                 a = sp[1];
502                                 sp += 2;
503                                 while (a--) {
504                                         sp[0] = le_short(sp[0]);
505                                         sp[1] = le_short(sp[1]);
506                                         sp += 2;
507                                 }
508                         }
509                         else {
510                                 sp += 2 * sp[1] + 2;
511                         }
512                         
513                         nr++;
514                 }
515
516                 /* finally pointerlen: use struct ListBase to test it, never change the size of it! */
517                 sp = findstruct_name(sdna, "ListBase");
518                 /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */
519                 
520                 sdna->pointerlen = sdna->typelens[sp[0]] / 2;
521
522                 if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 8)) {
523                         printf("ListBase struct error! Needs it to calculate pointerize.\n");
524                         exit(1);
525                         /* well, at least sizeof(ListBase) is error proof! (ton) */
526                 }
527                 
528                 /* second part of gravity problem, setting "gravity" type to void */
529                 if (gravity_fix > -1) {
530                         for (nr = 0; nr < sdna->nr_structs; nr++) {
531                                 sp = sdna->structs[nr];
532                                 if (strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0)
533                                         sp[10] = SDNA_TYPE_VOID;
534                         }
535                 }
536
537 #ifdef WITH_DNA_GHASH
538                 /* create a ghash lookup to speed up */
539                 sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->nr_structs);
540
541                 for (nr = 0; nr < sdna->nr_structs; nr++) {
542                         sp = sdna->structs[nr];
543                         BLI_ghash_insert(sdna->structs_map, sdna->types[sp[0]], SET_INT_IN_POINTER(nr));
544                 }
545 #endif
546         }
547 }
548
549 /**
550  * Constructs and returns a decoded SDNA structure from the given encoded SDNA data block.
551  */
552 SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swap)
553 {
554         SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
555         
556         sdna->lastfind = 0;
557
558         sdna->datalen = datalen;
559         sdna->data = MEM_mallocN(datalen, "sdna_data");
560         memcpy(sdna->data, data, datalen);
561         
562         init_structDNA(sdna, do_endian_swap);
563         
564         return sdna;
565 }
566
567 /* ******************** END READ DNA ********************** */
568
569 /* ******************* HANDLE DNA ***************** */
570
571 /**
572  * Used by #DNA_struct_get_compareflags (below) to recursively mark all structs
573  * containing a field of type structnr as changed between old and current SDNAs.
574  */
575 static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structnr)
576 {
577         int a, b, typenr, elems;
578         const short *sp;
579         const char *cp;
580         
581         /* check all structs, test if it's inside another struct */
582         sp = sdna->structs[structnr];
583         typenr = sp[0];
584         
585         for (a = 0; a < sdna->nr_structs; a++) {
586                 if ((a != structnr) && (compflags[a] == SDNA_CMP_EQUAL)) {
587                         sp = sdna->structs[a];
588                         elems = sp[1];
589                         sp += 2;
590                         for (b = 0; b < elems; b++, sp += 2) {
591                                 if (sp[0] == typenr) {
592                                         cp = sdna->names[sp[1]];
593                                         if (!ispointer(cp)) {
594                                                 compflags[a] = SDNA_CMP_NOT_EQUAL;
595                                                 recurs_test_compflags(sdna, compflags, a);
596                                         }
597                                 }
598                         }
599                 }
600         }
601         
602 }
603
604
605 /**
606  * Constructs and returns an array of byte flags with one element for each struct in oldsdna,
607  * indicating how it compares to newsdna:
608  *
609  * flag value:
610  * - 0  Struct has disappeared (values of this struct type will not be loaded by the current Blender)
611  * - 1  Struct is the same (can be loaded with straight memory copy after any necessary endian conversion)
612  * - 2  Struct is different in some way (needs to be copied/converted field by field)
613  */
614 char *DNA_struct_get_compareflags(SDNA *oldsdna, SDNA *newsdna)
615 {
616         int a, b;
617         const short *sp_old, *sp_new;
618         const char *str1, *str2;
619         char *compflags;
620         
621         if (oldsdna->nr_structs == 0) {
622                 printf("error: file without SDNA\n");
623                 return NULL;
624         }
625
626         compflags = MEM_callocN(oldsdna->nr_structs, "compflags");
627
628         /* we check all structs in 'oldsdna' and compare them with 
629          * the structs in 'newsdna'
630          */
631         
632         for (a = 0; a < oldsdna->nr_structs; a++) {
633                 sp_old = oldsdna->structs[a];
634                 
635                 /* search for type in cur */
636                 sp_new = findstruct_name(newsdna, oldsdna->types[sp_old[0]]);
637                 
638                 if (sp_new) {
639                         /* initial assumption */
640                         compflags[a] = SDNA_CMP_NOT_EQUAL;
641                         
642                         /* compare length and amount of elems */
643                         if (sp_new[1] == sp_old[1]) {
644                                 if (newsdna->typelens[sp_new[0]] == oldsdna->typelens[sp_old[0]]) {
645
646                                         /* same length, same amount of elems, now per type and name */
647                                         b = sp_old[1];
648                                         sp_old += 2;
649                                         sp_new += 2;
650                                         while (b > 0) {
651                                                 str1 = newsdna->types[sp_new[0]];
652                                                 str2 = oldsdna->types[sp_old[0]];
653                                                 if (strcmp(str1, str2) != 0) break;
654
655                                                 str1 = newsdna->names[sp_new[1]];
656                                                 str2 = oldsdna->names[sp_old[1]];
657                                                 if (strcmp(str1, str2) != 0) break;
658
659                                                 /* same type and same name, now pointersize */
660                                                 if (ispointer(str1)) {
661                                                         if (oldsdna->pointerlen != newsdna->pointerlen) break;
662                                                 }
663
664                                                 b--;
665                                                 sp_old += 2;
666                                                 sp_new += 2;
667                                         }
668                                         if (b == 0) {
669                                                 /* no differences found */
670                                                 compflags[a] = SDNA_CMP_EQUAL;
671                                         }
672
673                                 }
674                         }
675                         
676                 }
677         }
678
679         /* first struct in util.h is struct Link, this is skipped in compflags (als # 0).
680          * was a bug, and this way dirty patched! Solve this later....
681          */
682         compflags[0] = SDNA_CMP_EQUAL;
683
684         /* Because structs can be inside structs, we recursively
685          * set flags when a struct is altered
686          */
687         for (a = 0; a < oldsdna->nr_structs; a++) {
688                 if (compflags[a] == SDNA_CMP_NOT_EQUAL) {
689                         recurs_test_compflags(oldsdna, compflags, a);
690                 }
691         }
692         
693 #if 0
694         for (a = 0; a < oldsdna->nr_structs; a++) {
695                 if (compflags[a] == SDNA_CMP_NOT_EQUAL) {
696                         spold = oldsdna->structs[a];
697                         printf("changed: %s\n", oldsdna->types[spold[0]]);
698                 }
699         }
700 #endif
701
702         return compflags;
703 }
704
705 /**
706  * Converts the name of a primitive type to its enumeration code.
707  */
708 static eSDNA_Type sdna_type_nr(const char *dna_type)
709 {
710         if     ((strcmp(dna_type, "char") == 0) || (strcmp(dna_type, "const char") == 0))          return SDNA_TYPE_CHAR;
711         else if ((strcmp(dna_type, "uchar") == 0) || (strcmp(dna_type, "unsigned char") == 0))     return SDNA_TYPE_UCHAR;
712         else if ( strcmp(dna_type, "short") == 0)                                                  return SDNA_TYPE_SHORT;
713         else if ((strcmp(dna_type, "ushort") == 0) || (strcmp(dna_type, "unsigned short") == 0))   return SDNA_TYPE_USHORT;
714         else if ( strcmp(dna_type, "int") == 0)                                                    return SDNA_TYPE_INT;
715         else if ( strcmp(dna_type, "float") == 0)                                                  return SDNA_TYPE_FLOAT;
716         else if ( strcmp(dna_type, "double") == 0)                                                 return SDNA_TYPE_DOUBLE;
717         else if ( strcmp(dna_type, "int64_t") == 0)                                                return SDNA_TYPE_INT64;
718         else if ( strcmp(dna_type, "uint64_t") == 0)                                               return SDNA_TYPE_UINT64;
719         else                                                                                       return -1; /* invalid! */
720 }
721
722 /**
723  * Converts a value of one primitive type to another.
724  * Note there is no optimization for the case where otype and ctype are the same:
725  * assumption is that caller will handle this case.
726  *
727  * \param ctype  Name of type to convert to
728  * \param otype  Name of type to convert from
729  * \param name  Field name to extract array-size information
730  * \param curdata  Where to put converted data
731  * \param olddata  Data of type otype to convert
732  */
733 static void cast_elem(
734         const char *ctype, const char *otype, const char *name,
735         char *curdata, const char *olddata)
736 {
737         double val = 0.0;
738         int arrlen, curlen = 1, oldlen = 1;
739
740         eSDNA_Type ctypenr, otypenr;
741
742         arrlen = DNA_elem_array_size(name);
743
744         if ( (otypenr = sdna_type_nr(otype)) == -1 ||
745              (ctypenr = sdna_type_nr(ctype)) == -1)
746         {
747                 return;
748         }
749
750         /* define lengths */
751         oldlen = DNA_elem_type_size(otypenr);
752         curlen = DNA_elem_type_size(ctypenr);
753
754         while (arrlen > 0) {
755                 switch (otypenr) {
756                         case SDNA_TYPE_CHAR:
757                                 val = *olddata; break;
758                         case SDNA_TYPE_UCHAR:
759                                 val = *( (unsigned char *)olddata); break;
760                         case SDNA_TYPE_SHORT:
761                                 val = *( (short *)olddata); break;
762                         case SDNA_TYPE_USHORT:
763                                 val = *( (unsigned short *)olddata); break;
764                         case SDNA_TYPE_INT:
765                                 val = *( (int *)olddata); break;
766                         case SDNA_TYPE_FLOAT:
767                                 val = *( (float *)olddata); break;
768                         case SDNA_TYPE_DOUBLE:
769                                 val = *( (double *)olddata); break;
770                         case SDNA_TYPE_INT64:
771                                 val = *( (int64_t *)olddata); break;
772                         case SDNA_TYPE_UINT64:
773                                 val = *( (uint64_t *)olddata); break;
774                 }
775                 
776                 switch (ctypenr) {
777                         case SDNA_TYPE_CHAR:
778                                 *curdata = val; break;
779                         case SDNA_TYPE_UCHAR:
780                                 *( (unsigned char *)curdata) = val; break;
781                         case SDNA_TYPE_SHORT:
782                                 *( (short *)curdata) = val; break;
783                         case SDNA_TYPE_USHORT:
784                                 *( (unsigned short *)curdata) = val; break;
785                         case SDNA_TYPE_INT:
786                                 *( (int *)curdata) = val; break;
787                         case SDNA_TYPE_FLOAT:
788                                 if (otypenr < 2) val /= 255;
789                                 *( (float *)curdata) = val; break;
790                         case SDNA_TYPE_DOUBLE:
791                                 if (otypenr < 2) val /= 255;
792                                 *( (double *)curdata) = val; break;
793                         case SDNA_TYPE_INT64:
794                                 *( (int64_t *)curdata) = val; break;
795                         case SDNA_TYPE_UINT64:
796                                 *( (uint64_t *)curdata) = val; break;
797                 }
798
799                 olddata += oldlen;
800                 curdata += curlen;
801                 arrlen--;
802         }
803 }
804
805 /**
806  * Converts pointer values between different sizes. These are only used
807  * as lookup keys to identify data blocks in the saved .blend file, not
808  * as actual in-memory pointers.
809  *
810  * \param curlen  Pointer length to conver to
811  * \param oldlen  Length of pointers in olddata
812  * \param name  Field name to extract array-size information
813  * \param curdata  Where to put converted data
814  * \param olddata  Data to convert
815  */
816 static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata, const char *olddata)
817 {
818         int64_t lval;
819         int arrlen;
820         
821         arrlen = DNA_elem_array_size(name);
822         
823         while (arrlen > 0) {
824         
825                 if (curlen == oldlen) {
826                         memcpy(curdata, olddata, curlen);
827                 }
828                 else if (curlen == 4 && oldlen == 8) {
829                         lval = *((int64_t *)olddata);
830
831                         /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
832                          * pointers may lose uniqueness on truncation! (Hopefully this wont
833                          * happen unless/until we ever get to multi-gigabyte .blend files...) */
834                         *((int *)curdata) = lval >> 3;
835                 }
836                 else if (curlen == 8 && oldlen == 4) {
837                         *((int64_t *)curdata) = *((int *)olddata);
838                 }
839                 else {
840                         /* for debug */
841                         printf("errpr: illegal pointersize!\n");
842                 }
843                 
844                 olddata += oldlen;
845                 curdata += curlen;
846                 arrlen--;
847
848         }
849 }
850
851 /**
852  * Equality test on name and oname excluding any array-size suffix.
853  */
854 static int elem_strcmp(const char *name, const char *oname)
855 {
856         int a = 0;
857         
858         while (1) {
859                 if (name[a] != oname[a]) return 1;
860                 if (name[a] == '[' || oname[a] == '[') break;
861                 if (name[a] == 0 || oname[a] == 0) break;
862                 a++;
863         }
864         return 0;
865 }
866
867 /**
868  * Returns the address of the data for the specified field within olddata
869  * according to the struct format pointed to by old, or NULL if no such
870  * field can be found.
871  *
872  * \param sdna  Old SDNA
873  * \param type  Current field type name
874  * \param name  Current field name
875  * \param old  Pointer to struct information in sdna
876  * \param olddata  Struct data
877  * \param sppo  Optional place to return pointer to field info in sdna
878  * \return Data address.
879  */
880 static char *find_elem(
881         const SDNA *sdna,
882         const char *type,
883         const char *name,
884         const short *old,
885         char *olddata,
886         const short **sppo)
887 {
888         int a, elemcount, len;
889         const char *otype, *oname;
890         
891         /* without arraypart, so names can differ: return old namenr and type */
892         
893         /* in old is the old struct */
894         elemcount = old[1];
895         old += 2;
896         for (a = 0; a < elemcount; a++, old += 2) {
897
898                 otype = sdna->types[old[0]];
899                 oname = sdna->names[old[1]];
900
901                 len = elementsize(sdna, old[0], old[1]);
902
903                 if (elem_strcmp(name, oname) == 0) {  /* name equal */
904                         if (strcmp(type, otype) == 0) {   /* type equal */
905                                 if (sppo) *sppo = old;
906                                 return olddata;
907                         }
908                         
909                         return NULL;
910                 }
911                 
912                 olddata += len;
913         }
914         return NULL;
915 }
916
917 /**
918  * Converts the contents of a single field of a struct, of a non-struct type,
919  * from oldsdna to newsdna format.
920  *
921  * \param newsdna  SDNA of current Blender
922  * \param oldsdna  SDNA of Blender that saved file
923  * \param type  current field type name
924  * \param name  current field name
925  * \param curdata  put field data converted to newsdna here
926  * \param old  pointer to struct info in oldsdna
927  * \param olddata  struct contents laid out according to oldsdna
928  */
929 static void reconstruct_elem(
930         const SDNA *newsdna,
931         const SDNA *oldsdna,
932         const char *type,
933         const char *name,
934         char *curdata,
935         const short *old,
936         const char *olddata)
937 {
938         /* rules: test for NAME:
939          *      - name equal:
940          *          - cast type
941          *      - name partially equal (array differs)
942          *          - type equal: memcpy
943          *          - types casten
944          * (nzc 2-4-2001 I want the 'unsigned' bit to be parsed as well. Where
945          * can I force this?)
946          */
947         int a, elemcount, len, countpos, oldsize, cursize, mul;
948         const char *otype, *oname, *cp;
949         
950         /* is 'name' an array? */
951         cp = name;
952         countpos = 0;
953         while (*cp && *cp != '[') {
954                 cp++; countpos++;
955         }
956         if (*cp != '[') countpos = 0;
957         
958         /* in old is the old struct */
959         elemcount = old[1];
960         old += 2;
961         for (a = 0; a < elemcount; a++, old += 2) {
962                 otype = oldsdna->types[old[0]];
963                 oname = oldsdna->names[old[1]];
964                 len = elementsize(oldsdna, old[0], old[1]);
965                 
966                 if (strcmp(name, oname) == 0) { /* name equal */
967                         
968                         if (ispointer(name)) {  /* pointer of functionpointer afhandelen */
969                                 cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, name, curdata, olddata);
970                         }
971                         else if (strcmp(type, otype) == 0) {    /* type equal */
972                                 memcpy(curdata, olddata, len);
973                         }
974                         else {
975                                 cast_elem(type, otype, name, curdata, olddata);
976                         }
977
978                         return;
979                 }
980                 else if (countpos != 0) {  /* name is an array */
981
982                         if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) {  /* basis equal */
983                                 
984                                 cursize = DNA_elem_array_size(name);
985                                 oldsize = DNA_elem_array_size(oname);
986
987                                 if (ispointer(name)) {  /* handle pointer or functionpointer */
988                                         cast_pointer(newsdna->pointerlen, oldsdna->pointerlen,
989                                                      cursize > oldsize ? oname : name,
990                                                      curdata, olddata);
991                                 }
992                                 else if (strcmp(type, otype) == 0) {  /* type equal */
993                                         mul = len / oldsize; /* size of single old array element */
994                                         mul *= (cursize < oldsize) ? cursize : oldsize; /* smaller of sizes of old and new arrays */
995                                         memcpy(curdata, olddata, mul);
996                                         
997                                         if (oldsize > cursize && strcmp(type, "char") == 0) {
998                                                 /* string had to be truncated, ensure it's still null-terminated */
999                                                 curdata[mul - 1] = '\0';
1000                                         }
1001                                 }
1002                                 else {
1003                                         cast_elem(type, otype,
1004                                                   cursize > oldsize ? oname : name,
1005                                                   curdata, olddata);
1006                                 }
1007                                 return;
1008                         }
1009                 }
1010                 olddata += len;
1011         }
1012 }
1013
1014 /**
1015  * Converts the contents of an entire struct from oldsdna to newsdna format.
1016  *
1017  * \param newsdna  SDNA of current Blender
1018  * \param oldsdna  SDNA of Blender that saved file
1019  * \param compflags
1020  *
1021  * Result from DNA_struct_get_compareflags to avoid needless conversions.
1022  * \param oldSDNAnr  Index of old struct definition in oldsdna
1023  * \param data  Struct contents laid out according to oldsdna
1024  * \param curSDNAnr  Index of current struct definition in newsdna
1025  * \param cur  Where to put converted struct contents
1026  */
1027 static void reconstruct_struct(
1028         SDNA *newsdna,
1029         SDNA *oldsdna,
1030         const char *compflags,
1031
1032         int oldSDNAnr,
1033         char *data,
1034         int curSDNAnr,
1035         char *cur)
1036 {
1037         /* Recursive!
1038          * Per element from cur_struct, read data from old_struct.
1039          * If element is a struct, call recursive.
1040          */
1041         int a, elemcount, elen, eleno, mul, mulo, firststructtypenr;
1042         const short *spo, *spc, *sppo;
1043         const char *type;
1044         char *cpo, *cpc;
1045         const char *name, *nameo;
1046
1047         if (oldSDNAnr == -1) return;
1048         if (curSDNAnr == -1) return;
1049
1050         if (compflags[oldSDNAnr] == SDNA_CMP_EQUAL) {
1051                 /* if recursive: test for equal */
1052                 spo = oldsdna->structs[oldSDNAnr];
1053                 elen = oldsdna->typelens[spo[0]];
1054                 memcpy(cur, data, elen);
1055                 
1056                 return;
1057         }
1058
1059         firststructtypenr = *(newsdna->structs[0]);
1060
1061         spo = oldsdna->structs[oldSDNAnr];
1062         spc = newsdna->structs[curSDNAnr];
1063
1064         elemcount = spc[1];
1065
1066         spc += 2;
1067         cpc = cur;
1068         for (a = 0; a < elemcount; a++, spc += 2) {  /* convert each field */
1069                 type = newsdna->types[spc[0]];
1070                 name = newsdna->names[spc[1]];
1071                 
1072                 elen = elementsize(newsdna, spc[0], spc[1]);
1073
1074                 /* test: is type a struct? */
1075                 if (spc[0] >= firststructtypenr && !ispointer(name)) {
1076                         /* struct field type */
1077                         /* where does the old struct data start (and is there an old one?) */
1078                         cpo = find_elem(oldsdna, type, name, spo, data, &sppo);
1079                         
1080                         if (cpo) {
1081                                 oldSDNAnr = DNA_struct_find_nr(oldsdna, type);
1082                                 curSDNAnr = DNA_struct_find_nr(newsdna, type);
1083                                 
1084                                 /* array! */
1085                                 mul = DNA_elem_array_size(name);
1086                                 nameo = oldsdna->names[sppo[1]];
1087                                 mulo = DNA_elem_array_size(nameo);
1088                                 
1089                                 eleno = elementsize(oldsdna, sppo[0], sppo[1]);
1090                                 
1091                                 elen /= mul;
1092                                 eleno /= mulo;
1093                                 
1094                                 while (mul--) {
1095                                         reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc);
1096                                         cpo += eleno;
1097                                         cpc += elen;
1098                                         
1099                                         /* new struct array larger than old */
1100                                         mulo--;
1101                                         if (mulo <= 0) break;
1102                                 }
1103                         }
1104                         else {
1105                                 cpc += elen;  /* skip field no longer present */
1106                         }
1107                 }
1108                 else {
1109                         /* non-struct field type */
1110                         reconstruct_elem(newsdna, oldsdna, type, name, cpc, spo, data);
1111                         cpc += elen;
1112                 }
1113         }
1114 }
1115
1116 /**
1117  * Does endian swapping on the fields of a struct value.
1118  *
1119  * \param oldsdna  SDNA of Blender that saved file
1120  * \param oldSDNAnr  Index of struct info within oldsdna
1121  * \param data  Struct data
1122  */
1123 void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
1124 {
1125         /* Recursive!
1126          * If element is a struct, call recursive.
1127          */
1128         int a, mul, elemcount, elen, elena, firststructtypenr;
1129         const short *spo, *spc;
1130         char *cur;
1131         const char *type, *name;
1132
1133         if (oldSDNAnr == -1) return;
1134         firststructtypenr = *(oldsdna->structs[0]);
1135         
1136         spo = spc = oldsdna->structs[oldSDNAnr];
1137
1138         elemcount = spo[1];
1139
1140         spc += 2;
1141         cur = data;
1142         
1143         for (a = 0; a < elemcount; a++, spc += 2) {
1144                 type = oldsdna->types[spc[0]];
1145                 name = oldsdna->names[spc[1]];
1146                 
1147                 /* elementsize = including arraysize */
1148                 elen = elementsize(oldsdna, spc[0], spc[1]);
1149
1150                 /* test: is type a struct? */
1151                 if (spc[0] >= firststructtypenr && !ispointer(name)) {
1152                         /* struct field type */
1153                         /* where does the old data start (is there one?) */
1154                         char *cpo = find_elem(oldsdna, type, name, spo, data, NULL);
1155                         if (cpo) {
1156                                 oldSDNAnr = DNA_struct_find_nr(oldsdna, type);
1157                                 
1158                                 mul = DNA_elem_array_size(name);
1159                                 elena = elen / mul;
1160
1161                                 while (mul--) {
1162                                         DNA_struct_switch_endian(oldsdna, oldSDNAnr, cpo);
1163                                         cpo += elena;
1164                                 }
1165                         }
1166                 }
1167                 else {
1168                         /* non-struct field type */
1169                         if (ispointer(name)) {
1170                                 if (oldsdna->pointerlen == 8) {
1171                                         BLI_endian_switch_int64_array((int64_t *)cur, DNA_elem_array_size(name));
1172                                 }
1173                         }
1174                         else {
1175                                 if (ELEM(spc[0], SDNA_TYPE_SHORT, SDNA_TYPE_USHORT)) {
1176
1177                                         /* exception: variable called blocktype: derived from ID_  */
1178                                         bool skip = false;
1179                                         if (name[0] == 'b' && name[1] == 'l') {
1180                                                 if (strcmp(name, "blocktype") == 0) skip = true;
1181                                         }
1182
1183                                         if (skip == false) {
1184                                                 BLI_endian_switch_int16_array((int16_t *)cur, DNA_elem_array_size(name));
1185                                         }
1186                                 }
1187                                 else if (ELEM(spc[0], SDNA_TYPE_INT, SDNA_TYPE_FLOAT)) {
1188                                         /* note, intentionally ignore long/ulong here these could be 4 or 8 bits,
1189                                          * but turns out we only used for runtime vars and
1190                                          * only once for a struct type thats no longer used. */
1191
1192                                         BLI_endian_switch_int32_array((int32_t *)cur, DNA_elem_array_size(name));
1193                                 }
1194                                 else if (ELEM(spc[0], SDNA_TYPE_INT64, SDNA_TYPE_UINT64, SDNA_TYPE_DOUBLE)) {
1195                                         BLI_endian_switch_int64_array((int64_t *)cur, DNA_elem_array_size(name));
1196                                 }
1197                         }
1198                 }
1199                 cur += elen;
1200         }
1201 }
1202
1203 /**
1204  * \param newsdna  SDNA of current Blender
1205  * \param oldsdna  SDNA of Blender that saved file
1206  * \param compflags
1207  *
1208  * Result from DNA_struct_get_compareflags to avoid needless conversions
1209  * \param oldSDNAnr  Index of struct info within oldsdna
1210  * \param blocks  The number of array elements
1211  * \param data  Array of struct data
1212  * \return An allocated reconstructed struct
1213  */
1214 void *DNA_struct_reconstruct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int oldSDNAnr, int blocks, void *data)
1215 {
1216         int a, curSDNAnr, curlen = 0, oldlen;
1217         const short *spo, *spc;
1218         char *cur, *cpc, *cpo;
1219         const char *type;
1220         
1221         /* oldSDNAnr == structnr, we're looking for the corresponding 'cur' number */
1222         spo = oldsdna->structs[oldSDNAnr];
1223         type = oldsdna->types[spo[0]];
1224         oldlen = oldsdna->typelens[spo[0]];
1225         curSDNAnr = DNA_struct_find_nr(newsdna, type);
1226
1227         /* init data and alloc */
1228         if (curSDNAnr != -1) {
1229                 spc = newsdna->structs[curSDNAnr];
1230                 curlen = newsdna->typelens[spc[0]];
1231         }
1232         if (curlen == 0) {
1233                 return NULL;
1234         }
1235
1236         cur = MEM_callocN(blocks * curlen, "reconstruct");
1237         cpc = cur;
1238         cpo = data;
1239         for (a = 0; a < blocks; a++) {
1240                 reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc);
1241                 cpc += curlen;
1242                 cpo += oldlen;
1243         }
1244
1245         return cur;
1246 }
1247
1248 /**
1249  * Returns the offset of the field with the specified name and type within the specified
1250  * struct type in sdna.
1251  */
1252 int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
1253 {
1254         
1255         const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1256         const short * const spo = sdna->structs[SDNAnr];
1257         const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
1258         BLI_assert(SDNAnr != -1);
1259         return (int)((intptr_t)cp);
1260 }
1261
1262 bool DNA_struct_elem_find(SDNA *sdna, const char *stype, const char *vartype, const char *name)
1263 {
1264         
1265         const int SDNAnr = DNA_struct_find_nr(sdna, stype);
1266         
1267         if (SDNAnr != -1) {
1268                 const short * const spo = sdna->structs[SDNAnr];
1269                 const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
1270                 
1271                 if (cp) {
1272                         return true;
1273                 }
1274         }
1275         return false;
1276 }
1277
1278
1279 /**
1280  * Returns the size in bytes of a primitive type.
1281  */
1282 int DNA_elem_type_size(const eSDNA_Type elem_nr)
1283 {
1284         /* should contain all enum types */
1285         switch (elem_nr) {
1286                 case SDNA_TYPE_CHAR:
1287                 case SDNA_TYPE_UCHAR:
1288                         return 1;
1289                 case SDNA_TYPE_SHORT:
1290                 case SDNA_TYPE_USHORT:
1291                         return 2;
1292                 case SDNA_TYPE_INT:
1293                 case SDNA_TYPE_FLOAT:
1294                         return 4;
1295                 case SDNA_TYPE_DOUBLE:
1296                 case SDNA_TYPE_INT64:
1297                 case SDNA_TYPE_UINT64:
1298                         return 8;
1299         }
1300
1301         /* weak */
1302         return 8;
1303 }