source: oup/current/FileClasses/_DataTypes.pas@ 239

Last change on this file since 239 was 237, checked in by alloc, 17 years ago
File size: 20.0 KB
Line 
1unit _DataTypes;
2
3interface
4
5uses
6 Classes, _TreeElement;
7
8type
9 TContainer = class;
10
11 TDataField = class(TTreeElement)
12 function GetChildCount: Integer; override;
13 function GetChild(ID: Integer): TTreeElement; override;
14 function GetCaption: String; override;
15 protected
16 FOffset: Integer;
17 FName: String;
18 FDescription: String;
19 FDataLength: Integer;
20 FParentFile: TObject;
21 FParentBlock: TContainer;
22 FChanged: Boolean;
23 FExtraArgs: array of TVarRec;
24 function GetValueAsString: String; virtual;
25 public
26 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
27 Name, Description: String; ExtraArgs: array of const); virtual;
28
29 procedure Update(Offset, Length: Integer); virtual; abstract;
30
31 property Offset: Integer read FOffset;
32 property Name: String read FName;
33 property Description: String read FDescription;
34 property DataLength: Integer read FDataLength;
35 property ValueAsString: String read GetValueAsString;
36 end;
37
38 TFieldType = class of TDataField;
39
40 TContainer = class(TDataField)
41 public
42 function AddField(fieldtype: TFieldType; Name, Description: String;
43 ExtraArgs: array of const): TDataField; virtual; abstract;
44 procedure UpdateSize; virtual; abstract;
45 end;
46
47 TBlock = class(TContainer)
48 private
49 FDataFields: array of TDataField;
50 function GetChildCount: Integer; override;
51 function GetChild(ID: Integer): TTreeElement; override;
52 function GetFieldByOffset(Offset: Integer): TDataField;
53 public
54 // ExtraArgs: Pointer auf Integer: BlockLength <- no longer
55 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
56 Name, Description: String; ExtraArgs: array of const); override;
57 procedure Update(Offset, Length: Integer); override;
58 property FieldByOffset[Offset: Integer]: TDataField read GetFieldByOffset;
59
60 function AddField(fieldtype: TFieldType; Name, Description: String;
61 ExtraArgs: array of const): TDataField; override;
62 procedure UpdateSize; override;
63 end;
64
65
66 TInt = class(TDataField)
67 private
68 FInt: Integer;
69 function GetValueAsString: String; override;
70 public
71 // ExtraArgs: Pointer auf Integer: Bytes of TInt
72 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
73 Name, Description: String; ExtraArgs: array of const); override;
74 procedure Update(Offset, Length: Integer); override;
75 end;
76
77
78 TFloat = class(TDataField)
79 private
80 FFloat: Single;
81 function GetValueAsString: String; override;
82 public
83 // ExtraArgs: none
84 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
85 Name, Description: String; ExtraArgs: array of const); override;
86 procedure Update(Offset, Length: Integer); override;
87 end;
88
89
90 TBitSet = class(TDataField)
91 private
92 FBits: Byte;
93 FNames: TStringList;
94 function GetValueAsString: String; override;
95 public
96 // ExtraArgs: Pointer auf TStringList
97 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
98 Name, Description: String; ExtraArgs: array of const); override;
99 procedure Update(Offset, Length: Integer); override;
100 end;
101
102
103 TLevelID = class(TDataField)
104 private
105 FLevelID: Integer;
106 function GetValueAsString: String; override;
107 public
108 // ExtraArgs: keine
109 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
110 Name, Description: String; ExtraArgs: array of const); override;
111 procedure Update(Offset, Length: Integer); override;
112 end;
113
114
115 TFileID = class(TDataField)
116 private
117 FFileID: Integer;
118 function GetValueAsString: String; override;
119 public
120 // ExtraArgs: keine
121 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
122 Name, Description: String; ExtraArgs: array of const); override;
123 procedure Update(Offset, Length: Integer); override;
124 end;
125
126
127 TLinkByID = class(TDataField)
128 function GetChildCount: Integer; override;
129 function GetChild(ID: Integer): TTreeElement; override;
130 private
131 FFileID: Integer;
132 FPosExts: String;
133 function GetValueAsString: String; override;
134 public
135 // ExtraArgs: Pointer auf String: Possible Exts
136 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
137 Name, Description: String; ExtraArgs: array of const); override;
138 procedure Update(Offset, Length: Integer); override;
139 end;
140
141
142 TString = class(TDataField)
143 private
144 FString: String;
145 function GetValueAsString: String; override;
146 public
147 // ExtraArgs: Pointer auf Integer: Length
148 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
149 Name, Description: String; ExtraArgs: array of const); override;
150 procedure Update(Offset, Length: Integer); override;
151 end;
152
153
154 TArray = class(TContainer)
155 private
156 FDataFields: array of TBlock;
157 FTemplate: TBlock;
158 FCounterSize: Integer;
159 FBlockCount: Integer;
160 function GetChildCount: Integer; override;
161 function GetChild(ID: Integer): TTreeElement; override;
162 function GetFieldByOffset(Offset: Integer): TDataField;
163 public
164 // ExtraArgs:
165 // 1. Integer: CounterSize (if 0 then 2. integer is required)
166 // 2. Integer: BlockCount (for fixed-size arrays)
167 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
168 Name, Description: String; ExtraArgs: array of const); override;
169 procedure Update(Offset, Length: Integer); override;
170
171 function AddField(fieldtype: TFieldType; Name, Description: String;
172 ExtraArgs: array of const): TDataField; override;
173 procedure SetCount; overload;
174 procedure SetCount(n: Integer); overload;
175 procedure UpdateSize; override;
176 end;
177
178
179 TRawLink = class(TDataField)
180 private
181 FRawAddress: Integer;
182 function GetValueAsString: String; override;
183 public
184 // ExtraArgs: keine
185 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
186 Name, Description: String; ExtraArgs: array of const); override;
187 procedure Update(Offset, Length: Integer); override;
188 end;
189
190
191 TUnused = class(TDataField)
192 private
193 function GetValueAsString: String; override;
194 public
195 // ExtraArgs: Pointer auf Integer: Length
196 constructor Create(ParentFile: TObject; ParentBlock: TContainer;
197 Name, Description: String; ExtraArgs: array of const); override;
198 procedure Update(Offset, Length: Integer); override;
199 end;
200
201
202
203
204implementation
205
206uses
207 SysUtils, Dialogs, _FileTypes, ConnectionManager, StrUtils;
208
209
210
211
212{ TDataType }
213
214constructor TDataField.Create(ParentFile: TObject; ParentBlock: TContainer;
215 Name, Description: String; ExtraArgs: array of const);
216var
217 i: Integer;
218begin
219 if Assigned(ParentBlock) then
220 FOffset := ParentBlock.Offset + ParentBlock.DataLength
221 else
222 FOffset := 0;
223 FName := Name;
224 FDescription := Description;
225 FParentFile := ParentFile;
226 FParentBlock := ParentBlock;
227 SetLength(FExtraArgs, Length(ExtraArgs));
228 if Length(ExtraArgs) > 0 then
229 for i := 0 to High(ExtraArgs) do
230 FExtraArgs[i] := ExtraArgs[i];
231 FConnectionID := TFile(ParentFile).ConnectionID;
232end;
233
234function TDataField.GetCaption: String;
235begin
236 Result := FName;
237end;
238
239function TDataField.GetChild(ID: Integer): TTreeElement;
240begin
241 Result := nil;
242end;
243
244function TDataField.GetChildCount: Integer;
245begin
246 Result := 0;
247end;
248
249function TDataField.GetValueAsString: String;
250begin
251 Result := '';
252end;
253
254{ TString }
255
256constructor TString.Create(ParentFile: TObject; ParentBlock: TContainer;
257 Name, Description: String; ExtraArgs: array of const);
258begin
259 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
260 FDataLength := ExtraArgs[0].VInteger;
261end;
262
263function TString.GetValueAsString: String;
264begin
265 Result := FString;
266end;
267
268procedure TString.Update(Offset, Length: Integer);
269var
270 fstream: TMemoryStream;
271 i: Integer;
272begin
273 fstream := TFile(FParentFile).FileStream;
274 fstream.Seek(FOffset, soFromBeginning);
275 SetLength(FString, FDataLength);
276 fstream.Read(FString[1], FDataLength);
277 for i := 1 to FDataLength do
278 if FString[i] = Chr(0) then
279 begin
280 SetLength(FString, i - 1);
281 Break;
282 end;
283end;
284
285
286
287{ TInt }
288
289constructor TInt.Create(ParentFile: TObject; ParentBlock: TContainer;
290 Name, Description: String; ExtraArgs: array of const);
291begin
292 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
293 FDataLength := ExtraArgs[0].VInteger;
294 FInt := 0;
295end;
296
297function TInt.GetValueAsString: String;
298begin
299 Result := IntToStr(FInt);
300end;
301
302procedure TInt.Update(Offset, Length: Integer);
303var
304 fstream: TMemoryStream;
305begin
306 fstream := TFile(FParentFile).FileStream;
307 fstream.Seek(FOffset, soFromBeginning);
308 fstream.Read(FInt, FDataLength);
309end;
310
311
312
313{ TArray }
314
315function TArray.AddField(fieldtype: TFieldType;
316 Name, Description: String; ExtraArgs: array of const): TDataField;
317var
318 i: Integer;
319begin
320 Result := FTemplate.AddField(fieldtype, Name, Description, ExtraArgs);
321end;
322
323constructor TArray.Create(ParentFile: TObject; ParentBlock: TContainer;
324 Name, Description: String; ExtraArgs: array of const);
325begin
326 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
327 FCounterSize := ExtraArgs[0].VInteger;
328 if Length(ExtraArgs) = 2 then
329 FBlockCount := ExtraArgs[1].VInteger
330 else
331 FBlockCount := 0;
332 FTemplate := TBlock.Create(ParentFile, Self, '', '', []);
333end;
334
335function TArray.GetChildCount: Integer;
336begin
337 Result := Length(FDataFields);
338end;
339
340function TArray.GetChild(ID: Integer): TTreeElement;
341begin
342 Result := FDataFields[ID];
343end;
344
345function TArray.GetFieldByOffset(Offset: Integer): TDataField;
346begin
347 Exit;
348end;
349
350procedure TArray.SetCount;
351var
352 fstream: TMemoryStream;
353 arr_index: Integer;
354 i: Integer;
355
356 procedure Add(DestBlock, SrcBlock: TBlock);
357 var
358 fid: Integer;
359 field: TDataField;
360 result: TDataField;
361 begin
362 if Length(SrcBlock.FDataFields) > 0 then
363 begin
364 for fid := 0 to High(SrcBlock.FDataFields) do
365 begin
366 field := SrcBlock.FDataFields[fid];
367 result := DestBlock.AddField(TFieldType(field.ClassType), field.Name, field.Description, field.FExtraArgs);
368 if result is TBlock then
369 Add(TBlock(result), TBlock(field));
370 end;
371 end;
372 end;
373
374begin
375 if FCounterSize > 0 then
376 begin
377 fstream := TFile(FParentFile).FileStream;
378 fstream.Seek(Offset, soFromBeginning);
379 FBlockCount := 0;
380 fstream.Read(FBlockCount, FCounterSize);
381 end;
382 FDataLength := FCounterSize;
383 if FBlockCount > 0 then
384 begin
385 for arr_index := 0 to FBlockCount - 1 do
386 begin
387 SetLength(FDataFields, arr_index + 1);
388 FDataFields[arr_index] := TBlock.Create(FParentFile, Self,
389 '[' + IntToStr(arr_index) + ']', '', []);
390 Add(FDataFields[arr_index], FTemplate);
391 end;
392 end;
393 if Pos('[', FName) > 0 then
394 begin
395 if Pos(']', FName) = Length(FName) then
396 begin
397 i := Pos('[', ReverseString(FName));
398 FName := MidStr(FName, 1, Length(FName) - i);
399 end;
400 end;
401 FName := FName + '[' + IntToStr(FBlockCount) + ']';
402 FParentBlock.UpdateSize;
403end;
404
405procedure TArray.SetCount(n: Integer);
406var
407 fstream: TMemoryStream;
408begin
409 FBlockCount := n;
410 if FCounterSize > 0 then
411 begin
412 fstream := TFile(FParentFile).FileStream;
413 fstream.Seek(Offset, soFromBeginning);
414 fstream.Write(FBlockCount, FCounterSize);
415 end;
416 SetCount;
417end;
418
419procedure TArray.Update(Offset, Length: Integer);
420var
421 i: Integer;
422 field: TDataField;
423begin
424 if System.Length(FDataFields) > 0 then
425 begin
426 if Length > 0 then
427 begin
428 for i := 0 to High(FDataFields) do
429 begin
430 field := FDataFields[i];
431 if ((field.Offset < Offset) and (field.Offset + field.DataLength > Offset + Length)) or
432 ((field.Offset > Offset) and (field.Offset < Offset + Length)) or
433 ((field.Offset + field.DataLength > Offset) and (field.Offset+field.DataLength < Offset + Length)) then
434 field.Update(Offset, Length);
435 end;
436 end else begin
437 for i := 0 to High(FDataFields) do
438 begin
439 FDataFields[i].Update(Offset, Length);
440 end;
441 end;
442 end;
443end;
444
445procedure TArray.UpdateSize;
446var
447 i: Integer;
448begin
449 FDataLength := FCounterSize;
450 if Length(FDataFields) > 0 then
451 for i := 0 to High(FDataFields) do
452 FDataLength := FDataLength + FDataFields[i].DataLength;
453 FParentBlock.UpdateSize;
454end;
455
456
457
458{ TBlock }
459
460function TBlock.AddField(fieldtype: TFieldType; Name,
461 Description: String; ExtraArgs: array of const): TDataField;
462begin
463 SetLength(FDataFields, Length(FDataFields) + 1);
464 FDataFields[High(FDataFields)] := TFieldType(fieldtype).Create(
465 FParentFile, Self, Name, Description, ExtraArgs);
466 Result := FDataFields[High(FDataFields)];
467 FDataLength := FDataLength + Result.DataLength;
468 if Assigned(FParentBlock) then
469 FParentBlock.UpdateSize;
470end;
471
472constructor TBlock.Create(ParentFile: TObject; ParentBlock: TContainer;
473 Name, Description: String; ExtraArgs: array of const);
474begin
475 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
476end;
477
478function TBlock.GetChild(ID: Integer): TTreeElement;
479begin
480 Result := FDataFields[ID];
481end;
482
483function TBlock.GetChildCount: Integer;
484begin
485 Result := Length(FDataFields);
486end;
487
488function TBlock.GetFieldByOffset(Offset: Integer): TDataField;
489begin
490 Exit;
491end;
492
493procedure TBlock.Update(Offset, Length: Integer);
494var
495 i: Integer;
496 field: TDataField;
497begin
498 if System.Length(FDataFields) > 0 then
499 begin
500 if Length > 0 then
501 begin
502 for i := 0 to High(FDataFields) do
503 begin
504 field := FDataFields[i];
505 if ((field.Offset < Offset) and (field.Offset + field.DataLength > Offset + Length)) or
506 ((field.Offset > Offset) and (field.Offset < Offset + Length)) or
507 ((field.Offset + field.DataLength > Offset) and (field.Offset+field.DataLength < Offset + Length)) then
508 field.Update(Offset, Length);
509 end;
510 end else begin
511 for i := 0 to High(FDataFields) do
512 begin
513 FDataFields[i].Update(Offset, Length);
514 end;
515 end;
516 end;
517end;
518
519procedure TBlock.UpdateSize;
520var
521 i: Integer;
522begin
523 FDataLength := 0;
524 if Length(FDataFields) > 0 then
525 for i := 0 to High(FDataFields) do
526 FDataLength := FDataLength + FDataFields[i].FDataLength;
527 if Assigned(FParentBlock) then
528 FParentBlock.UpdateSize;
529end;
530
531
532
533{ TLevelID }
534
535constructor TLevelID.Create(ParentFile: TObject; ParentBlock: TContainer;
536 Name, Description: String; ExtraArgs: array of const);
537begin
538 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
539 FDataLength := 4;
540 FLevelID := 0;
541end;
542
543function TLevelID.GetValueAsString: String;
544begin
545 Result := IntToStr(FLevelID);
546end;
547
548procedure TLevelID.Update(Offset, Length: Integer);
549var
550 fstream: TMemoryStream;
551begin
552 fstream := TFile(FParentFile).FileStream;
553 fstream.Seek(FOffset, soFromBeginning);
554 fstream.Read(FLevelID, 4);
555 FLevelID := FLevelID div 256 div 256 div 256 div 2;
556end;
557
558
559
560{ TFileID }
561
562constructor TFileID.Create(ParentFile: TObject; ParentBlock: TContainer;
563 Name, Description: String; ExtraArgs: array of const);
564begin
565 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
566 FDataLength := 4;
567 FFileID := -1;
568end;
569
570function TFileID.GetValueAsString: String;
571begin
572 Result := IntToStr(FFileID);
573end;
574
575procedure TFileID.Update(Offset, Length: Integer);
576var
577 fstream: TMemoryStream;
578begin
579 fstream := TFile(FParentFile).FileStream;
580 fstream.Seek(FOffset, soFromBeginning);
581 fstream.Read(FFileID, 4);
582 if FFileID > 0 then
583 FFileID := FFileID div 256
584 else
585 FFileID := -1;
586end;
587
588
589
590{ TLinkByID }
591
592constructor TLinkByID.Create(ParentFile: TObject; ParentBlock: TContainer;
593 Name, Description: String; ExtraArgs: array of const);
594begin
595 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
596 FDataLength := 4;
597 case ExtraArgs[0].VType of
598 vtChar: FPosExts := ExtraArgs[0].VChar;
599 vtAnsiString: FPosExts := String(ExtraArgs[0].VAnsiString);
600 end;
601 FFileID := -1;
602end;
603
604function TLinkByID.GetChild(ID: Integer): TTreeElement;
605begin
606 if FFileID > 0 then
607 Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].Child[ID]
608 else
609 Result := nil;
610end;
611
612function TLinkByID.GetChildCount: Integer;
613begin
614 if FFileID > 0 then
615 Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].ChildCount
616 else
617 Result := 0;
618end;
619
620function TLinkByID.GetValueAsString: String;
621begin
622 if FFileID >= 0 then
623 Result := IntToStr(FFileID)
624 else
625 Result := 'unused';
626end;
627
628procedure TLinkByID.Update(Offset, Length: Integer);
629var
630 fstream: TMemoryStream;
631begin
632 fstream := TFile(FParentFile).FileStream;
633 fstream.Seek(FOffset, soFromBeginning);
634 fstream.Read(FFileID, 4);
635 if FFileID > 0 then
636 FFileID := FFileID div 256
637 else
638 FFileID := -1;
639end;
640
641
642
643{ TRawLink }
644
645constructor TRawLink.Create(ParentFile: TObject; ParentBlock: TContainer;
646 Name, Description: String; ExtraArgs: array of const);
647begin
648 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
649 FDataLength := 4;
650end;
651
652function TRawLink.GetValueAsString: String;
653begin
654 if FRawAddress > 0 then
655 Result := '0x' + IntToHex(FRawAddress, 8)
656 else
657 Result := 'unused';
658end;
659
660procedure TRawLink.Update(Offset, Length: Integer);
661var
662 fstream: TMemoryStream;
663begin
664 fstream := TFile(FParentFile).FileStream;
665 fstream.Seek(FOffset, soFromBeginning);
666 fstream.Read(FRawAddress, 4);
667end;
668
669
670
671{ TUnused }
672
673constructor TUnused.Create(ParentFile: TObject; ParentBlock: TContainer;
674 Name, Description: String; ExtraArgs: array of const);
675begin
676 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
677 FDataLength := ExtraArgs[0].VInteger;
678end;
679
680function TUnused.GetValueAsString: String;
681begin
682 Result := '';
683end;
684
685procedure TUnused.Update(Offset, Length: Integer);
686begin
687 Exit;
688end;
689
690
691
692{ TBitSet }
693
694constructor TBitSet.Create(ParentFile: TObject; ParentBlock: TContainer;
695 Name, Description: String; ExtraArgs: array of const);
696var
697 i: Integer;
698begin
699 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
700 FNames := TStringList.Create;
701 for i := 0 to High(ExtraArgs) do
702 case ExtraArgs[i].VType of
703 vtChar: FNames.Add(ExtraArgs[0].VChar);
704 vtAnsiString: FNames.Add(String(ExtraArgs[0].VAnsiString));
705 end;
706 FDataLength := 1;
707 FBits := 0;
708end;
709
710function TBitSet.GetValueAsString: String;
711 function IntToBits(Int: Integer): String;
712 var
713 i: Integer;
714 begin
715 Result := '';
716 for i := 0 to 7 do
717 begin
718 Result := IntToStr(FBits and (1 shl i) shr i) + Result;
719 end;
720 end;
721begin
722 Result := IntToBits(FBits);
723end;
724
725procedure TBitSet.Update(Offset, Length: Integer);
726var
727 fstream: TMemoryStream;
728begin
729 fstream := TFile(FParentFile).FileStream;
730 fstream.Seek(FOffset, soFromBeginning);
731 fstream.Read(FBits, FDataLength);
732end;
733
734
735
736{ TFloat }
737
738constructor TFloat.Create(ParentFile: TObject; ParentBlock: TContainer; Name,
739 Description: String; ExtraArgs: array of const);
740begin
741 inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
742 FDataLength := 4;
743 FFloat := 0;
744end;
745
746function TFloat.GetValueAsString: String;
747begin
748 Result := FloatToStr(FFloat);
749end;
750
751procedure TFloat.Update(Offset, Length: Integer);
752var
753 fstream: TMemoryStream;
754begin
755 fstream := TFile(FParentFile).FileStream;
756 fstream.Seek(FOffset, soFromBeginning);
757 fstream.Read(FFloat, FDataLength);
758end;
759
760
761end.
Note: See TracBrowser for help on using the repository browser.