source: golgotha/src/golg/saver.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 4.2 KB
RevLine 
[80]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
16g1_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
24g1_saver_class::~g1_saver_class()
25{
26  g1_global_id.free_remapping(remap);
27}
28
29void 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
39i4_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
61i4_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
93g1_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
101g1_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
110void 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
118void 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
125void 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
131w32 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
140void 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
159void 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
194g1_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
Note: See TracBrowser for help on using the repository browser.