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