1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "saver.hh"
|
---|
10 | #include "checksum/checksum.hh"
|
---|
11 | #include "memory/malloc.hh"
|
---|
12 | #include "g1_object.hh"
|
---|
13 |
|
---|
14 | // Saver methods
|
---|
15 |
|
---|
16 | g1_saver_class::g1_saver_class(i4_file_class *out, i4_bool close_on_delete)
|
---|
17 | : i4_saver_class(out, close_on_delete), remap(0)
|
---|
18 | {
|
---|
19 | t_refs=0;
|
---|
20 | state=DIRECTORY_CREATE;
|
---|
21 | current_offset=out->tell();
|
---|
22 | }
|
---|
23 |
|
---|
24 | g1_saver_class::~g1_saver_class()
|
---|
25 | {
|
---|
26 | g1_global_id.free_remapping(remap);
|
---|
27 | }
|
---|
28 |
|
---|
29 | void g1_saver_class::set_helpers(g1_object_class **reference_list, w32 total_references)
|
---|
30 | {
|
---|
31 | ref_list=reference_list;
|
---|
32 | t_refs=total_references;
|
---|
33 |
|
---|
34 | remap = g1_global_id.alloc_remapping();
|
---|
35 | for (w32 i=0; i<t_refs; i++)
|
---|
36 | (*remap)[ref_list[i]->global_id] = i;
|
---|
37 | }
|
---|
38 |
|
---|
39 | i4_bool g1_saver_class::write_global_id(w32 id)
|
---|
40 | {
|
---|
41 | if (state==DIRECTORY_CREATE)
|
---|
42 | {
|
---|
43 | current_offset+=2;
|
---|
44 | return i4_T;
|
---|
45 | }
|
---|
46 | else
|
---|
47 | {
|
---|
48 | w16 found=0xffff;
|
---|
49 | if (g1_global_id.check_id(id))
|
---|
50 | found = (*remap)[id];
|
---|
51 |
|
---|
52 | out->write_16(found);
|
---|
53 |
|
---|
54 | if (found==0xffff)
|
---|
55 | return i4_F;
|
---|
56 | }
|
---|
57 |
|
---|
58 | return i4_T;
|
---|
59 | }
|
---|
60 |
|
---|
61 | i4_bool g1_saver_class::write_reference(const g1_reference_class &ref)
|
---|
62 | {
|
---|
63 | if (state==DIRECTORY_CREATE)
|
---|
64 | {
|
---|
65 | current_offset+=4;
|
---|
66 | return i4_T;
|
---|
67 | }
|
---|
68 | else
|
---|
69 | {
|
---|
70 | w16 found=0;
|
---|
71 |
|
---|
72 | if (ref.ref)
|
---|
73 | {
|
---|
74 | for (w32 i=0; !found && i<t_refs; i++)
|
---|
75 | if (ref.ref==ref_list[i])
|
---|
76 | found=i+1;
|
---|
77 |
|
---|
78 | out->write_16(found);
|
---|
79 | }
|
---|
80 | else
|
---|
81 | out->write_16(0);
|
---|
82 |
|
---|
83 | // blank for notifee
|
---|
84 | out->write_16(0);
|
---|
85 | }
|
---|
86 |
|
---|
87 | return i4_T;
|
---|
88 | }
|
---|
89 |
|
---|
90 |
|
---|
91 | // Loader methods
|
---|
92 |
|
---|
93 | g1_loader_class::g1_loader_class(i4_file_class *in, i4_bool close_on_delete)
|
---|
94 | : i4_loader_class(in, close_on_delete), id_remap(0)
|
---|
95 | {
|
---|
96 | ref_list=0;
|
---|
97 | first_ref=0;
|
---|
98 | li_remap=0;
|
---|
99 | }
|
---|
100 |
|
---|
101 | g1_loader_class::~g1_loader_class()
|
---|
102 | {
|
---|
103 | if (id_remap)
|
---|
104 | {
|
---|
105 | g1_global_id.claim_freespace();
|
---|
106 | i4_free(id_remap);
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | void g1_loader_class::set_remap(w32 total_references)
|
---|
111 | {
|
---|
112 | t_refs=total_references;
|
---|
113 | id_remap = (w32 *)i4_malloc(total_references*sizeof(*id_remap), "loader_remapping");
|
---|
114 | for (int i=0; i<total_references; i++)
|
---|
115 | id_remap[i] = g1_global_id.alloc(0);
|
---|
116 | }
|
---|
117 |
|
---|
118 | void g1_loader_class::end_remap()
|
---|
119 | {
|
---|
120 | for (int i=0; i<t_refs; i++)
|
---|
121 | if (g1_global_id.preassigned(id_remap[i]))
|
---|
122 | g1_global_id.free(id_remap[i]);
|
---|
123 | }
|
---|
124 |
|
---|
125 | void g1_loader_class::set_helpers(g1_object_class **reference_list, w32 total_references)
|
---|
126 | {
|
---|
127 | ref_list=reference_list;
|
---|
128 | t_refs=total_references;
|
---|
129 | }
|
---|
130 |
|
---|
131 | w32 g1_loader_class::read_global_id()
|
---|
132 | {
|
---|
133 | w32 i=in->read_16();
|
---|
134 | if (i==0xffff || !id_remap)
|
---|
135 | return g1_global_id.invalid_id();
|
---|
136 | else
|
---|
137 | return id_remap[i];
|
---|
138 | }
|
---|
139 |
|
---|
140 | void g1_loader_class::read_reference(g1_reference_class &ref)
|
---|
141 | {
|
---|
142 | w16 index=in->read_16();
|
---|
143 | ref.ref=0; // clear out hi bits
|
---|
144 | ref.ref=(g1_object_class *)index;
|
---|
145 |
|
---|
146 | // read blank for notifee
|
---|
147 | in->read_16();
|
---|
148 |
|
---|
149 | if (ref.ref) // if non-0 reference we need to modify it later, so add to list
|
---|
150 | {
|
---|
151 | ref.next=first_ref;
|
---|
152 | first_ref=&ref;
|
---|
153 | }
|
---|
154 | else
|
---|
155 | ref.next=0;
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | void g1_loader_class::convert_references()
|
---|
160 | {
|
---|
161 | g1_reference_class *f,*next;
|
---|
162 |
|
---|
163 | for (f=first_ref; f;)
|
---|
164 | {
|
---|
165 | next=f->next;
|
---|
166 | g1_object_class *r;
|
---|
167 |
|
---|
168 | w16 ref=*((w16 *)&f->ref);
|
---|
169 | if (ref==0)
|
---|
170 | r=0;
|
---|
171 | else
|
---|
172 | {
|
---|
173 | ref--;
|
---|
174 | if (ref<t_refs)
|
---|
175 | r=ref_list[ref];
|
---|
176 | else
|
---|
177 | {
|
---|
178 | i4_warning("bad reference in file");
|
---|
179 | r=0;
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | f->ref=0;
|
---|
184 |
|
---|
185 | f->reference_object(r);
|
---|
186 |
|
---|
187 | f=next;
|
---|
188 | }
|
---|
189 | first_ref=0;
|
---|
190 | }
|
---|
191 |
|
---|
192 |
|
---|
193 |
|
---|
194 | g1_loader_class *g1_open_save_file(i4_file_class *in, i4_bool close_on_delete_or_fail)
|
---|
195 | {
|
---|
196 | g1_loader_class *l=new g1_loader_class(in, close_on_delete_or_fail);
|
---|
197 |
|
---|
198 | if (l->error())
|
---|
199 | {
|
---|
200 | delete l;
|
---|
201 | return 0;
|
---|
202 | }
|
---|
203 |
|
---|
204 | return l;
|
---|
205 | }
|
---|
206 |
|
---|