Another step in the undo evolution.
[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 #ifdef WIN32
39 #include "BLI_winstuff.h"
40 #endif
41
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <math.h>
46
47 #include "MEM_guardedalloc.h"
48
49 #include "DNA_listBase.h"
50 #include "DNA_userdef_types.h"
51
52 #include "BKE_utildefines.h"
53 #include "BKE_global.h"
54
55 #include "BLO_undofile.h"
56
57 #include "BLI_blenlib.h"
58 #include "BLI_linklist.h"
59
60
61
62 /* **************** support for memory-write, for undo buffers *************** */
63
64 /* not memfile itself */
65 void BLO_free_memfile(MemFile *memfile)
66 {
67         MemFileChunk *chunk;
68         
69         while(chunk = (memfile->chunks.first) ) {
70                 if(chunk->ident==0) MEM_freeN(chunk->buf);
71                 BLI_remlink(&memfile->chunks, chunk);
72                 MEM_freeN(chunk);
73         }
74         memfile->size= 0;
75 }
76
77 /* to keep list of memfiles consistant, 'first' is always first in list */
78 /* result is that 'first' is being freed */
79 void BLO_merge_memfile(MemFile *first, MemFile *second)
80 {
81         MemFileChunk *fc, *sc;
82         
83         fc= first->chunks.first;
84         sc= second->chunks.first;
85         while (fc || sc) {
86                 if(fc && sc) {
87                         if(sc->ident) {
88                                 sc->ident= 0;
89                                 fc->ident= 1;
90                         }
91                 }
92                 if(fc) fc= fc->next;
93                 if(sc) sc= sc->next;
94         }
95         
96         BLO_free_memfile(first);
97 }
98
99 static int my_memcmp(int *mem1, int *mem2, int len)
100 {
101         register int a= len, *mema= mem1, *memb= mem2;
102         
103         while(a--) {
104                 if( *mema != *memb) return 1;
105                 mema++;
106                 memb++;
107         }
108         return 0;
109 }
110
111 void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned int size)
112 {
113         static MemFileChunk *compchunk=NULL;
114         MemFileChunk *curchunk;
115         
116         /* this function inits when compare != NULL or when current==NULL */
117         if(compare) {
118                 compchunk= compare->chunks.first;
119                 return;
120         }
121         if(current==NULL) {
122                 compchunk= NULL;
123                 return;
124         }
125         
126         curchunk= MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
127         curchunk->size= size;
128         curchunk->buf= NULL;
129         curchunk->ident= 0;
130         BLI_addtail(&current->chunks, curchunk);
131         
132         /* we compare compchunk with buf */
133         if(compchunk) {
134                 if(compchunk->size == curchunk->size) {
135                         if( my_memcmp((int *)compchunk->buf, (int *)buf, size/4)==0) {
136                                 curchunk->buf= compchunk->buf;
137                                 curchunk->ident= 1;
138                         }
139                 }
140                 compchunk= compchunk->next;
141         }
142         
143         /* not equal... */
144         if(curchunk->buf==NULL) {
145                 curchunk->buf= MEM_mallocN(size, "Chunk buffer");
146                 memcpy(curchunk->buf, buf, size);
147                 current->size += size;
148         }
149 }
150