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

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