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