Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmv-save.cc
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-gmapkernel
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 //******************************************************************************
25 #include "g-map-vertex.hh"
26 #include "streams.hh"
27 #include <cstring>
28 #include <map>
29 using namespace std;
30 using namespace GMap3d;
31 //******************************************************************************
32 void CGMapVertex::giveNumberToDarts(int ADirectInfoIndex)
33 {
34  CDynamicCoverageAll it(this);
35 
36  for (unsigned long int num=0; it.cont(); ++it, ++num)
37  (*it)->setDirectInfo(ADirectInfoIndex, (void *) num);
38 }
39 //******************************************************************************
40 TSaveFormat CGMapVertex::getFileFormat(const char * AFilename)
41 {
42  ifstream stream(AFilename);
43  char id[256];
44 
45  stream.getline(id,256);
46  stream.close();
47 
48  if (strcmp(id, getFileHeader(BinaryFormat))==0) return BinaryFormat;
49  if (strcmp(id, getFileHeader( AsciiFormat))==0) return AsciiFormat;
50 
51  return UnknownFormat;
52 }
53 //******************************************************************************
54 const char * CGMapVertex::getFileHeader(TSaveFormat AFormat)
55 {
56  switch (AFormat)
57  {
58  case BinaryFormat:
59  return "Moka file [binary]";
60  case AsciiFormat:
61  return "Moka file [ascii]";
62  default:
63  return NULL;
64  }
65 }
66 //******************************************************************************
67 bool CGMapVertex::save(const char * AFilename, TSaveFormat AFormat)
68 {
69  ofstream stream;
70  if ( AFormat==BinaryFormat )
71  stream.open(AFilename, ios::trunc | ios::binary);
72  else
73  stream.open(AFilename, ios::trunc);
74 
75  bool result = save(stream, AFormat);
76  stream.close();
77  return result;
78 }
79 //******************************************************************************
80 CDart* CGMapVertex::load(const char * AFilename, TSaveFormat AFormat)
81 {
82  ifstream stream;
83  if ( AFormat==BinaryFormat )
84  stream.open(AFilename, ios::binary);
85  else
86  stream.open(AFilename);
87 
88  CDart* result = load(stream, AFormat);
89  stream.close();
90  return result;
91 }
92 //******************************************************************************
93 bool CGMapVertex::save(ostream & AStream, TSaveFormat AFormat)
94 {
95  int directInfoIndex = getNewDirectInfo();
96  const char * header = getFileHeader(AFormat);
97 
98  assert(header!=NULL);
99 
100  // Numérotation des brins:
101  giveNumberToDarts(directInfoIndex);
102 
103  // Positionnement du format d'écriture:
104  switch (AFormat)
105  {
106  case AsciiFormat : setAsciiMode (); break;
107  case BinaryFormat: setBinaryMode(); break;
108  default: cerr << "CGMapVertex.save: Format inconnu!!!" << endl;
109  }
110 
111  AStream << header << endl;
112 
113  // Sauvegarde de l'état général des marques:
114  assert(NB_MARKS % 8 == 0);
115  bool m[8], u[8];
116 
117  for (int i=0; i<NB_MARKS; ++i)
118  {
119  m[i % 8] = FMaskMarks[i];
120  u[i % 8] = FUsedMarks[i];
121 
122  if (i % 8 == 7)
123  {
124  writeChar(AStream, bool2char(m)); writeSpc(AStream);
125  writeChar(AStream, bool2char(u)); writeSpc(AStream);
126  }
127  }
128 
129  writeRet(AStream);
130 
131  // Sauvegarde des brins:
132  bool ok = true;
133  CDynamicCoverageAll it(this);
134 
135  for (; ok && it.cont(); ++it)
136  {
137  CDartVertex * current = (CDartVertex *) *it;
138  ok = current->save(AStream, AFormat, directInfoIndex);
139  }
140 
141  freeDirectInfo(directInfoIndex);
142  return ok;
143 }
144 //******************************************************************************
145 CDart* CGMapVertex::load(istream & AStream, TSaveFormat AFormat)
146 {
147  // Positionnement du format de lecture:
148  switch (AFormat)
149  {
150  case AsciiFormat : setAsciiMode (); break;
151  case BinaryFormat: setBinaryMode(); break;
152  default:
153  cerr << "CGMapVertex.load: Format inconnu!!!" << endl;
154  return NULL;
155  }
156 
157  // Lecture et vérification du header:
158  {
159  char id[256];
160  AStream.getline(id, 256);
161 
162  if (strcmp(id, getFileHeader(AFormat)) != 0)
163  return NULL;
164  }
165 
166  // Lecture de l'état général des marques du fichier à charger:
167  bitset<NB_MARKS> streamUsed;
168  bitset<NB_MARKS> streamMask;
169 
170  assert(NB_MARKS % 8 == 0);
171  bool m[8],u[8];
172 
173  int i;
174 
175  for (i=0; i<NB_MARKS; ++i)
176  {
177  if (i % 8 == 0)
178  {
179  char2bool(readChar(AStream), m);
180  char2bool(readChar(AStream), u);
181  }
182 
183  if (u[i % 8] && ! FUsedMarks[i])
184  cerr << "CGMapVertex::load: Marque n°" << i
185  << " ignorée lors du chargement." << endl;
186 
187  streamUsed.set(i, u[i % 8]);
188  streamMask.set(i, m[i % 8]);
189  }
190 
191  // Lecture des brins du fichier à charger:
192  bitset<NB_MARKS> marksToKeep = FUsedMarks & streamUsed;
193 
194  int nbLoaded = 0;
195  int mark = getNewMark(); // pour savoir quels brins ont été chargés
196 
197  negateMaskMark(mark);
198 
199  CDartVertex * dart=NULL;
200  for (bool cont = true; cont; )
201  {
202  dart = (CDartVertex *) addMapDart();
203  cont = dart->load(AStream, AFormat);
204 
205  if (cont)
206  {
207  // Mise-à-jour des marques du brin chargé:
208  setMarks(dart, (dart->getMarks() ^ streamMask) & marksToKeep);
209  ++nbLoaded;
210  }
211  else
212  delMapDart(dart);
213  }
214 
215  negateMaskMark(mark);
216 
217  // Alpha-i: Transformation des indices en pointeurs:
218  CDynamicCoverageAll it(this);
219  if ( it.cont() )
220  {
221  dart=static_cast<CDartVertex*>(*it);
222 
223  CDartVertex** table = new CDartVertex* [nbLoaded];
224  i = nbLoaded;
225 
226  for (; it.cont(); ++it)
227  if (isMarked(*it, mark))
228  {
229  table[--i] = (CDartVertex *) *it;
230  unsetMark(*it, mark);
231  }
232 
233  assert(i==0);
234 
235  for (; i<nbLoaded; ++i)
236  for (int dim=0; dim<=3; ++dim)
237  {
238  int n = (long int) table[i]->getAlpha(dim) -1;
239 
240  if (n==i)
241  table[i]->setFree(dim);
242  else
243  if (n<i)
244  linkAlpha(table[i], table[n], dim);
245  }
246 
247  delete [] table;
248  }
249 
250  freeMark(mark);
251 
252  return dart;
253 }
254 //******************************************************************************
255 CDart* CGMapVertex::load(const char * AFilename)
256 {
257  TSaveFormat format= CGMapVertex::getFileFormat(AFilename);
258 
259  if ( format==UnknownFormat ) return NULL;
260  return load(AFilename,format);
261 }
262 //******************************************************************************