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