unnecessary messing with code
[k8-i-v-a-n.git] / src / felib / fesave.h
blob01304944e9ad719464b25aefe6e35922ba7a2675
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
12 #ifndef __FELIB_SAVE_H__
13 #define __FELIB_SAVE_H__
15 #include <ctime>
16 #include <cstdio>
17 #include <vector>
18 #include <stack>
19 #include <deque>
20 #include <list>
21 #include <map>
22 #include <set>
24 #ifdef USE_ZLIB
25 # include <zlib.h>
26 #endif
29 #include "error.h"
30 #include "festring.h"
31 #include "fearray.h"
34 #define RAW_SAVE_LOAD(type) \
35 inline outputfile &operator << (outputfile &SaveFile, type Value) { \
36 SaveFile.Write(reinterpret_cast<char *>(&Value), sizeof(Value)); \
37 return SaveFile; \
38 } \
40 inline inputfile &operator >> (inputfile &SaveFile, type &Value) { \
41 SaveFile.Read(reinterpret_cast<char *>(&Value), sizeof(Value)); \
42 return SaveFile; \
46 class inputfile;
47 class outputfile;
50 typedef std::map<festring, sLong> valuemap;
53 class outputfile {
54 public:
55 outputfile (cfestring &FileName, truth maxcomp, truth AbortOnErr=true);
56 ~outputfile ();
58 void Put (char What);
59 void Write (cchar *Offset, sLong Size);
60 truth IsOpen () { return (Buffer != 0); }
61 void Close ();
62 void Flush ();
64 private:
65 #ifdef USE_ZLIB
66 gzFile Buffer;
67 #else
68 FILE *Buffer;
69 #endif
70 festring FileName;
74 typedef festring (*InputFileGetVarFn) (inputfile *fl, cfestring &name);
76 class inputfile {
77 public:
78 inputfile (cfestring &FileName, const valuemap *ValueMap=0, truth AbortOnErr=true);
79 virtual ~inputfile ();
81 void SkipSpaces ();
83 festring ReadCode (truth AbortOnEOF=true);
84 festring ReadWord (truth AbortOnEOF=true);
85 void ReadWord (festring &str, truth AbortOnEOF=true, truth skipIt=false);
86 char ReadLetter (truth AbortOnEOF=true);
87 sLong ReadNumber (int CallLevel=HIGHEST, truth PreserveTerminator=false, truth *wasCloseBrc=0);
88 festring ReadStringOrNumber (sLong *num, truth *isString, truth PreserveTerminator=false, truth *wasCloseBrc=0);
89 v2 ReadVector2d ();
90 rect ReadRect ();
91 int Get ();
92 void Unget (int ch);
93 void Read (char *Offset, sLong Size);
94 truth IsOpen () { return (Buffer != 0); }
95 truth Eof ();
96 void ClearFlags ();
97 void SeekPosBegin (sLong Offset);
98 void SeekPosCurrent (sLong Offset);
99 void SeekPosEnd (sLong Offset);
100 sLong TellPos ();
101 //feuLong TellLine () { return TellLineOfPos(TellPos()); }
102 //feuLong TellLineOfPos (sLong);
103 cfestring &GetFileName () const { return FileName; }
104 void Close ();
106 static truth fileExists (const festring &fname);
107 static festring GetMyDir (void);
109 festring getVar (cfestring &name);
110 void setVar (cfestring &name, cfestring &value);
111 truth delVar (cfestring &name);
113 void setGetVarCB (InputFileGetVarFn cb) { mGetVar = cb; }
115 void die (cfestring &msg);
117 inline int TokenLine () const { return mTokenLine; }
118 inline int CurrentLine () const { return mCurrentLine; }
120 protected:
121 festring ReadNumberIntr (int CallLevel, sLong *num, truth *isString, truth allowStr, truth PreserveTerminator, truth *wasCloseBrc);
122 int HandlePunct (festring &String, int Char, int Mode);
124 festring findVar (cfestring &name, truth *found) const;
125 void readWordIntr (festring &String, truth AbortOnEOF);
127 festring readCondition (festring &token, int prio, truth skipIt);
129 protected:
130 typedef std::map<festring, festring> VarMap;
131 #ifdef USE_ZLIB
132 gzFile Buffer;
133 #else
134 FILE *Buffer;
135 #endif
136 festring FileName;
137 const valuemap *ValueMap;
138 truth lastWordWasString;
139 VarMap mVars;
140 InputFileGetVarFn mGetVar;
141 std::stack<int> mIfStack;
142 #ifdef USE_ZLIB
143 int mFileSize;
144 #endif
145 int mCharBuf[4];
146 int mCharBufPos;
147 int mCurrentLine;
148 int mTokenLine;
152 class meminputfile : public inputfile {
153 public:
154 meminputfile (cfestring &str, const valuemap *ValueMap=0);
155 virtual ~meminputfile ();
157 protected:
158 void *buf;
159 int bufSize;
160 festring tfname;
164 /* Reads a binary form variable of type type and returns it.
165 * An inputfile template member function would be far more elegant,
166 * but VC doesn't seem to understand it. */
167 template <class type> inline type _ReadType_ (inputfile &SaveFile, const char *tag) {
168 type Variable;
170 //fprintf(stderr, "ReadType: [%s]\n", tag);
171 SaveFile >> Variable;
172 return Variable;
175 #define ReadType(typename,fl) _ReadType_<typename>(fl, #typename)
177 inline void ReadData (char &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
178 inline void ReadData (uChar &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
179 inline void ReadData (short &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
180 inline void ReadData (uShort &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
181 //inline void ReadData (sLong &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); } //k8:64
182 inline void ReadData (feuLong &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
183 inline void ReadData (int &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); }
184 inline void ReadData (packv2 &Type, inputfile &SaveFile) { Type = SaveFile.ReadVector2d(); }
185 inline void ReadData (v2 &Type, inputfile &SaveFile) { Type = SaveFile.ReadVector2d(); }
186 inline void ReadData (rect &Type, inputfile &SaveFile) { Type = SaveFile.ReadRect(); }
188 void ReadData (festring &, inputfile &);
189 void ReadData (fearray<sLong> &, inputfile &);
190 void ReadData (fearray<festring> &, inputfile &);
192 //TODO: add ':=' syntax
193 template <class type> inline void ReadData (fearray<type> &Array, inputfile &SaveFile) {
194 Array.Clear();
195 festring Word;
196 SaveFile.ReadWord(Word);
197 //if (Word == "=") SaveFile.ReadWord(Word);
198 if (Word == "==") {
199 Array.Allocate(1);
200 ReadData(Array.Data[0], SaveFile);
201 return;
203 if (Word != "=") ABORT("Array syntax error: '=' or '==' expected in file %s, line %u!", SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
204 SaveFile.ReadWord(Word);
205 if (Word != "{") ABORT("Array syntax error \"%s\" found in file %s, line %u!", Word.CStr(), SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
206 typedef typename fearray<type>::sizetype sizetype;
207 sizetype Size = SaveFile.ReadNumber();
208 Array.Allocate(Size);
209 for (sizetype c = 0; c < Size; ++c) ReadData(Array.Data[c], SaveFile);
210 if (SaveFile.ReadWord() != "}") ABORT("Illegal array terminator \"%s\" encountered in file %s, line %u!", Word.CStr(), SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
214 inline outputfile &operator << (outputfile &SaveFile, char Value) {
215 SaveFile.Put(Value);
216 return SaveFile;
220 inline inputfile &operator >> (inputfile &SaveFile, char &Value) {
221 Value = SaveFile.Get();
222 return SaveFile;
226 inline outputfile &operator << (outputfile &SaveFile, uChar Value) {
227 SaveFile.Put(Value);
228 return SaveFile;
232 inline inputfile &operator >> (inputfile &SaveFile, uChar &Value) {
233 Value = SaveFile.Get();
234 return SaveFile;
238 inline outputfile &operator << (outputfile &SaveFile, short Value) {
239 SaveFile.Put(Value);
240 SaveFile.Put(Value >> 8);
241 return SaveFile;
245 inline inputfile &operator >> (inputfile &SaveFile, short &Value) {
246 int LowWord = SaveFile.Get();
247 Value = SaveFile.Get() << 8 | LowWord;
248 return SaveFile;
252 inline outputfile &operator << (outputfile &SaveFile, uShort Value) {
253 SaveFile.Put(Value);
254 SaveFile.Put(Value >> 8);
255 return SaveFile;
259 inline inputfile &operator >> (inputfile &SaveFile, uShort &Value) {
260 int LowWord = SaveFile.Get();
261 Value = SaveFile.Get() << 8 | LowWord;
262 return SaveFile;
266 //RAW_SAVE_LOAD(sLong); //k8:64
267 //RAW_SAVE_LOAD(feuLong); //k8:64
268 RAW_SAVE_LOAD(int);
269 RAW_SAVE_LOAD(uInt);
270 RAW_SAVE_LOAD(double);
271 RAW_SAVE_LOAD(packv2);
272 RAW_SAVE_LOAD(v2);
273 RAW_SAVE_LOAD(rect);
274 RAW_SAVE_LOAD(time_t);
277 outputfile &operator << (outputfile &, cfestring &);
278 inputfile &operator >> (inputfile &, festring &);
279 outputfile &operator << (outputfile &, cchar *);
280 inputfile &operator >> (inputfile &, char *&);
283 template <class type1, class type2> inline outputfile &operator << (outputfile &SaveFile, const std::pair<type1, type2> &Pair) {
284 SaveFile << Pair.first << Pair.second;
285 return SaveFile;
288 template <class type1, class type2> inline inputfile &operator >> (inputfile &SaveFile, std::pair<type1, type2> &Pair) {
289 SaveFile >> Pair.first >> Pair.second;
290 return SaveFile;
293 template <class type> inline outputfile &operator << (outputfile &SaveFile, const std::vector<type> &Vector) {
294 SaveFile << feuLong(Vector.size());
295 for (feuLong c = 0; c < Vector.size(); ++c) SaveFile << Vector[c];
296 return SaveFile;
299 template <class type> inline inputfile &operator >> (inputfile &SaveFile, std::vector<type> &Vector) {
300 Vector.resize(ReadType(feuLong, SaveFile), type());
301 for (feuLong c = 0; c < Vector.size(); ++c) SaveFile >> Vector[c];
302 return SaveFile;
305 template <class type> inline outputfile &operator << (outputfile &SaveFile, const std::deque<type> &Deque) {
306 SaveFile << feuLong(Deque.size());
307 for (feuLong c = 0; c < Deque.size(); ++c) SaveFile << Deque[c];
308 return SaveFile;
311 template <class type> inline inputfile &operator >> (inputfile &SaveFile, std::deque<type> &Deque) {
312 Deque.resize(ReadType(feuLong, SaveFile), type());
313 for (feuLong c = 0; c < Deque.size(); ++c) SaveFile >> Deque[c];
314 return SaveFile;
317 template <class type> inline outputfile &operator << (outputfile &SaveFile, const std::list<type> &List) {
318 SaveFile << feuLong(List.size());
319 for (typename std::list<type>::const_iterator i = List.begin(); i != List.end(); ++i) SaveFile << *i;
320 return SaveFile;
323 template <class type> inline inputfile &operator >> (inputfile &SaveFile, std::list<type> &List) {
324 List.resize(ReadType(feuLong, SaveFile), type());
325 for (typename std::list<type>::iterator i = List.begin(); i != List.end(); ++i) SaveFile >> *i;
326 return SaveFile;
329 template <class type1, class type2> inline outputfile &operator << (outputfile &SaveFile, const std::map<type1, type2> &Map) {
330 SaveFile << feuLong(Map.size());
331 for (typename std::map<type1, type2>::const_iterator i = Map.begin(); i != Map.end(); ++i) SaveFile << i->first << i->second;
332 return SaveFile;
335 template <class type1, class type2> inline inputfile &operator >> (inputfile &SaveFile, std::map<type1, type2> &Map) {
336 Map.clear();
337 type1 First;
338 feuLong Size;
339 SaveFile >> Size;
340 typename std::map<type1, type2>::iterator i;
341 for (feuLong c = 0; c < Size; ++c) {
342 SaveFile >> First;
343 i = Map.insert(Map.end(), std::make_pair(First, type2()));
344 SaveFile >> i->second;
346 return SaveFile;
349 template <class type> inline outputfile &operator << (outputfile &SaveFile, const std::set<type> &Set) {
350 SaveFile << feuLong(Set.size());
351 for (typename std::set<type>::const_iterator i = Set.begin(); i != Set.end(); ++i) SaveFile << *i;
352 return SaveFile;
355 template <class type> inline inputfile &operator >> (inputfile &SaveFile, std::set<type> &Set) {
356 Set.clear();
357 feuLong Size;
358 SaveFile >> Size;
359 for (feuLong c = 0; c < Size; ++c) {
360 type Value;
361 SaveFile >> Value;
362 Set.insert(Value);
364 return SaveFile;
367 template <class type> inline outputfile &operator << (outputfile &SaveFile, const fearray<type> &Array) {
368 typename fearray<type>::sizetype c, Size = Array.Size;
369 SaveFile << Size;
370 for (c = 0; c < Size; ++c) SaveFile << Array[c];
371 return SaveFile;
374 template <class type> inline inputfile &operator >> (inputfile &SaveFile, fearray<type> &Array) {
375 typename fearray<type>::sizetype c, Size;
376 SaveFile >> Size;
377 Array.Allocate(Size);
378 for (c = 0; c < Size; ++c) SaveFile >> Array[c];
379 return SaveFile;
382 template <class type> inline outputfile &SaveLinkedList (outputfile &SaveFile, const type *Element) {
383 for (const type* E = Element; E; E = E->Next) {
384 SaveFile.Put(true);
385 SaveFile << E;
387 SaveFile.Put(false);
388 return SaveFile;
391 template <class type> inline inputfile &LoadLinkedList(inputfile &SaveFile, type *&Element) {
392 if (SaveFile.Get()) {
393 SaveFile >> Element;
394 type *E;
395 for (E = Element; SaveFile.Get(); E = E->Next) SaveFile >> E->Next;
396 E->Next = 0;
397 } else {
398 Element = 0;
400 return SaveFile;
403 template <class type> inline outputfile &SaveArray (outputfile &SaveFile, const type *Array, int Count) {
404 for (int c = 0; c < Count; ++c) SaveFile << Array[c];
405 return SaveFile;
408 template <class type> inline inputfile &LoadArray (inputfile &SaveFile, type *Array, int Count) {
409 for (int c = 0; c < Count; ++c) SaveFile >> Array[c];
410 return SaveFile;
414 #endif