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;
39 Procedure WriteByte(Var x
: Byte);
40 Procedure WriteWord(Var x
: Word);
41 Procedure WriteDWORD(Var x
: DWORD
);
42 Procedure WriteShortInt(Var x
: ShortInt);
43 Procedure WriteSmallInt(Var x
: SmallInt);
44 Procedure WriteInt(Var x
: Integer);
45 Procedure WriteSingle(Var x
: Single);
46 Procedure WriteBoolean(Var x
: Boolean);
47 Procedure WriteString(const x
: AnsiString; aMaxLen
: Word=65535);
48 Procedure WriteMemory(Var x
: Pointer; memSize
: Cardinal);
49 Procedure Fill(aLen
: Cardinal; aFillSym
: Byte);
50 Procedure SaveToFile(Var aFile
: File);
51 Procedure SaveToMemory(Var aMem
: TBinMemoryWriter
);
54 TBinMemoryReader
= Class (TObject
)
60 Procedure ReadVar(Var x
; varSize
: Cardinal);
64 Destructor Destroy(); Override;
65 Procedure ReadByte(Var x
: Byte);
66 Procedure ReadWord(Var x
: Word);
67 Procedure ReadDWORD(Var x
: DWORD
);
68 Procedure ReadShortInt(Var x
: ShortInt);
69 Procedure ReadSmallInt(Var x
: SmallInt);
70 Procedure ReadInt(Var x
: Integer);
71 Procedure ReadSingle(Var x
: Single);
72 Procedure ReadBoolean(Var x
: Boolean);
73 Procedure ReadString(Var x
: AnsiString);
74 Procedure ReadMemory(Var x
: Pointer; Var memSize
: Cardinal);
75 Procedure Skip(aLen
: Cardinal);
76 Procedure LoadFromFile(Var aFile
: File);
77 Procedure LoadFromMemory(Var aMem
: TBinMemoryReader
);
80 TBinFileWriter
= Class (TObject
)
87 Destructor Destroy(); Override;
88 Procedure OpenFile(Const aFileName
: String;
91 aOverWrite
: Boolean = True);
93 Procedure WriteMemory(Var aMemory
: TBinMemoryWriter
);
96 TBinFileReader
= Class (TObject
)
102 Constructor Create();
103 Destructor Destroy(); Override;
104 Function OpenFile(Const aFileName
: String;
106 aFileVer
: Byte): Boolean;
108 Procedure ReadMemory(Var aMemory
: TBinMemoryReader
);
111 procedure FillMemory(Dest
: Pointer; Len
: Cardinal; Ch
: Byte);
112 procedure CopyMemory(Dest
: Pointer; Src
: Pointer; Len
: Cardinal);
113 procedure ZeroMemory(Dest
: Pointer; Len
: Cardinal);
121 MAX_BIN_SIZE
= 4 * 1024 * 1024; // 4 MB
123 procedure CopyMemory(Dest
: Pointer; Src
: Pointer; Len
: Cardinal);
125 Move(Src
^, Dest
^, Len
);
128 procedure FillMemory(Dest
: Pointer; Len
: Cardinal; Ch
: Byte);
130 FillChar(Dest
^, Len
, Ch
);
133 procedure ZeroMemory(Dest
: Pointer; Len
: Cardinal);
135 FillChar(Dest
^, Len
, 0);
138 { T B i n M e m o r y W r i t e r : }
140 Constructor TBinMemoryWriter
.Create(aSize
: Cardinal);
146 if FSize
> MAX_BIN_SIZE
then
147 FSize
:= MAX_BIN_SIZE
;
149 GetMem(FData
, FSize
);
153 Destructor TBinMemoryWriter
.Destroy();
164 Procedure TBinMemoryWriter
.WriteVar(Var x
; varSize
: Cardinal);
166 if (FPosition
+ varSize
) > FSize
then
167 ExtendMemory(varSize
);
169 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
171 FPosition
:= FPosition
+ varSize
;
174 Procedure TBinMemoryWriter
.ExtendMemory(addLen
: Cardinal);
179 while ((FPosition
+ addLen
) > FSize
) and
180 (FSize
<= MAX_BIN_SIZE
) do
183 if FSize
> MAX_BIN_SIZE
then
185 raise EBinSizeError
.Create('TBinMemoryWriter.ExtendMemory: Tried to allocete more than 4 MB');
191 if FPosition
> 0 then
192 CopyMemory(tmp
, FData
, FPosition
);
197 e_WriteLog('Save Memory Extended: '+IntToStr(FSize
), MSG_NOTIFY
);
200 Procedure TBinMemoryWriter
.WriteByte(Var x
: Byte);
202 WriteVar(x
, SizeOf(Byte));
205 Procedure TBinMemoryWriter
.WriteWord(Var x
: Word);
207 WriteVar(x
, SizeOf(Word));
210 Procedure TBinMemoryWriter
.WriteDWORD(Var x
: DWORD
);
212 WriteVar(x
, SizeOf(DWORD
));
215 Procedure TBinMemoryWriter
.WriteShortInt(Var x
: ShortInt);
217 WriteVar(x
, SizeOf(ShortInt));
220 Procedure TBinMemoryWriter
.WriteSmallInt(Var x
: SmallInt);
222 WriteVar(x
, SizeOf(SmallInt));
225 Procedure TBinMemoryWriter
.WriteInt(Var x
: Integer);
227 WriteVar(x
, SizeOf(Integer));
230 Procedure TBinMemoryWriter
.WriteSingle(Var x
: Single);
232 WriteVar(x
, SizeOf(Single));
235 Procedure TBinMemoryWriter
.WriteBoolean(Var x
: Boolean);
245 WriteVar(y
, SizeOf(Byte));
248 Procedure TBinMemoryWriter
.WriteString (const x
: AnsiString; aMaxLen
: Word=65535);
252 if (Length(x
) > aMaxLen
) then len
:= aMaxLen
else len
:= Word(Length(x
));
254 if (FPosition
+SizeOf(Byte)+len
) > FSize
then ExtendMemory(SizeOf(Byte)+len
);
257 CopyMemory(Pointer(NativeUInt(FData
)+FPosition
), @len
, SizeOf(len
));
258 FPosition
:= FPosition
+SizeOf(len
);
262 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
), @x
[1], len
);
263 FPosition
:= FPosition
+len
;
267 Procedure TBinMemoryWriter
.WriteMemory(Var x
: Pointer; memSize
: Cardinal);
269 if (FPosition
+ SizeOf(Cardinal) + memSize
) > FSize
then
270 ExtendMemory(SizeOf(Cardinal) + memSize
);
272 // Äëèíà áëîêà ïàìÿòè:
273 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
274 @memSize
, SizeOf(Cardinal));
275 FPosition
:= FPosition
+ SizeOf(Cardinal);
279 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
281 FPosition
:= FPosition
+ memSize
;
285 Procedure TBinMemoryWriter
.Fill(aLen
: Cardinal; aFillSym
: Byte);
287 if (FPosition
+ aLen
) > FSize
then
292 FillMemory(Pointer(NativeUInt(FData
) + FPosition
),
294 FPosition
:= FPosition
+ aLen
;
298 Procedure TBinMemoryWriter
.SaveToFile(Var aFile
: File);
304 BlockWrite(aFile
, FPosition
, SizeOf(Cardinal), nw
);
305 if nw
<> SizeOf(Cardinal) then
307 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Length');
312 BlockWrite(aFile
, FData
^, FPosition
, nw
);
313 if nw
<> FPosition
then
315 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Data');
320 Procedure TBinMemoryWriter
.SaveToMemory(Var aMem
: TBinMemoryWriter
);
324 aMem
.WriteMemory(FData
, FPosition
);
328 { T B i n M e m o r y R e a d e r : }
330 Constructor TBinMemoryReader
.Create();
337 Destructor TBinMemoryReader
.Destroy();
348 Procedure TBinMemoryReader
.ReadVar(Var x
; varSize
: Cardinal);
350 if (FPosition
+ varSize
) <= FSize
then
353 Pointer(NativeUInt(FData
) + FPosition
),
355 FPosition
:= FPosition
+ varSize
;
358 raise EBinSizeError
.Create('TBinMemoryReader.ReadVar: End of Memory');
361 Procedure TBinMemoryReader
.ReadByte(Var x
: Byte);
363 ReadVar(x
, SizeOf(Byte));
366 Procedure TBinMemoryReader
.ReadWord(Var x
: Word);
368 ReadVar(x
, SizeOf(Word));
371 Procedure TBinMemoryReader
.ReadDWORD(Var x
: DWORD
);
373 ReadVar(x
, SizeOf(DWORD
));
376 Procedure TBinMemoryReader
.ReadShortInt(Var x
: ShortInt);
378 ReadVar(x
, SizeOf(ShortInt));
381 Procedure TBinMemoryReader
.ReadSmallInt(Var x
: SmallInt);
383 ReadVar(x
, SizeOf(SmallInt));
386 Procedure TBinMemoryReader
.ReadInt(Var x
: Integer);
388 ReadVar(x
, SizeOf(Integer));
391 Procedure TBinMemoryReader
.ReadSingle(Var x
: Single);
393 ReadVar(x
, SizeOf(Single));
396 Procedure TBinMemoryReader
.ReadBoolean(Var x
: Boolean);
401 ReadVar(y
, SizeOf(Byte));
409 Procedure TBinMemoryReader
.ReadString (Var x
: AnsiString);
413 if (FPosition
+SizeOf(len
)) <= FSize
then
416 CopyMemory(@len
, Pointer(NativeUInt(FData
)+FPosition
), SizeOf(len
));
417 if (FPosition
+SizeOf(len
)+len
<= FSize
) then
419 FPosition
:= FPosition
+SizeOf(len
);
425 CopyMemory(@x
[1], Pointer(NativeUInt(FData
) + FPosition
), len
);
426 FPosition
:= FPosition
+len
;
435 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: Too Long String');
440 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: End of Memory');
444 Procedure TBinMemoryReader
.ReadMemory(Var x
: Pointer; Var memSize
: Cardinal);
446 if (FPosition
+ SizeOf(Cardinal)) <= FSize
then
448 // Äëèíà áëîêà ïàìÿòè:
450 Pointer(NativeUInt(FData
) + FPosition
),
453 if (FPosition
+ SizeOf(Cardinal) + memSize
) <= FSize
then
455 FPosition
:= FPosition
+ SizeOf(Cardinal);
461 Pointer(NativeUInt(FData
) + FPosition
),
463 FPosition
:= FPosition
+ memSize
;
469 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: Too Long Memory');
472 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: End of Memory');
475 Procedure TBinMemoryReader
.Skip(aLen
: Cardinal);
477 if (FPosition
+ aLen
) <= FSize
then
479 FPosition
:= FPosition
+ aLen
;
482 raise EBinSizeError
.Create('TBinMemoryReader.Skip: End of Memory');
485 Procedure TBinMemoryReader
.LoadFromFile(Var aFile
: File);
495 BlockRead(aFile
, aSize
, SizeOf(Cardinal), nr
);
496 if nr
<> SizeOf(Cardinal) then
498 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Length');
503 GetMem(FData
, FSize
);
506 BlockRead(aFile
, FData
^, FSize
, nr
);
509 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Data');
514 Procedure TBinMemoryReader
.LoadFromMemory(Var aMem
: TBinMemoryReader
);
521 aMem
.ReadMemory(FData
, FSize
);
526 { T B i n F i l e W r i t e r : }
528 Constructor TBinFileWriter
.Create();
533 Destructor TBinFileWriter
.Destroy();
540 Procedure TBinFileWriter
.OpenFile(Const aFileName
: String;
543 aOverWrite
: Boolean = True);
550 if (not FileExists(aFileName
)) or (aOverWrite
) then
552 AssignFile(FHandle
, aFileName
);
556 BlockWrite(FHandle
, aFileSig
, SizeOf(Cardinal), nw
);
557 if nw
<> SizeOf(Cardinal) then
559 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Signature');
564 BlockWrite(FHandle
, aFileVer
, SizeOf(Byte), nw
);
565 if nw
<> SizeOf(Byte) then
567 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Version');
577 Procedure TBinFileWriter
.Close();
581 System
.Close(FHandle
);
586 Procedure TBinFileWriter
.WriteMemory(Var aMemory
: TBinMemoryWriter
);
588 if (FOpened
) and (aMemory
<> nil) then
590 aMemory
.SaveToFile(FHandle
);
594 { T B i n F i l e R e a d e r : }
596 Constructor TBinFileReader
.Create();
601 Destructor TBinFileReader
.Destroy();
608 Function TBinFileReader
.OpenFile(Const aFileName
: String;
610 aFileVer
: Byte): Boolean;
621 if FileExists(aFileName
) then
623 AssignFile(FHandle
, aFileName
);
627 BlockRead(FHandle
, sig
, SizeOf(Cardinal), nr
);
628 if (nr
<> SizeOf(Cardinal)) then
630 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Signature');
633 if (sig
<> aFileSig
) then
635 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Signature');
640 BlockRead(FHandle
, ver
, SizeOf(Byte), nr
);
641 if (nr
<> SizeOf(Byte)) then
643 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Version');
646 if (ver
<> aFileVer
) then
648 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Version');
659 Procedure TBinFileReader
.Close();
663 System
.Close(FHandle
);
668 Procedure TBinFileReader
.ReadMemory(Var aMemory
: TBinMemoryReader
);
670 if (FOpened
) and (aMemory
<> nil) then
672 aMemory
.LoadFromFile(FHandle
);