DEADSOFTWARE

put "{$MODE ...}" directive in each source file; removed trailing spaces, and convert...
[d2df-sdl.git] / src / shared / BinEditor.pas
1 {$MODE DELPHI}
2 Unit BinEditor;
4 Interface
6 Uses
7 SysUtils;
9 Type
10 EBinSizeError = Class (Exception);
12 TBinMemoryWriter = Class (TObject)
13 Private
14 FSize: Cardinal;
15 FData: Pointer;
16 FPosition: Cardinal;
18 Procedure WriteVar(Var x; varSize: Cardinal);
19 Procedure ExtendMemory(addLen: Cardinal);
21 Public
22 Constructor Create(aSize: Cardinal);
23 Destructor Destroy(); Override;
24 Procedure WriteByte(Var x: Byte);
25 Procedure WriteWord(Var x: Word);
26 Procedure WriteDWORD(Var x: DWORD);
27 Procedure WriteShortInt(Var x: ShortInt);
28 Procedure WriteSmallInt(Var x: SmallInt);
29 Procedure WriteInt(Var x: Integer);
30 Procedure WriteSingle(Var x: Single);
31 Procedure WriteBoolean(Var x: Boolean);
32 Procedure WriteString(Var x: String; aMaxLen: Byte = 255);
33 Procedure WriteMemory(Var x: Pointer; memSize: Cardinal);
34 Procedure Fill(aLen: Cardinal; aFillSym: Byte);
35 Procedure SaveToFile(Var aFile: File);
36 Procedure SaveToMemory(Var aMem: TBinMemoryWriter);
37 End;
39 TBinMemoryReader = Class (TObject)
40 Private
41 FSize: Cardinal;
42 FData: Pointer;
43 FPosition: Cardinal;
45 Procedure ReadVar(Var x; varSize: Cardinal);
47 Public
48 Constructor Create();
49 Destructor Destroy(); Override;
50 Procedure ReadByte(Var x: Byte);
51 Procedure ReadWord(Var x: Word);
52 Procedure ReadDWORD(Var x: DWORD);
53 Procedure ReadShortInt(Var x: ShortInt);
54 Procedure ReadSmallInt(Var x: SmallInt);
55 Procedure ReadInt(Var x: Integer);
56 Procedure ReadSingle(Var x: Single);
57 Procedure ReadBoolean(Var x: Boolean);
58 Procedure ReadString(Var x: String);
59 Procedure ReadMemory(Var x: Pointer; Var memSize: Cardinal);
60 Procedure Skip(aLen: Cardinal);
61 Procedure LoadFromFile(Var aFile: File);
62 Procedure LoadFromMemory(Var aMem: TBinMemoryReader);
63 End;
65 TBinFileWriter = Class (TObject)
66 Private
67 FHandle: File;
68 FOpened: Boolean;
70 Public
71 Constructor Create();
72 Destructor Destroy(); Override;
73 Procedure OpenFile(Const aFileName: String;
74 aFileSig: Cardinal;
75 aFileVer: Byte;
76 aOverWrite: Boolean = True);
77 Procedure Close();
78 Procedure WriteMemory(Var aMemory: TBinMemoryWriter);
79 End;
81 TBinFileReader = Class (TObject)
82 Private
83 FHandle: File;
84 FOpened: Boolean;
86 Public
87 Constructor Create();
88 Destructor Destroy(); Override;
89 Function OpenFile(Const aFileName: String;
90 aFileSig: Cardinal;
91 aFileVer: Byte): Boolean;
92 Procedure Close();
93 Procedure ReadMemory(Var aMemory: TBinMemoryReader);
94 End;
96 procedure FillMemory(Dest: Pointer; Len: Cardinal; Ch: Byte);
97 procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
98 procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
100 Implementation
102 Uses
103 Math, e_log;
105 Const
106 MAX_BIN_SIZE = 4 * 1024 * 1024; // 4 MB
108 procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
109 begin
110 Move(Src^, Dest^, Len);
111 end;
113 procedure FillMemory(Dest: Pointer; Len: Cardinal; Ch: Byte);
114 begin
115 FillChar(Dest^, Len, Ch);
116 end;
118 procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
119 begin
120 FillChar(Dest^, Len, 0);
121 end;
123 { T B i n M e m o r y W r i t e r : }
125 Constructor TBinMemoryWriter.Create(aSize: Cardinal);
126 begin
127 if aSize <= 0 then
128 FSize := 1
129 else
130 FSize := aSize;
131 if FSize > MAX_BIN_SIZE then
132 FSize := MAX_BIN_SIZE;
134 GetMem(FData, FSize);
135 FPosition := 0;
136 end;
138 Destructor TBinMemoryWriter.Destroy();
139 begin
140 if FData <> nil then
141 begin
142 FreeMem(FData);
143 FData := nil;
144 end;
146 Inherited;
147 end;
149 Procedure TBinMemoryWriter.WriteVar(Var x; varSize: Cardinal);
150 begin
151 if (FPosition + varSize) > FSize then
152 ExtendMemory(varSize);
154 CopyMemory(Pointer(Cardinal(FData) + FPosition),
155 @x, varSize);
156 FPosition := FPosition + varSize;
157 end;
159 Procedure TBinMemoryWriter.ExtendMemory(addLen: Cardinal);
160 var
161 tmp: Pointer;
163 begin
164 while ((FPosition + addLen) > FSize) and
165 (FSize <= MAX_BIN_SIZE) do
166 FSize := FSize * 2;
168 if FSize > MAX_BIN_SIZE then
169 begin
170 raise EBinSizeError.Create('TBinMemoryWriter.ExtendMemory: Tried to allocete more than 4 MB');
171 Exit;
172 end;
174 GetMem(tmp, FSize);
176 if FPosition > 0 then
177 CopyMemory(tmp, FData, FPosition);
179 FreeMem(FData);
180 FData := tmp;
182 e_WriteLog('Save Memory Extended: '+IntToStr(FSize), MSG_NOTIFY);
183 end;
185 Procedure TBinMemoryWriter.WriteByte(Var x: Byte);
186 begin
187 WriteVar(x, SizeOf(Byte));
188 end;
190 Procedure TBinMemoryWriter.WriteWord(Var x: Word);
191 begin
192 WriteVar(x, SizeOf(Word));
193 end;
195 Procedure TBinMemoryWriter.WriteDWORD(Var x: DWORD);
196 begin
197 WriteVar(x, SizeOf(DWORD));
198 end;
200 Procedure TBinMemoryWriter.WriteShortInt(Var x: ShortInt);
201 begin
202 WriteVar(x, SizeOf(ShortInt));
203 end;
205 Procedure TBinMemoryWriter.WriteSmallInt(Var x: SmallInt);
206 begin
207 WriteVar(x, SizeOf(SmallInt));
208 end;
210 Procedure TBinMemoryWriter.WriteInt(Var x: Integer);
211 begin
212 WriteVar(x, SizeOf(Integer));
213 end;
215 Procedure TBinMemoryWriter.WriteSingle(Var x: Single);
216 begin
217 WriteVar(x, SizeOf(Single));
218 end;
220 Procedure TBinMemoryWriter.WriteBoolean(Var x: Boolean);
221 var
222 y: Byte;
224 begin
225 if x then
226 y := 1
227 else
228 y := 0;
230 WriteVar(y, SizeOf(Byte));
231 end;
233 Procedure TBinMemoryWriter.WriteString(Var x: String; aMaxLen: Byte = 255);
234 var
235 len: Byte;
237 begin
238 len := Min(Length(x), aMaxLen);
240 if (FPosition + SizeOf(Byte) + len) > FSize then
241 ExtendMemory(SizeOf(Byte) + len);
243 // Äëèíà ñòðîêè:
244 CopyMemory(Pointer(Cardinal(FData) + FPosition),
245 @len, SizeOf(Byte));
246 FPosition := FPosition + SizeOf(Byte);
247 // Ñòðîêà:
248 if len > 0 then
249 begin
250 CopyMemory(Pointer(Cardinal(FData) + FPosition),
251 @x[1], len);
252 FPosition := FPosition + len;
253 end;
254 end;
256 Procedure TBinMemoryWriter.WriteMemory(Var x: Pointer; memSize: Cardinal);
257 begin
258 if (FPosition + SizeOf(Cardinal) + memSize) > FSize then
259 ExtendMemory(SizeOf(Cardinal) + memSize);
261 // Äëèíà áëîêà ïàìÿòè:
262 CopyMemory(Pointer(Cardinal(FData) + FPosition),
263 @memSize, SizeOf(Cardinal));
264 FPosition := FPosition + SizeOf(Cardinal);
265 // Áëîê ïàìÿòè:
266 if memSize > 0 then
267 begin
268 CopyMemory(Pointer(Cardinal(FData) + FPosition),
269 x, memSize);
270 FPosition := FPosition + memSize;
271 end;
272 end;
274 Procedure TBinMemoryWriter.Fill(aLen: Cardinal; aFillSym: Byte);
275 begin
276 if (FPosition + aLen) > FSize then
277 ExtendMemory(aLen);
279 if aLen > 0 then
280 begin
281 FillMemory(Pointer(Cardinal(FData) + FPosition),
282 aLen, aFillSym);
283 FPosition := FPosition + aLen;
284 end;
285 end;
287 Procedure TBinMemoryWriter.SaveToFile(Var aFile: File);
288 var
289 nw: Cardinal;
291 begin
292 // Ðàçìåð áëîêà:
293 BlockWrite(aFile, FPosition, SizeOf(Cardinal), nw);
294 if nw <> SizeOf(Cardinal) then
295 begin
296 raise EInOutError.Create('TBinMemoryWriter.SaveToFile: Writing Length');
297 end
298 else
299 begin
300 // Äàííûå áëîêà:
301 BlockWrite(aFile, FData^, FPosition, nw);
302 if nw <> FPosition then
303 begin
304 raise EInOutError.Create('TBinMemoryWriter.SaveToFile: Writing Data');
305 end
306 end;
307 end;
309 Procedure TBinMemoryWriter.SaveToMemory(Var aMem: TBinMemoryWriter);
310 begin
311 if aMem <> nil then
312 begin
313 aMem.WriteMemory(FData, FPosition);
314 end;
315 end;
317 { T B i n M e m o r y R e a d e r : }
319 Constructor TBinMemoryReader.Create();
320 begin
321 FSize := 0;
322 FData := nil;
323 FPosition := 1;
324 end;
326 Destructor TBinMemoryReader.Destroy();
327 begin
328 if FData <> nil then
329 begin
330 FreeMem(FData);
331 FData := nil;
332 end;
334 Inherited;
335 end;
337 Procedure TBinMemoryReader.ReadVar(Var x; varSize: Cardinal);
338 begin
339 if (FPosition + varSize) <= FSize then
340 begin
341 CopyMemory(@x,
342 Pointer(Cardinal(FData) + FPosition),
343 varSize);
344 FPosition := FPosition + varSize;
345 end
346 else
347 raise EBinSizeError.Create('TBinMemoryReader.ReadVar: End of Memory');
348 end;
350 Procedure TBinMemoryReader.ReadByte(Var x: Byte);
351 begin
352 ReadVar(x, SizeOf(Byte));
353 end;
355 Procedure TBinMemoryReader.ReadWord(Var x: Word);
356 begin
357 ReadVar(x, SizeOf(Word));
358 end;
360 Procedure TBinMemoryReader.ReadDWORD(Var x: DWORD);
361 begin
362 ReadVar(x, SizeOf(DWORD));
363 end;
365 Procedure TBinMemoryReader.ReadShortInt(Var x: ShortInt);
366 begin
367 ReadVar(x, SizeOf(ShortInt));
368 end;
370 Procedure TBinMemoryReader.ReadSmallInt(Var x: SmallInt);
371 begin
372 ReadVar(x, SizeOf(SmallInt));
373 end;
375 Procedure TBinMemoryReader.ReadInt(Var x: Integer);
376 begin
377 ReadVar(x, SizeOf(Integer));
378 end;
380 Procedure TBinMemoryReader.ReadSingle(Var x: Single);
381 begin
382 ReadVar(x, SizeOf(Single));
383 end;
385 Procedure TBinMemoryReader.ReadBoolean(Var x: Boolean);
386 var
387 y: Byte;
389 begin
390 ReadVar(y, SizeOf(Byte));
392 if y > 0 then
393 x := True
394 else
395 x := False;
396 end;
398 Procedure TBinMemoryReader.ReadString(Var x: String);
399 var
400 len: Byte;
402 begin
403 if (FPosition + SizeOf(Byte)) <= FSize then
404 begin
405 // Äëèíà ñòðîêè:
406 CopyMemory(@len,
407 Pointer(Cardinal(FData) + FPosition),
408 SizeOf(Byte));
410 if (FPosition + SizeOf(Byte) + len) <= FSize then
411 begin
412 FPosition := FPosition + SizeOf(Byte);
413 // Ñòðîêà:
414 SetLength(x, len);
415 if len > 0 then
416 begin
417 CopyMemory(@x[1],
418 Pointer(Cardinal(FData) + FPosition),
419 len);
420 FPosition := FPosition + len;
421 end
422 else
423 x := '';
424 end
425 else
426 raise EBinSizeError.Create('TBinMemoryReader.ReadString: Too Long String');
427 end
428 else
429 raise EBinSizeError.Create('TBinMemoryReader.ReadString: End of Memory');
430 end;
432 Procedure TBinMemoryReader.ReadMemory(Var x: Pointer; Var memSize: Cardinal);
433 begin
434 if (FPosition + SizeOf(Cardinal)) <= FSize then
435 begin
436 // Äëèíà áëîêà ïàìÿòè:
437 CopyMemory(@memSize,
438 Pointer(Cardinal(FData) + FPosition),
439 SizeOf(Cardinal));
441 if (FPosition + SizeOf(Cardinal) + memSize) <= FSize then
442 begin
443 FPosition := FPosition + SizeOf(Cardinal);
444 // Áëîê ïàìÿòè:
445 if memSize > 0 then
446 begin
447 GetMem(x, memSize);
448 CopyMemory(x,
449 Pointer(Cardinal(FData) + FPosition),
450 memSize);
451 FPosition := FPosition + memSize;
452 end
453 else
454 x := nil;
455 end
456 else
457 raise EBinSizeError.Create('TBinMemoryReader.ReadMemory: Too Long Memory');
458 end
459 else
460 raise EBinSizeError.Create('TBinMemoryReader.ReadMemory: End of Memory');
461 end;
463 Procedure TBinMemoryReader.Skip(aLen: Cardinal);
464 begin
465 if (FPosition + aLen) <= FSize then
466 begin
467 FPosition := FPosition + aLen;
468 end
469 else
470 raise EBinSizeError.Create('TBinMemoryReader.Skip: End of Memory');
471 end;
473 Procedure TBinMemoryReader.LoadFromFile(Var aFile: File);
474 var
475 nr: Cardinal;
476 aSize: Cardinal;
478 begin
479 if FData <> nil then
480 FreeMem(FData);
482 // Ðàçìåð áëîêà:
483 BlockRead(aFile, aSize, SizeOf(Cardinal), nr);
484 if nr <> SizeOf(Cardinal) then
485 begin
486 raise EInOutError.Create('TBinMemoryReader.LoadFromFile: Reading Length');
487 end
488 else
489 begin
490 FSize := aSize;
491 GetMem(FData, FSize);
492 FPosition := 0;
493 // Äàííûå áëîêà:
494 BlockRead(aFile, FData^, FSize, nr);
495 if nr <> FSize then
496 begin
497 raise EInOutError.Create('TBinMemoryReader.LoadFromFile: Reading Data');
498 end
499 end;
500 end;
502 Procedure TBinMemoryReader.LoadFromMemory(Var aMem: TBinMemoryReader);
503 begin
504 if FData <> nil then
505 FreeMem(FData);
507 if aMem <> nil then
508 begin
509 aMem.ReadMemory(FData, FSize);
510 FPosition := 0;
511 end;
512 end;
514 { T B i n F i l e W r i t e r : }
516 Constructor TBinFileWriter.Create();
517 begin
518 FOpened := False;
519 end;
521 Destructor TBinFileWriter.Destroy();
522 begin
523 Close();
525 Inherited;
526 end;
528 Procedure TBinFileWriter.OpenFile(Const aFileName: String;
529 aFileSig: Cardinal;
530 aFileVer: Byte;
531 aOverWrite: Boolean = True);
532 var
533 nw: Integer;
535 begin
536 Close();
538 if (not FileExists(aFileName)) or (aOverWrite) then
539 begin
540 AssignFile(FHandle, aFileName);
541 ReWrite(FHandle, 1);
543 // Ñèãíàòóðà:
544 BlockWrite(FHandle, aFileSig, SizeOf(Cardinal), nw);
545 if nw <> SizeOf(Cardinal) then
546 begin
547 raise EInOutError.Create('TBinFileWriter.OpenFile: Writing File Signature');
548 end
549 else
550 begin
551 // Âåðñèÿ:
552 BlockWrite(FHandle, aFileVer, SizeOf(Byte), nw);
553 if nw <> SizeOf(Byte) then
554 begin
555 raise EInOutError.Create('TBinFileWriter.OpenFile: Writing File Version');
556 end
557 else
558 begin
559 FOpened := True;
560 end;
561 end;
562 end;
563 end;
565 Procedure TBinFileWriter.Close();
566 begin
567 if FOpened then
568 begin
569 System.Close(FHandle);
570 FOpened := False;
571 end;
572 end;
574 Procedure TBinFileWriter.WriteMemory(Var aMemory: TBinMemoryWriter);
575 begin
576 if (FOpened) and (aMemory <> nil) then
577 begin
578 aMemory.SaveToFile(FHandle);
579 end;
580 end;
582 { T B i n F i l e R e a d e r : }
584 Constructor TBinFileReader.Create();
585 begin
586 FOpened := False;
587 end;
589 Destructor TBinFileReader.Destroy();
590 begin
591 Close();
593 Inherited;
594 end;
596 Function TBinFileReader.OpenFile(Const aFileName: String;
597 aFileSig: Cardinal;
598 aFileVer: Byte): Boolean;
599 var
600 nr: Integer;
601 sig: Cardinal;
602 ver: Byte;
604 begin
605 Result := False;
607 Close();
609 if FileExists(aFileName) then
610 begin
611 AssignFile(FHandle, aFileName);
612 ReSet(FHandle, 1);
614 // Ñèãíàòóðà:
615 BlockRead(FHandle, sig, SizeOf(Cardinal), nr);
616 if (nr <> SizeOf(Cardinal)) then
617 begin
618 raise EInOutError.Create('TBinFileReader.OpenFile: Reading File Signature');
619 end
620 else
621 if (sig <> aFileSig) then
622 begin
623 raise EInOutError.Create('TBinFileReader.OpenFile: Wrong File Signature');
624 end
625 else
626 begin
627 // Âåðñèÿ:
628 BlockRead(FHandle, ver, SizeOf(Byte), nr);
629 if (nr <> SizeOf(Byte)) then
630 begin
631 raise EInOutError.Create('TBinFileReader.OpenFile: Reading File Version');
632 end
633 else
634 if (ver <> aFileVer) then
635 begin
636 raise EInOutError.Create('TBinFileReader.OpenFile: Wrong File Version');
637 end
638 else
639 begin
640 FOpened := True;
641 Result := True;
642 end;
643 end;
644 end;
645 end;
647 Procedure TBinFileReader.Close();
648 begin
649 if FOpened then
650 begin
651 System.Close(FHandle);
652 FOpened := False;
653 end;
654 end;
656 Procedure TBinFileReader.ReadMemory(Var aMemory: TBinMemoryReader);
657 begin
658 if (FOpened) and (aMemory <> nil) then
659 begin
660 aMemory.LoadFromFile(FHandle);
661 end;
662 end;
665 End.