Filling in branch from trunk
[blender.git] / source / blender / blenloader / intern / undofile.c
1 /**
2  * $Id: 
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2004 Blender Foundation
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * .blend file reading entry point
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdio.h>
41 #include <math.h>
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_listBase.h"
46 #include "DNA_userdef_types.h"
47
48 #include "BKE_utildefines.h"
49 #include "BKE_global.h"
50
51 #include "BLO_undofile.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_linklist.h"
55
56
57
58 /* **************** support for memory-write, for undo buffers *************** */
59
60 /* not memfile itself */
61 void BLO_free_memfile(MemFile *memfile)
62 {
63         MemFileChunk *chunk;
64         
65         while( (chunk = (memfile->chunks.first) ) ) {
66                 if(chunk->ident==0) MEM_freeN(chunk->buf);
67                 BLI_remlink(&memfile->chunks, chunk);
68                 MEM_freeN(chunk);
69         }
70         memfile->size= 0;
71 }
72
73 /* to keep list of memfiles consistant, 'first' is always first in list */
74 /* result is that 'first' is being freed */
75 void BLO_merge_memfile(MemFile *first, MemFile *second)
76 {
77         MemFileChunk *fc, *sc;
78         
79         fc= first->chunks.first;
80         sc= second->chunks.first;
81         while (fc || sc) {
82                 if(fc && sc) {
83                         if(sc->ident) {
84                                 sc->ident= 0;
85                                 fc->ident= 1;
86                         }
87                 }
88                 if(fc) fc= fc->next;
89                 if(sc) sc= sc->next;
90         }
91         
92         BLO_free_memfile(first);
93 }
94
95 static int my_memcmp(int *mem1, int *mem2, int len)
96 {
97         register int a= len, *mema= mem1, *memb= mem2;
98         
99         while(a--) {
100                 if( *mema != *memb) return 1;
101                 mema++;
102                 memb++;
103         }
104         return 0;
105 }
106
107 void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned int size)
108 {
109         static MemFileChunk *compchunk=NULL;
110         MemFileChunk *curchunk;
111         
112         /* this function inits when compare != NULL or when current==NULL */
113         if(compare) {
114                 compchunk= compare->chunks.first;
115                 return;
116         }
117         if(current==NULL) {
118                 compchunk= NULL;
119                 return;
120         }
121         
122         curchunk= MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
123         curchunk->size= size;
124         curchunk->buf= NULL;
125         curchunk->ident= 0;
126         BLI_addtail(&current->chunks, curchunk);
127         
128         /* we compare compchunk with buf */
129         if(compchunk) {
130                 if(compchunk->size == curchunk->size) {
131                         if( my_memcmp((int *)compchunk->buf, (int *)buf, size/4)==0) {
132                                 curchunk->buf= compchunk->buf;
133                                 curchunk->ident= 1;
134                         }
135                 }
136                 compchunk= compchunk->next;
137         }
138         
139         /* not equal... */
140         if(curchunk->buf==NULL) {
141                 curchunk->buf= MEM_mallocN(size, "Chunk buffer");
142                 memcpy(curchunk->buf, buf, size);
143                 current->size += size;
144         }
145 }
146