e1e90229576fdcf6eef72af0257f189f15d36ed7
1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 {$INCLUDE a_modes.inc}
25 EBinSizeError
= Class (Exception
);
27 TBinMemoryWriter
= Class (TObject
)
33 Procedure WriteVar (var x
; varSize
: Cardinal);
34 Procedure ExtendMemory(addLen
: Cardinal);
37 Constructor Create (aSize
: Cardinal);
38 Destructor Destroy (); Override;
40 Procedure WriteByte (x
: Byte);
41 Procedure WriteWord (x
: Word);
42 Procedure WriteDWORD (x
: DWORD
);
43 Procedure WriteShortInt (x
: ShortInt);
44 Procedure WriteSmallInt (x
: SmallInt);
45 Procedure WriteInt (x
: Integer);
46 Procedure WriteSingle (x
: Single);
47 Procedure WriteBoolean (x
: Boolean);
48 Procedure WriteString (const x
: AnsiString; aMaxLen
: Word=65535);
49 Procedure WriteMemory (x
: Pointer; memSize
: Cardinal);
50 Procedure Fill (aLen
: Cardinal; aFillSym
: Byte);
51 Procedure SaveToFile (Var aFile
: File);
52 Procedure SaveToMemory (Var aMem
: TBinMemoryWriter
);
55 TBinMemoryReader
= Class (TObject
)
61 Procedure ReadVar(Var x
; varSize
: Cardinal);
65 Destructor Destroy(); Override;
66 Procedure ReadByte(Var x
: Byte);
67 Procedure ReadWord(Var x
: Word);
68 Procedure ReadDWORD(Var x
: DWORD
);
69 Procedure ReadShortInt(Var x
: ShortInt);
70 Procedure ReadSmallInt(Var x
: SmallInt);
71 Procedure ReadInt(Var x
: Integer);
72 Procedure ReadSingle(Var x
: Single);
73 Procedure ReadBoolean(Var x
: Boolean);
74 Procedure ReadString(Var x
: AnsiString);
75 Procedure ReadMemory(Var x
: Pointer; Var memSize
: Cardinal);
76 Procedure Skip(aLen
: Cardinal);
77 Procedure LoadFromFile(Var aFile
: File);
78 Procedure LoadFromMemory(Var aMem
: TBinMemoryReader
);
81 TBinFileWriter
= Class (TObject
)
88 Destructor Destroy(); Override;
89 Procedure OpenFile(Const aFileName
: String;
92 aOverWrite
: Boolean = True);
94 Procedure WriteMemory(Var aMemory
: TBinMemoryWriter
);
97 TBinFileReader
= Class (TObject
)
103 Constructor Create();
104 Destructor Destroy(); Override;
105 Function OpenFile(Const aFileName
: String;
107 aFileVer
: Byte): Boolean;
109 Procedure ReadMemory(Var aMemory
: TBinMemoryReader
);
112 procedure FillMemory(Dest
: Pointer; Len
: Cardinal; Ch
: Byte);
113 procedure CopyMemory(Dest
: Pointer; Src
: Pointer; Len
: Cardinal);
114 procedure ZeroMemory(Dest
: Pointer; Len
: Cardinal);
122 MAX_BIN_SIZE
= 4 * 1024 * 1024; // 4 MB
124 procedure CopyMemory(Dest
: Pointer; Src
: Pointer; Len
: Cardinal);
126 Move(Src
^, Dest
^, Len
);
129 procedure FillMemory(Dest
: Pointer; Len
: Cardinal; Ch
: Byte);
131 FillChar(Dest
^, Len
, Ch
);
134 procedure ZeroMemory(Dest
: Pointer; Len
: Cardinal);
136 FillChar(Dest
^, Len
, 0);
139 { T B i n M e m o r y W r i t e r : }
141 Constructor TBinMemoryWriter
.Create(aSize
: Cardinal);
147 if FSize
> MAX_BIN_SIZE
then
148 FSize
:= MAX_BIN_SIZE
;
150 GetMem(FData
, FSize
);
154 Destructor TBinMemoryWriter
.Destroy();
165 Procedure TBinMemoryWriter
.WriteVar (var x
; varSize
: Cardinal);
167 if (FPosition
+varSize
> FSize
) then ExtendMemory(varSize
);
168 CopyMemory(Pointer(PtrUInt(FData
)+FPosition
), @x
, varSize
);
169 FPosition
:= FPosition
+varSize
;
172 Procedure TBinMemoryWriter
.ExtendMemory(addLen
: Cardinal);
177 while ((FPosition
+ addLen
) > FSize
) and
178 (FSize
<= MAX_BIN_SIZE
) do
181 if FSize
> MAX_BIN_SIZE
then
183 raise EBinSizeError
.Create('TBinMemoryWriter.ExtendMemory: Tried to allocete more than 4 MB');
189 if FPosition
> 0 then
190 CopyMemory(tmp
, FData
, FPosition
);
195 e_WriteLog('Save Memory Extended: '+IntToStr(FSize
), MSG_NOTIFY
);
198 Procedure TBinMemoryWriter
.WriteByte (x
: Byte);
200 WriteVar(x
, SizeOf(Byte));
203 Procedure TBinMemoryWriter
.WriteWord (x
: Word);
205 WriteVar(x
, SizeOf(Word));
208 Procedure TBinMemoryWriter
.WriteDWORD (x
: DWORD
);
210 WriteVar(x
, SizeOf(DWORD
));
213 Procedure TBinMemoryWriter
.WriteShortInt (x
: ShortInt);
215 WriteVar(x
, SizeOf(ShortInt));
218 Procedure TBinMemoryWriter
.WriteSmallInt (x
: SmallInt);
220 WriteVar(x
, SizeOf(SmallInt));
223 Procedure TBinMemoryWriter
.WriteInt (x
: Integer);
225 WriteVar(x
, SizeOf(Integer));
228 Procedure TBinMemoryWriter
.WriteSingle (x
: Single);
230 WriteVar(x
, SizeOf(Single));
233 Procedure TBinMemoryWriter
.WriteBoolean (x
: Boolean);
237 if x
then y
:= 1 else y
:= 0;
238 WriteVar(y
, SizeOf(Byte));
241 Procedure TBinMemoryWriter
.WriteString (const x
: AnsiString; aMaxLen
: Word=65535);
245 if (Length(x
) > aMaxLen
) then len
:= aMaxLen
else len
:= Word(Length(x
));
247 if (FPosition
+SizeOf(Byte)+len
) > FSize
then ExtendMemory(SizeOf(Byte)+len
);
250 CopyMemory(Pointer(NativeUInt(FData
)+FPosition
), @len
, SizeOf(len
));
251 FPosition
:= FPosition
+SizeOf(len
);
255 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
), @x
[1], len
);
256 FPosition
:= FPosition
+len
;
260 Procedure TBinMemoryWriter
.WriteMemory (x
: Pointer; memSize
: Cardinal);
262 if (FPosition
+SizeOf(Cardinal)+memSize
) > FSize
then ExtendMemory(SizeOf(Cardinal)+memSize
);
263 // Äëèíà áëîêà ïàìÿòè
264 CopyMemory(Pointer(PtrUInt(FData
)+FPosition
), @memSize
, SizeOf(Cardinal));
265 FPosition
:= FPosition
+SizeOf(Cardinal);
267 if (memSize
> 0) then
269 CopyMemory(Pointer(PtrUInt(FData
)+FPosition
), x
, memSize
);
270 FPosition
:= FPosition
+memSize
;
274 Procedure TBinMemoryWriter
.Fill (aLen
: Cardinal; aFillSym
: Byte);
276 if (FPosition
+aLen
> FSize
) then ExtendMemory(aLen
);
279 FillMemory(Pointer(PtrUInt(FData
) + FPosition
), aLen
, aFillSym
);
280 FPosition
:= FPosition
+aLen
;
284 Procedure TBinMemoryWriter
.SaveToFile(Var aFile
: File);
290 BlockWrite(aFile
, FPosition
, SizeOf(Cardinal), nw
);
291 if nw
<> SizeOf(Cardinal) then
293 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Length');
298 BlockWrite(aFile
, FData
^, FPosition
, nw
);
299 if nw
<> FPosition
then
301 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Data');
306 Procedure TBinMemoryWriter
.SaveToMemory(Var aMem
: TBinMemoryWriter
);
310 aMem
.WriteMemory(FData
, FPosition
);
314 { T B i n M e m o r y R e a d e r : }
316 Constructor TBinMemoryReader
.Create();
323 Destructor TBinMemoryReader
.Destroy();
334 Procedure TBinMemoryReader
.ReadVar(Var x
; varSize
: Cardinal);
336 if (FPosition
+ varSize
) <= FSize
then
339 Pointer(NativeUInt(FData
) + FPosition
),
341 FPosition
:= FPosition
+ varSize
;
344 raise EBinSizeError
.Create('TBinMemoryReader.ReadVar: End of Memory');
347 Procedure TBinMemoryReader
.ReadByte(Var x
: Byte);
349 ReadVar(x
, SizeOf(Byte));
352 Procedure TBinMemoryReader
.ReadWord(Var x
: Word);
354 ReadVar(x
, SizeOf(Word));
357 Procedure TBinMemoryReader
.ReadDWORD(Var x
: DWORD
);
359 ReadVar(x
, SizeOf(DWORD
));
362 Procedure TBinMemoryReader
.ReadShortInt(Var x
: ShortInt);
364 ReadVar(x
, SizeOf(ShortInt));
367 Procedure TBinMemoryReader
.ReadSmallInt(Var x
: SmallInt);
369 ReadVar(x
, SizeOf(SmallInt));
372 Procedure TBinMemoryReader
.ReadInt(Var x
: Integer);
374 ReadVar(x
, SizeOf(Integer));
377 Procedure TBinMemoryReader
.ReadSingle(Var x
: Single);
379 ReadVar(x
, SizeOf(Single));
382 Procedure TBinMemoryReader
.ReadBoolean(Var x
: Boolean);
387 ReadVar(y
, SizeOf(Byte));
395 Procedure TBinMemoryReader
.ReadString (Var x
: AnsiString);
399 if (FPosition
+SizeOf(len
)) <= FSize
then
402 CopyMemory(@len
, Pointer(NativeUInt(FData
)+FPosition
), SizeOf(len
));
403 if (FPosition
+SizeOf(len
)+len
<= FSize
) then
405 FPosition
:= FPosition
+SizeOf(len
);
411 CopyMemory(@x
[1], Pointer(NativeUInt(FData
) + FPosition
), len
);
412 FPosition
:= FPosition
+len
;
421 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: Too Long String');
426 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: End of Memory');
430 Procedure TBinMemoryReader
.ReadMemory(Var x
: Pointer; Var memSize
: Cardinal);
432 if (FPosition
+ SizeOf(Cardinal)) <= FSize
then
434 // Äëèíà áëîêà ïàìÿòè:
436 Pointer(NativeUInt(FData
) + FPosition
),
439 if (FPosition
+ SizeOf(Cardinal) + memSize
) <= FSize
then
441 FPosition
:= FPosition
+ SizeOf(Cardinal);
447 Pointer(NativeUInt(FData
) + FPosition
),
449 FPosition
:= FPosition
+ memSize
;
455 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: Too Long Memory');
458 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: End of Memory');
461 Procedure TBinMemoryReader
.Skip(aLen
: Cardinal);
463 if (FPosition
+ aLen
) <= FSize
then
465 FPosition
:= FPosition
+ aLen
;
468 raise EBinSizeError
.Create('TBinMemoryReader.Skip: End of Memory');
471 Procedure TBinMemoryReader
.LoadFromFile(Var aFile
: File);
481 BlockRead(aFile
, aSize
, SizeOf(Cardinal), nr
);
482 if nr
<> SizeOf(Cardinal) then
484 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Length');
489 GetMem(FData
, FSize
);
492 BlockRead(aFile
, FData
^, FSize
, nr
);
495 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Data');
500 Procedure TBinMemoryReader
.LoadFromMemory(Var aMem
: TBinMemoryReader
);
507 aMem
.ReadMemory(FData
, FSize
);
512 { T B i n F i l e W r i t e r : }
514 Constructor TBinFileWriter
.Create();
519 Destructor TBinFileWriter
.Destroy();
526 Procedure TBinFileWriter
.OpenFile(Const aFileName
: String;
529 aOverWrite
: Boolean = True);
536 if (not FileExists(aFileName
)) or (aOverWrite
) then
538 AssignFile(FHandle
, aFileName
);
542 BlockWrite(FHandle
, aFileSig
, SizeOf(Cardinal), nw
);
543 if nw
<> SizeOf(Cardinal) then
545 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Signature');
550 BlockWrite(FHandle
, aFileVer
, SizeOf(Byte), nw
);
551 if nw
<> SizeOf(Byte) then
553 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Version');
563 Procedure TBinFileWriter
.Close();
567 System
.Close(FHandle
);
572 Procedure TBinFileWriter
.WriteMemory(Var aMemory
: TBinMemoryWriter
);
574 if (FOpened
) and (aMemory
<> nil) then
576 aMemory
.SaveToFile(FHandle
);
580 { T B i n F i l e R e a d e r : }
582 Constructor TBinFileReader
.Create();
587 Destructor TBinFileReader
.Destroy();
594 Function TBinFileReader
.OpenFile(Const aFileName
: String;
596 aFileVer
: Byte): Boolean;
607 if FileExists(aFileName
) then
609 AssignFile(FHandle
, aFileName
);
613 BlockRead(FHandle
, sig
, SizeOf(Cardinal), nr
);
614 if (nr
<> SizeOf(Cardinal)) then
616 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Signature');
619 if (sig
<> aFileSig
) then
621 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Signature');
626 BlockRead(FHandle
, ver
, SizeOf(Byte), nr
);
627 if (nr
<> SizeOf(Byte)) then
629 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Version');
632 if (ver
<> aFileVer
) then
634 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Version');
645 Procedure TBinFileReader
.Close();
649 System
.Close(FHandle
);
654 Procedure TBinFileReader
.ReadMemory(Var aMemory
: TBinMemoryReader
);
656 if (FOpened
) and (aMemory
<> nil) then
658 aMemory
.LoadFromFile(FHandle
);