3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
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__
34 #define RAW_SAVE_LOAD(type) \
35 inline outputfile &operator << (outputfile &SaveFile, type Value) { \
36 SaveFile.Write(reinterpret_cast<char *>(&Value), sizeof(Value)); \
40 inline inputfile &operator >> (inputfile &SaveFile, type &Value) { \
41 SaveFile.Read(reinterpret_cast<char *>(&Value), sizeof(Value)); \
50 typedef std::map
<festring
, sLong
> valuemap
;
55 outputfile (cfestring
&FileName
, truth maxcomp
, truth AbortOnErr
=true);
59 void Write (cchar
*Offset
, sLong Size
);
60 truth
IsOpen () { return (Buffer
!= 0); }
74 typedef festring (*InputFileGetVarFn
) (inputfile
*fl
, cfestring
&name
);
78 inputfile (cfestring
&FileName
, const valuemap
*ValueMap
=0, truth AbortOnErr
=true);
79 virtual ~inputfile ();
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);
93 void Read (char *Offset
, sLong Size
);
94 truth
IsOpen () { return (Buffer
!= 0); }
97 void SeekPosBegin (sLong Offset
);
98 void SeekPosCurrent (sLong Offset
);
99 void SeekPosEnd (sLong Offset
);
101 //feuLong TellLine () { return TellLineOfPos(TellPos()); }
102 //feuLong TellLineOfPos (sLong);
103 cfestring
&GetFileName () const { return FileName
; }
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
; }
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
);
130 typedef std::map
<festring
, festring
> VarMap
;
137 const valuemap
*ValueMap
;
138 truth lastWordWasString
;
140 InputFileGetVarFn mGetVar
;
141 std::stack
<int> mIfStack
;
152 class meminputfile
: public inputfile
{
154 meminputfile (cfestring
&str
, const valuemap
*ValueMap
=0);
155 virtual ~meminputfile ();
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
) {
170 //fprintf(stderr, "ReadType: [%s]\n", tag);
171 SaveFile
>> 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
) {
196 SaveFile
.ReadWord(Word
);
197 //if (Word == "=") SaveFile.ReadWord(Word);
200 ReadData(Array
.Data
[0], SaveFile
);
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
) {
220 inline inputfile
&operator >> (inputfile
&SaveFile
, char &Value
) {
221 Value
= SaveFile
.Get();
226 inline outputfile
&operator << (outputfile
&SaveFile
, uChar Value
) {
232 inline inputfile
&operator >> (inputfile
&SaveFile
, uChar
&Value
) {
233 Value
= SaveFile
.Get();
238 inline outputfile
&operator << (outputfile
&SaveFile
, short Value
) {
240 SaveFile
.Put(Value
>> 8);
245 inline inputfile
&operator >> (inputfile
&SaveFile
, short &Value
) {
246 int LowWord
= SaveFile
.Get();
247 Value
= SaveFile
.Get() << 8 | LowWord
;
252 inline outputfile
&operator << (outputfile
&SaveFile
, uShort Value
) {
254 SaveFile
.Put(Value
>> 8);
259 inline inputfile
&operator >> (inputfile
&SaveFile
, uShort
&Value
) {
260 int LowWord
= SaveFile
.Get();
261 Value
= SaveFile
.Get() << 8 | LowWord
;
266 //RAW_SAVE_LOAD(sLong); //k8:64
267 //RAW_SAVE_LOAD(feuLong); //k8:64
270 RAW_SAVE_LOAD(double);
271 RAW_SAVE_LOAD(packv2
);
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
;
288 template <class type1
, class type2
> inline inputfile
&operator >> (inputfile
&SaveFile
, std::pair
<type1
, type2
> &Pair
) {
289 SaveFile
>> Pair
.first
>> Pair
.second
;
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
];
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
];
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
];
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
];
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
;
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
;
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
;
335 template <class type1
, class type2
> inline inputfile
&operator >> (inputfile
&SaveFile
, std::map
<type1
, type2
> &Map
) {
340 typename
std::map
<type1
, type2
>::iterator i
;
341 for (feuLong c
= 0; c
< Size
; ++c
) {
343 i
= Map
.insert(Map
.end(), std::make_pair(First
, type2()));
344 SaveFile
>> i
->second
;
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
;
355 template <class type
> inline inputfile
&operator >> (inputfile
&SaveFile
, std::set
<type
> &Set
) {
359 for (feuLong c
= 0; c
< Size
; ++c
) {
367 template <class type
> inline outputfile
&operator << (outputfile
&SaveFile
, const fearray
<type
> &Array
) {
368 typename fearray
<type
>::sizetype c
, Size
= Array
.Size
;
370 for (c
= 0; c
< Size
; ++c
) SaveFile
<< Array
[c
];
374 template <class type
> inline inputfile
&operator >> (inputfile
&SaveFile
, fearray
<type
> &Array
) {
375 typename fearray
<type
>::sizetype c
, Size
;
377 Array
.Allocate(Size
);
378 for (c
= 0; c
< Size
; ++c
) SaveFile
>> Array
[c
];
382 template <class type
> inline outputfile
&SaveLinkedList (outputfile
&SaveFile
, const type
*Element
) {
383 for (const type
* E
= Element
; E
; E
= E
->Next
) {
391 template <class type
> inline inputfile
&LoadLinkedList(inputfile
&SaveFile
, type
*&Element
) {
392 if (SaveFile
.Get()) {
395 for (E
= Element
; SaveFile
.Get(); E
= E
->Next
) SaveFile
>> E
->Next
;
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
];
408 template <class type
> inline inputfile
&LoadArray (inputfile
&SaveFile
, type
*Array
, int Count
) {
409 for (int c
= 0; c
< Count
; ++c
) SaveFile
>> Array
[c
];