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(Var x
: String; aMaxLen
: Byte = 255);
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
: String);
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(Var x
: String; aMaxLen
: Byte = 255);
253 len
:= Min(Length(x
), aMaxLen
);
255 if (FPosition
+ SizeOf(Byte) + len
) > FSize
then
256 ExtendMemory(SizeOf(Byte) + len
);
259 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
261 FPosition
:= FPosition
+ SizeOf(Byte);
265 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
267 FPosition
:= FPosition
+ len
;
271 Procedure TBinMemoryWriter
.WriteMemory(Var x
: Pointer; memSize
: Cardinal);
273 if (FPosition
+ SizeOf(Cardinal) + memSize
) > FSize
then
274 ExtendMemory(SizeOf(Cardinal) + memSize
);
276 // Äëèíà áëîêà ïàìÿòè:
277 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
278 @memSize
, SizeOf(Cardinal));
279 FPosition
:= FPosition
+ SizeOf(Cardinal);
283 CopyMemory(Pointer(NativeUInt(FData
) + FPosition
),
285 FPosition
:= FPosition
+ memSize
;
289 Procedure TBinMemoryWriter
.Fill(aLen
: Cardinal; aFillSym
: Byte);
291 if (FPosition
+ aLen
) > FSize
then
296 FillMemory(Pointer(NativeUInt(FData
) + FPosition
),
298 FPosition
:= FPosition
+ aLen
;
302 Procedure TBinMemoryWriter
.SaveToFile(Var aFile
: File);
308 BlockWrite(aFile
, FPosition
, SizeOf(Cardinal), nw
);
309 if nw
<> SizeOf(Cardinal) then
311 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Length');
316 BlockWrite(aFile
, FData
^, FPosition
, nw
);
317 if nw
<> FPosition
then
319 raise EInOutError
.Create('TBinMemoryWriter.SaveToFile: Writing Data');
324 Procedure TBinMemoryWriter
.SaveToMemory(Var aMem
: TBinMemoryWriter
);
328 aMem
.WriteMemory(FData
, FPosition
);
332 { T B i n M e m o r y R e a d e r : }
334 Constructor TBinMemoryReader
.Create();
341 Destructor TBinMemoryReader
.Destroy();
352 Procedure TBinMemoryReader
.ReadVar(Var x
; varSize
: Cardinal);
354 if (FPosition
+ varSize
) <= FSize
then
357 Pointer(NativeUInt(FData
) + FPosition
),
359 FPosition
:= FPosition
+ varSize
;
362 raise EBinSizeError
.Create('TBinMemoryReader.ReadVar: End of Memory');
365 Procedure TBinMemoryReader
.ReadByte(Var x
: Byte);
367 ReadVar(x
, SizeOf(Byte));
370 Procedure TBinMemoryReader
.ReadWord(Var x
: Word);
372 ReadVar(x
, SizeOf(Word));
375 Procedure TBinMemoryReader
.ReadDWORD(Var x
: DWORD
);
377 ReadVar(x
, SizeOf(DWORD
));
380 Procedure TBinMemoryReader
.ReadShortInt(Var x
: ShortInt);
382 ReadVar(x
, SizeOf(ShortInt));
385 Procedure TBinMemoryReader
.ReadSmallInt(Var x
: SmallInt);
387 ReadVar(x
, SizeOf(SmallInt));
390 Procedure TBinMemoryReader
.ReadInt(Var x
: Integer);
392 ReadVar(x
, SizeOf(Integer));
395 Procedure TBinMemoryReader
.ReadSingle(Var x
: Single);
397 ReadVar(x
, SizeOf(Single));
400 Procedure TBinMemoryReader
.ReadBoolean(Var x
: Boolean);
405 ReadVar(y
, SizeOf(Byte));
413 Procedure TBinMemoryReader
.ReadString(Var x
: String);
418 if (FPosition
+ SizeOf(Byte)) <= FSize
then
422 Pointer(NativeUInt(FData
) + FPosition
),
425 if (FPosition
+ SizeOf(Byte) + len
) <= FSize
then
427 FPosition
:= FPosition
+ SizeOf(Byte);
433 Pointer(NativeUInt(FData
) + FPosition
),
435 FPosition
:= FPosition
+ len
;
441 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: Too Long String');
444 raise EBinSizeError
.Create('TBinMemoryReader.ReadString: End of Memory');
447 Procedure TBinMemoryReader
.ReadMemory(Var x
: Pointer; Var memSize
: Cardinal);
449 if (FPosition
+ SizeOf(Cardinal)) <= FSize
then
451 // Äëèíà áëîêà ïàìÿòè:
453 Pointer(NativeUInt(FData
) + FPosition
),
456 if (FPosition
+ SizeOf(Cardinal) + memSize
) <= FSize
then
458 FPosition
:= FPosition
+ SizeOf(Cardinal);
464 Pointer(NativeUInt(FData
) + FPosition
),
466 FPosition
:= FPosition
+ memSize
;
472 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: Too Long Memory');
475 raise EBinSizeError
.Create('TBinMemoryReader.ReadMemory: End of Memory');
478 Procedure TBinMemoryReader
.Skip(aLen
: Cardinal);
480 if (FPosition
+ aLen
) <= FSize
then
482 FPosition
:= FPosition
+ aLen
;
485 raise EBinSizeError
.Create('TBinMemoryReader.Skip: End of Memory');
488 Procedure TBinMemoryReader
.LoadFromFile(Var aFile
: File);
498 BlockRead(aFile
, aSize
, SizeOf(Cardinal), nr
);
499 if nr
<> SizeOf(Cardinal) then
501 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Length');
506 GetMem(FData
, FSize
);
509 BlockRead(aFile
, FData
^, FSize
, nr
);
512 raise EInOutError
.Create('TBinMemoryReader.LoadFromFile: Reading Data');
517 Procedure TBinMemoryReader
.LoadFromMemory(Var aMem
: TBinMemoryReader
);
524 aMem
.ReadMemory(FData
, FSize
);
529 { T B i n F i l e W r i t e r : }
531 Constructor TBinFileWriter
.Create();
536 Destructor TBinFileWriter
.Destroy();
543 Procedure TBinFileWriter
.OpenFile(Const aFileName
: String;
546 aOverWrite
: Boolean = True);
553 if (not FileExists(aFileName
)) or (aOverWrite
) then
555 AssignFile(FHandle
, aFileName
);
559 BlockWrite(FHandle
, aFileSig
, SizeOf(Cardinal), nw
);
560 if nw
<> SizeOf(Cardinal) then
562 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Signature');
567 BlockWrite(FHandle
, aFileVer
, SizeOf(Byte), nw
);
568 if nw
<> SizeOf(Byte) then
570 raise EInOutError
.Create('TBinFileWriter.OpenFile: Writing File Version');
580 Procedure TBinFileWriter
.Close();
584 System
.Close(FHandle
);
589 Procedure TBinFileWriter
.WriteMemory(Var aMemory
: TBinMemoryWriter
);
591 if (FOpened
) and (aMemory
<> nil) then
593 aMemory
.SaveToFile(FHandle
);
597 { T B i n F i l e R e a d e r : }
599 Constructor TBinFileReader
.Create();
604 Destructor TBinFileReader
.Destroy();
611 Function TBinFileReader
.OpenFile(Const aFileName
: String;
613 aFileVer
: Byte): Boolean;
624 if FileExists(aFileName
) then
626 AssignFile(FHandle
, aFileName
);
630 BlockRead(FHandle
, sig
, SizeOf(Cardinal), nr
);
631 if (nr
<> SizeOf(Cardinal)) then
633 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Signature');
636 if (sig
<> aFileSig
) then
638 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Signature');
643 BlockRead(FHandle
, ver
, SizeOf(Byte), nr
);
644 if (nr
<> SizeOf(Byte)) then
646 raise EInOutError
.Create('TBinFileReader.OpenFile: Reading File Version');
649 if (ver
<> aFileVer
) then
651 raise EInOutError
.Create('TBinFileReader.OpenFile: Wrong File Version');
662 Procedure TBinFileReader
.Close();
666 System
.Close(FHandle
);
671 Procedure TBinFileReader
.ReadMemory(Var aMemory
: TBinMemoryReader
);
673 if (FOpened
) and (aMemory
<> nil) then
675 aMemory
.LoadFromFile(FHandle
);