source: oup/current/Code/OniDataClass.pas@ 94

Last change on this file since 94 was 92, checked in by alloc, 18 years ago

Rev86 was first after multi-cons

File size: 41.5 KB
Line 
1unit OniDataClass;
2interface
3uses Data, Classes, SysUtils, StrUtils,
4 Dialogs, ABSDecUtil, ABSMain, DB, Windows;
5
6type
7 TOniData = class
8 private
9 FFileName: String;
10 FLevelInfo: TLevelInfo;
11 FBackend: Integer;
12 Fos_mac: Boolean;
13 protected
14 public
15 property FileName: String Read FFileName Write FFileName;
16 property Backend: Integer Read FBackend Write FBackend;
17 property OSisMac: Boolean Read Fos_mac Write Fos_mac;
18 property LevelInfo: TLevelinfo Read FLevelInfo Write FLevelInfo;
19
20 constructor Create(filename: String; var Result: Boolean); virtual; abstract;
21 procedure Close; virtual; abstract;
22
23 function GetFileInfo(fileid: Integer): TFileInfo; virtual;
24 function GetFilesList(ext: String; pattern: String;
25 NoEmptyFiles: Boolean; sort: TSortType): TStringArray; virtual; abstract;
26 function GetFilesCount: LongWord; virtual; abstract;
27 function GetExtensionsList: TStringArray; virtual; abstract;
28 function GetExtendedExtensionsList: TExtensionsMap; virtual; abstract;
29 function ExtractFileID(Name: String): Integer;
30 function GetFileIDByName(Name: String): Integer;
31
32 function LoadDatFile(fileid: LongWord): Tdata; virtual; abstract;
33 procedure UpdateDatFile(fileid: LongWord; Data: Tdata); virtual; abstract;
34 procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
35 virtual; abstract;
36 procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
37 virtual; abstract;
38
39 function GetRawList(fileid: LongWord): TRawList; virtual; abstract;
40 function GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
41 procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
42 virtual; abstract;
43 procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord; target: Pointer);
44 virtual; abstract;
45 procedure LoadRawFilePart(fileid, dat_offset: LongWord;
46 offset, size: LongWord; target: Pointer); virtual; abstract;
47 procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
48 offset, size: LongWord; target: Pointer); virtual; abstract;
49 function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
50 virtual; abstract;//Returns new Address
51 published
52 end;
53
54 TOniDataDat = class(TOniData)
55 private
56 Fdat_file: TFileStream;
57 Fraw_file: TFileStream;
58 Fsep_file: TFileStream;
59 Fdat_header: THeader;
60 Fdat_filesmap: TFilesMap;
61 Fdat_files: TFiles;
62 Fdat_namedfilesmap: TNamedFilesMap;
63 Fdat_extensionsmap: TExtensionsMap;
64 FUnloadWhenUnused: Boolean;
65 FDatOpened: Boolean;
66 FRawOpened: Boolean;
67 FSepOpened: Boolean;
68 protected
69 public
70 property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
71
72 constructor Create(DatFilename: String; var Result: Boolean); override;
73 procedure Close; override;
74
75 function GetFileInfo(fileid: Integer): TFileInfo; override;
76 function GetFilesList(ext: String; pattern: String;
77 NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
78 function GetFilesCount: LongWord; override;
79 function GetExtensionsList: TStringArray; override;
80 function GetExtendedExtensionsList: TExtensionsMap; override;
81
82 function LoadDatFile(fileid: LongWord): Tdata; override;
83 procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
84 procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
85 procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
86
87 procedure LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord; target: Pointer);
88 function GetRawList(fileid: LongWord): TRawList; override;
89 procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
90 procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
91 target: Pointer); override;
92 procedure LoadRawFilePart(fileid, dat_offset: LongWord;
93 offset, size: LongWord; target: Pointer); override;
94 procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
95 offset, size: LongWord; target: Pointer); override;
96 function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
97 override;//Returns new Address
98 published
99 end;
100
101 TOniDataADB = class(TOniData)
102 private
103 FDatabase: TABSDatabase;
104 FQuery: TABSQuery;
105 Fdat_files: TFiles;
106 Fdat_extensionsmap: TExtensionsMap;
107 protected
108 public
109 constructor Create(OLDBFilename: String; var Result: Boolean); override;
110 procedure Close; override;
111
112 procedure UpdateListCache;
113 // function GetDatLinks(srcid:LongWord):TDatLinks;
114 function GetFileInfo(fileid: Integer): TFileInfo; override;
115 function GetFilesList(ext: String; pattern: String;
116 NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
117 function GetFilesCount: LongWord; override;
118 function GetExtensionsList: TStringArray; override;
119 function GetExtendedExtensionsList: TExtensionsMap; override;
120 function GetNamedFilesMap: TNamedFilesMap;
121
122 function LoadDatFile(fileid: LongWord): Tdata; override;
123 procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
124 procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
125 procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
126
127 function GetRawList(fileid: LongWord): TRawList; override;
128 procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
129 procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
130 target: Pointer); override;
131 procedure LoadRawFilePart(fileid, dat_offset: LongWord;
132 offset, size: LongWord; target: Pointer); override;
133 procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
134 offset, size: LongWord; target: Pointer); override;
135 published
136 end;
137
138
139
140const
141 ODB_None = -1;
142 ODB_Dat = 0;
143 ODB_ADB = 1;
144
145var
146 DataConnections: array of TOniData;
147
148function CreateDataConnection(filename: String; backend: Integer): TOniData;
149function ConnectionExists(filename: String): TOniData;
150procedure CloseDataConnection(connection: TOniData);
151function GetEmptyFileInfo: TFileInfo;
152
153
154
155
156
157implementation
158uses DataStructures, Functions;
159
160
161
162(*
163 Implementation of TOniData
164*)
165
166function TOniData.GetFileIDByName(Name: String): Integer;
167var
168 files: TStringArray;
169 i: Integer;
170begin
171 Result := -1;
172 files := Self.GetFilesList('', Name, False, stIDAsc);
173 if Length(files) > 0 then
174 for i := 0 to High(files) do
175 if Pos(Name, files[i]) = Pos('-', files[i]) + 1 then
176 begin
177 // if MidStr(files[i],Pos('-',files[i])+1,Length(files[i])-Pos('-',files[i])-5)=name then begin
178 Result := Self.ExtractFileID(files[i]);
179 Break;
180 end;
181end;
182
183
184
185
186function TOniData.ExtractFileID(Name: String): Integer;
187begin
188 if Name[5] = '-' then
189 Result := HexToLong(MidStr(Name, 1, 4))
190 else
191 Result := StrToInt(MidStr(Name, 1, 5));
192end;
193
194
195
196
197function TOniData.GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
198var
199 i: LongWord;
200 raw_list: TRawList;
201begin
202 raw_list := Self.GetRawList(fileid);
203 Result.src_id := 0;
204 Result.src_offset := 0;
205 Result.raw_addr := 0;
206 Result.raw_size := 0;
207 if Length(raw_list) > 0 then
208 begin
209 for i := 0 to High(raw_list) do
210 begin
211 if raw_list[i].src_offset = dat_offset then
212 begin
213 Result.src_id := fileid;
214 Result.src_offset := raw_list[i].src_offset;
215 Result.raw_addr := raw_list[i].raw_addr;
216 Result.raw_size := raw_list[i].raw_size;
217 Result.loc_sep := raw_list[i].loc_sep;
218 Break;
219 end;
220 end;
221 end;
222end;
223
224
225
226function TOniData.GetFileInfo(fileid: Integer): TFileInfo;
227begin
228 Result.ID := -1;
229 Result.FileName := '';
230 Result.FileNameHex := '';
231 Result.Extension := '';
232 Result.Name := '';
233 Result.Size := 0;
234 Result.FileType := 0;
235 Result.DatAddr := 0;
236 Result.opened := False;
237end;
238
239
240
241
242(*
243================================================================================
244 Implementation of TOniDataDat
245*)
246
247constructor TOniDataDat.Create(DatFilename: String; var Result: Boolean);
248const
249 header_ident1_pc: array[0..$13] of Byte =
250 ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
251 $14, $00, $10, $00, $08, $00);
252 header_ident1_mac: array[0..$13] of Byte =
253 ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
254 $14, $00, $10, $00, $08, $00);
255 header_ident1_macbeta: array[0..$13] of Byte =
256 ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
257 $14, $00, $10, $00, $08, $00);
258 header_ident2: array[0..$F] of Byte =
259 ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
260var
261 i: LongWord;
262 header_pc, header_mac: Boolean;
263begin
264 FUnloadWhenUnused := True;
265 FDatOpened := False;
266 FRawOpened := False;
267 if not FileExists(DatFilename) then
268 begin
269 ShowMessage('File doesn''t exist!!!');
270 Result := False;
271 Exit;
272 end;
273 FFileName := DatFilename;
274 Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
275 Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
276 header_pc := True;
277 header_mac := True;
278 for i := 0 to High(Fdat_header.Ident) do
279 begin
280 FLevelInfo.Ident[i] := Fdat_header.Ident[i];
281 if Fdat_header.Ident[i] <> header_ident1_pc[i] then
282 header_pc := False;
283 if Fdat_header.Ident[i] <> header_ident1_mac[i] then
284 header_mac := False;
285 end;
286 if not (header_pc xor header_mac) then
287 begin
288 Result := False;
289 Exit;
290 end
291 else
292 begin
293 if (header_pc and not header_mac) then
294 Fos_mac := False
295 else
296 Fos_mac := True;
297 end;
298 SetLength(Fdat_filesmap, Fdat_header.Files);
299 SetLength(Fdat_files, Fdat_header.Files);
300 for i := 0 to Fdat_header.Files - 1 do
301 Fdat_file.Read(Fdat_filesmap[i], SizeOf(Fdat_filesmap[i]));
302 for i := 0 to Fdat_header.Files - 1 do
303 begin
304 Fdat_files[i].ID := i;
305 Fdat_files[i].Extension := Fdat_filesmap[i].Extension;
306 Fdat_files[i].Extension := ReverseString(Fdat_files[i].Extension);
307 Fdat_files[i].Size := Fdat_filesmap[i].FileSize;
308 Fdat_files[i].FileType := Fdat_filesmap[i].FileType;
309 Fdat_files[i].DatAddr := Fdat_filesmap[i].DataAddr - 8 + Fdat_header.DataAddr;
310 if (Fdat_filesmap[i].FileType and $01) = 0 then
311 begin
312 Fdat_file.Seek(Fdat_filesmap[i].NameAddr + Fdat_header.NamesAddr, soFromBeginning);
313 SetLength(Fdat_files[i].Name, 100);
314 Fdat_file.Read(Fdat_files[i].Name[1], 100);
315 Fdat_files[i].Name := MidStr(Fdat_files[i].Name, 1 + 4, Pos(
316 #0, Fdat_files[i].Name) - 1 - 4);
317 end
318 else
319 begin
320 Fdat_files[i].Name := '';
321 end;
322 Fdat_files[i].FileName :=
323 FormatNumber(i, 5, '0') + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
324 Fdat_files[i].FileNameHex :=
325 IntToHex(i, 4) + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
326 end;
327 Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
328 SetLength(Fdat_namedfilesmap, Fdat_header.NamedFiles);
329 for i := 0 to Fdat_header.NamedFiles - 1 do
330 Fdat_file.Read(Fdat_namedfilesmap[i], SizeOf(Fdat_namedfilesmap[i]));
331
332 Fdat_file.Seek($40 + Fdat_header.Files * $14 + Fdat_header.NamedFiles * $8, soFromBeginning);
333 SetLength(Fdat_extensionsmap, Fdat_header.Extensions);
334 for i := 0 to Fdat_header.Extensions - 1 do
335 Fdat_file.Read(Fdat_extensionsmap[i], SizeOf(Fdat_extensionsmap[i]));
336
337 Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
338 Fdat_file.Read(FLevelInfo.LevelNumber, 1);
339 FLevelInfo.LevelNumber := FLevelInfo.LevelNumber div 2;
340
341 Fdat_file.Free;
342
343 Result := True;
344 FBackend := ODB_Dat;
345end;
346
347
348
349
350procedure TOniDataDat.Close;
351begin
352 if not FUnloadWhenUnused and FDatOpened then
353 Fdat_file.Free;
354 if not FUnloadWhenUnused and FRawOpened then
355 Fraw_file.Free;
356 if not FUnloadWhenUnused and FSepOpened then
357 Fsep_file.Free;
358 Self.Free;
359end;
360
361
362
363
364function TOniDataDat.GetFileInfo(fileid: Integer): TFileInfo;
365begin
366 if fileid = -1 then
367 begin
368 Result := inherited GetFileInfo(fileid);
369 Exit;
370 end;
371 if fileid < Self.GetFilesCount then
372 Result := Fdat_files[fileid]
373 else
374 Result.ID := -1;
375end;
376
377
378
379
380function TOniDataDat.GetFilesList(ext: String; pattern: String;
381 NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
382var
383 i: LongWord;
384 list: TStringList;
385 id, name, extension: String;
386 fields: TStrings;
387
388 procedure getfields;
389 begin
390 fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
391 if sort in [stIDAsc, stIDDesc] then
392 begin
393 id := fields.Strings[0];
394 name := fields.Strings[1];
395 extension := fields.Strings[2];
396 end;
397 if sort in [stNameAsc, stNameDesc] then
398 begin
399 id := fields.Strings[1];
400 name := fields.Strings[0];
401 extension := fields.Strings[2];
402 end;
403 if sort in [stExtAsc, stExtDesc] then
404 begin
405 id := fields.Strings[1];
406 name := fields.Strings[2];
407 extension := fields.Strings[0];
408 end;
409 end;
410
411begin
412 list := TStringList.Create;
413 list.Sorted := True;
414 for i := 0 to Fdat_header.Files - 1 do
415 begin
416 if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
417 ((Length(pattern) = 0) or
418 (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
419 begin
420 if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
421 begin
422 if AppSettings.FilenumbersAsHex then
423 id := IntToHex(Fdat_files[i].ID, 4)
424 else
425 id := FormatNumber(Fdat_files[i].ID, 5, '0');
426 name := Fdat_files[i].Name;
427 extension := Fdat_files[i].Extension;
428
429 case sort of
430 stIDAsc, stIDDesc: list.Add(id + ';' + name + ';' + extension);
431 stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
432 stExtAsc, stExtDesc: list.Add(extension + ';' + id + ';' + name);
433 end;
434 end;
435 end;
436 end;
437 SetLength(Result, list.Count);
438 if Length(Result) > 0 then
439 begin
440 fields := TStringList.Create;
441 if sort in [stIDAsc, stNameAsc, stExtAsc] then
442 for i := 0 to list.Count - 1 do
443 begin
444 getfields;
445 Result[i] := id + '-' + name + '.' + extension;
446 end
447 else
448 for i := list.Count - 1 downto 0 do
449 begin
450 getfields;
451 Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
452 end;
453 fields.Free;
454 end;
455 list.Free;
456end;
457
458
459
460
461function TOniDataDat.GetFilesCount: LongWord;
462begin
463 Result := Fdat_header.Files;
464end;
465
466
467
468
469function TOniDataDat.GetExtensionsList: TStringArray;
470var
471 i: LongWord;
472begin
473 SetLength(Result, Fdat_header.Extensions);
474 for i := 0 to Fdat_header.Extensions - 1 do
475 begin
476 with Fdat_extensionsmap[i] do
477 begin
478 Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
479 ' (' + IntToStr(ExtCount) + ')';
480 end;
481 end;
482end;
483
484
485
486
487function TOniDataDat.GetExtendedExtensionsList: TExtensionsMap;
488var
489 i: LongWord;
490begin
491 SetLength(Result, Fdat_header.Extensions);
492 for i := 0 to Fdat_header.Extensions - 1 do
493 begin
494 Result[i] := Fdat_extensionsmap[i];
495 end;
496end;
497
498
499
500
501function TOniDataDat.LoadDatFile(fileid: LongWord): Tdata;
502begin
503 if fileid < Self.GetFilesCount then
504 begin
505 if FUnloadWhenUnused or not FDatOpened then
506 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
507 Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
508 SetLength(Result, Fdat_files[fileid].Size);
509 Fdat_file.Read(Result[0], Fdat_files[fileid].Size);
510 if UnloadWhenUnused then
511 Fdat_file.Free
512 else
513 FDatOpened := True;
514 end;
515end;
516
517
518
519
520procedure TOniDataDat.UpdateDatFile(fileid: LongWord; Data: Tdata);
521begin
522 if fileid < Self.GetFilesCount then
523 begin
524 if FUnloadWhenUnused or not FDatOpened then
525 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
526 Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
527 Fdat_file.Write(Data[0], Length(Data));
528 if UnloadWhenUnused then
529 Fdat_file.Free
530 else
531 FDatOpened := True;
532 end;
533end;
534
535
536
537
538procedure TOniDataDat.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
539begin
540 if fileid < Self.GetFilesCount then
541 begin
542 if FUnloadWhenUnused or not FDatOpened then
543 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
544 Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
545 Fdat_file.Read(target^, size);
546 if UnloadWhenUnused then
547 Fdat_file.Free
548 else
549 FDatOpened := True;
550 end;
551end;
552
553
554
555
556procedure TOniDataDat.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
557begin
558 if fileid < Self.GetFilesCount then
559 begin
560 if FUnloadWhenUnused or not FDatOpened then
561 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
562 Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
563 Fdat_file.Write(target^, size);
564 if UnloadWhenUnused then
565 Fdat_file.Free
566 else
567 FDatOpened := True;
568 end;
569end;
570
571
572
573
574function TOniDataDat.GetRawList(fileid: LongWord): TRawList;
575var
576 i: LongWord;
577begin
578 SetLength(Result, 0);
579 for i := 0 to High(RawListHandlers) do
580 if UpperCase(RawListHandlers[i].Ext) = UpperCase(Fdat_files[fileid].extension) then
581 if RawListHandlers[i].needed then
582 begin
583 Result := RawListHandlers[i].Handler(Self, fileid);
584 Break;
585 end
586 else
587 Break;
588end;
589
590
591
592
593procedure TOniDataDat.LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord;
594 target: Pointer);
595begin
596 if not loc_sep then
597 begin
598 if FUnloadWhenUnused or not FRawOpened then
599 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
600 fmOpenReadWrite);
601 if raw_addr <= Fraw_file.Size then
602 begin
603 Fraw_file.Seek(raw_addr, soFromBeginning);
604 Fraw_file.Read(target^, size);
605 end;
606 if UnloadWhenUnused then
607 Fraw_file.Free
608 else
609 FRawOpened := True;
610 end
611 else
612 begin
613 if FUnloadWhenUnused or not FSepOpened then
614 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
615 fmOpenReadWrite);
616 if raw_addr <= Fsep_file.Size then
617 begin
618 Fsep_file.Seek(raw_addr, soFromBeginning);
619 Fsep_file.Read(target^, size);
620 end;
621 if UnloadWhenUnused then
622 Fsep_file.Free
623 else
624 FSepOpened := True;
625 end;
626end;
627
628
629
630
631procedure TOniDataDat.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
632var
633 raw_info: TRawInfo;
634begin
635 if fileid < Self.GetFilesCount then
636 begin
637 raw_info := Self.GetRawInfo(fileid, dat_offset);
638 if not raw_info.loc_sep then
639 begin
640 if FUnloadWhenUnused or not FRawOpened then
641 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
642 fmOpenReadWrite);
643 Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
644 Fraw_file.Read(target^, raw_info.raw_size);
645 if UnloadWhenUnused then
646 Fraw_file.Free
647 else
648 FRawOpened := True;
649 end
650 else
651 begin
652 if FUnloadWhenUnused or not FSepOpened then
653 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
654 fmOpenReadWrite);
655 Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
656 Fsep_file.Read(target^, raw_info.raw_size);
657 if UnloadWhenUnused then
658 Fsep_file.Free
659 else
660 FSepOpened := True;
661 end;
662 end;
663end;
664
665
666
667
668procedure TOniDataDat.UpdateRawFile(fileid, dat_offset: LongWord;
669 size: LongWord; target: Pointer);
670var
671 raw_info: TRawInfo;
672begin
673 if fileid < Self.GetFilesCount then
674 begin
675 raw_info := Self.GetRawInfo(fileid, dat_offset);
676 if not raw_info.loc_sep then
677 begin
678 if FUnloadWhenUnused or not FRawOpened then
679 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
680 fmOpenReadWrite);
681 Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
682 Fraw_file.Write(target^, raw_info.raw_size);
683 if UnloadWhenUnused then
684 Fraw_file.Free
685 else
686 FRawOpened := True;
687 end
688 else
689 begin
690 if FUnloadWhenUnused or not FSepOpened then
691 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
692 fmOpenReadWrite);
693 Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
694 Fsep_file.Write(target^, raw_info.raw_size);
695 if UnloadWhenUnused then
696 Fsep_file.Free
697 else
698 FSepOpened := True;
699 end;
700 end;
701end;
702
703
704
705
706procedure TOniDataDat.LoadRawFilePart(fileid, dat_offset: LongWord;
707 offset, size: LongWord; target: Pointer);
708var
709 raw_info: TRawInfo;
710 Data: Tdata;
711 mem: TMemoryStream;
712begin
713 if fileid < Self.GetFilesCount then
714 begin
715 raw_info := Self.GetRawInfo(fileid, dat_offset);
716 SetLength(Data, raw_info.raw_size);
717 Self.LoadRawFile(fileid, dat_offset, @Data[0]);
718 mem := TMemoryStream.Create;
719 mem.Write(Data[offset], size);
720 mem.Read(target^, size);
721 mem.Free;
722 end;
723end;
724
725
726
727
728procedure TOniDataDat.UpdateRawFilePart(fileid, dat_offset: LongWord;
729 offset, size: LongWord; target: Pointer);
730var
731 raw_info: TRawInfo;
732begin
733 if fileid < Self.GetFilesCount then
734 begin
735 raw_info := Self.GetRawInfo(fileid, dat_offset);
736 if not raw_info.loc_sep then
737 begin
738 if FUnloadWhenUnused or not FRawOpened then
739 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
740 fmOpenReadWrite);
741 Fraw_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
742 Fraw_file.Write(target^, raw_info.raw_size);
743 if UnloadWhenUnused then
744 Fraw_file.Free
745 else
746 FRawOpened := True;
747 end
748 else
749 begin
750 if FUnloadWhenUnused or not FSepOpened then
751 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
752 fmOpenReadWrite);
753 Fsep_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
754 Fsep_file.Write(target^, raw_info.raw_size);
755 if UnloadWhenUnused then
756 Fsep_file.Free
757 else
758 FSepOpened := True;
759 end;
760 end;
761end;
762
763
764
765
766function TOniDataDat.AppendRawFile(loc_sep: Boolean; size: LongWord;
767 target: Pointer): LongWord; //Returns new Address
768begin
769 if not loc_sep then
770 begin
771 if FUnloadWhenUnused or not FRawOpened then
772 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
773 fmOpenReadWrite);
774 Result := Fraw_file.Size;
775 Fraw_file.Seek(0, soFromEnd);
776 Fraw_file.Write(target^, size);
777 if UnloadWhenUnused then
778 Fraw_file.Free
779 else
780 FRawOpened := True;
781 end
782 else
783 begin
784 if FUnloadWhenUnused or not FSepOpened then
785 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
786 fmOpenReadWrite);
787 Result := Fsep_file.Size;
788 Fsep_file.Seek(0, soFromEnd);
789 Fsep_file.Write(target^, size);
790 if UnloadWhenUnused then
791 Fsep_file.Free
792 else
793 FSepOpened := True;
794 end;
795end;
796
797
798
799
800
801
802
803
804
805
806
807(*
808================================================================================
809 Implementation of TOniDataADB
810*)
811
812constructor TOniDataADB.Create(OLDBFilename: String; var Result: Boolean);
813var
814 i, j: Byte;
815 temps: String;
816begin
817 if not FileExists(OLDBFilename) then
818 begin
819 ShowMessage('File doesn''t exist!!!');
820 Result := False;
821 Exit;
822 end;
823 FFileName := OLDBFilename;
824 FDatabase := TABSDatabase.Create(nil);
825 FDatabase.DatabaseName := 'OLDBcon';
826 FDatabase.DatabaseFileName := OLDBFilename;
827 FDatabase.Open;
828 FQuery := TABSQuery.Create(FDatabase);
829 FQuery.DatabaseName := 'OLDBcon';
830 FQuery.SQL.Text := 'SELECT [name],[value] FROM globals ORDER BY [name] ASC';
831 FQuery.Open;
832 FQuery.First;
833 repeat
834 if FQuery.FieldByName('name').AsString = 'dbversion' then
835 begin
836 if FQuery.FieldByName('value').AsString <> DBversion then
837 begin
838 ShowMessage('Database-file ' + #13 + #10 +
839 '"' + OLDBFilename + '"' + #13 + #10 +
840 'has wrong version. (Required: ' + DBversion + '; found: ' +
841 FQuery.FieldByName('value').AsString + ')');
842 FQuery.Close;
843 Result := False;
844 Exit;
845 end;
846 end;
847 if FQuery.FieldByName('name').AsString = 'lvl' then
848 begin
849 FLevelInfo.LevelNumber := StrToInt(FQuery.FieldByName('value').AsString);
850 end;
851 if FQuery.FieldByName('name').AsString = 'ident' then
852 begin
853 temps := FQuery.FieldByName('value').AsString;
854 for i := 0 to High(FLevelInfo.Ident) do
855 begin
856 j := i * 2 + 1;
857 case temps[j] of
858 '0'..'9':
859 FLevelInfo.Ident[i] := Ord(temps[j]) - 48;
860 'A'..'F':
861 FLevelInfo.Ident[i] := Ord(temps[j]) - 55;
862 end;
863 FLevelInfo.Ident[i] := FLevelInfo.Ident[i] * 16;
864 case temps[j + 1] of
865 '0'..'9':
866 FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 48;
867 'A'..'F':
868 FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 55;
869 end;
870 end;
871 end;
872 if FQuery.FieldByName('name').AsString = 'ident' then
873 begin
874 temps := FQuery.FieldByName('value').AsString;
875 Fos_mac := temps = 'MAC';
876 end;
877 FQuery.Next;
878 until FQuery.EOF;
879 FQuery.Close;
880
881 UpdateListCache;
882
883 Result := True;
884 FBackend := ODB_ADB;
885end;
886
887
888
889
890procedure TOniDataADB.Close;
891begin
892 FDatabase.Close;
893 FDatabase.Free;
894 Self.Free;
895end;
896
897
898
899procedure TOniDataADB.UpdateListCache;
900var
901 i: LongWord;
902 temps: String;
903begin
904 FQuery.SQL.Text := 'SELECT id,name,extension,[size],contenttype FROM datfiles ORDER BY id ASC;';
905 FQuery.Open;
906 if FQuery.RecordCount > 0 then
907 begin
908 FQuery.First;
909 SetLength(Fdat_files, FQuery.RecordCount);
910 i := 0;
911 repeat
912 Fdat_files[i].ID := FQuery.FieldByName('id').AsInteger;
913 Fdat_files[i].Name := FQuery.FieldByName('name').AsString;
914 Fdat_files[i].Extension := FQuery.FieldByName('extension').AsString;
915 Fdat_files[i].FileName := FormatNumber(Fdat_files[i].ID, 5, '0') + '-' +
916 Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
917 Fdat_files[i].FileNameHex := IntToHex(Fdat_files[i].ID, 4) + '-' +
918 Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
919 Fdat_files[i].Size := FQuery.FieldByName('size').AsInteger;
920 Fdat_files[i].FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
921 Fdat_files[i].DatAddr := 0;
922 Fdat_files[i].opened := False;
923 Inc(i);
924 FQuery.Next;
925 until FQuery.EOF;
926 end;
927 FQuery.Close;
928
929 SetLength(Fdat_extensionsmap, 0);
930 FQuery.SQL.Text :=
931 'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
932 FQuery.Open;
933 if FQuery.RecordCount > 0 then
934 begin
935 SetLength(Fdat_extensionsmap, FQuery.RecordCount);
936 i := 0;
937 repeat
938 temps := FQuery.FieldByName('extension').AsString[1];
939 Fdat_extensionsmap[i].Extension[3] := temps[1];
940 Fdat_extensionsmap[i].Extension[2] := temps[2];
941 Fdat_extensionsmap[i].Extension[1] := temps[3];
942 Fdat_extensionsmap[i].Extension[0] := temps[4];
943 Fdat_extensionsmap[i].ExtCount := FQuery.FieldByName('x').AsInteger;
944 Inc(i);
945 FQuery.Next;
946 until FQuery.EOF;
947 end;
948 FQuery.Close;
949end;
950
951
952function TOniDataADB.GetFileInfo(fileid: Integer): TFileInfo;
953var
954 i: Integer;
955begin
956 if fileid = -1 then
957 begin
958 Result := inherited GetFileInfo(fileid);
959 Exit;
960 end;
961 if fileid < Self.GetFilesCount then
962 begin
963 for i := 0 to High(Fdat_files) do
964 if Fdat_files[i].ID = fileid then
965 Break;
966 if i < Length(Fdat_files) then
967 Result := Fdat_files[i]
968 else
969 Result.ID := -1;
970 end
971 else
972 begin
973 Result.ID := -1;
974 end;
975end;
976
977
978
979
980function TOniDataADB.GetFilesList(ext: String; pattern: String;
981 NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
982var
983 i: LongWord;
984 list: TStringList;
985 id, name, extension: String;
986 fields: TStrings;
987
988 procedure getfields;
989 begin
990 fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
991 if sort in [stIDAsc, stIDDesc] then
992 begin
993 id := fields.Strings[0];
994 name := fields.Strings[1];
995 extension := fields.Strings[2];
996 end;
997 if sort in [stNameAsc, stNameDesc] then
998 begin
999 id := fields.Strings[1];
1000 name := fields.Strings[0];
1001 extension := fields.Strings[2];
1002 end;
1003 if sort in [stExtAsc, stExtDesc] then
1004 begin
1005 id := fields.Strings[1];
1006 name := fields.Strings[2];
1007 extension := fields.Strings[0];
1008 end;
1009 end;
1010
1011begin
1012 list := TStringList.Create;
1013 list.Sorted := True;
1014 for i := 0 to High(Fdat_files) do
1015 begin
1016 if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
1017 ((Length(pattern) = 0) or
1018 (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
1019 begin
1020 if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
1021 begin
1022 if AppSettings.FilenumbersAsHex then
1023 id := IntToHex(Fdat_files[i].ID, 4)
1024 else
1025 id := FormatNumber(Fdat_files[i].ID, 5, '0');
1026 name := Fdat_files[i].Name;
1027 extension := Fdat_files[i].Extension;
1028
1029 case sort of
1030 stIDAsc, stIDDesc: list.Add(id + ';' + name + ';' + extension);
1031 stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
1032 stExtAsc, stExtDesc: list.Add(extension + ';' + id + ';' + name);
1033 end;
1034 end;
1035 end;
1036 end;
1037 SetLength(Result, list.Count);
1038 fields := TStringList.Create;
1039 if sort in [stIDAsc, stNameAsc, stExtAsc] then
1040 for i := 0 to list.Count - 1 do
1041 begin
1042 getfields;
1043 Result[i] := id + '-' + name + '.' + extension;
1044 end
1045 else
1046 for i := list.Count - 1 downto 0 do
1047 begin
1048 getfields;
1049 Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
1050 end;
1051 list.Free;
1052 fields.Free;
1053end;
1054
1055
1056
1057
1058function TOniDataADB.GetFilesCount: LongWord;
1059begin
1060 Result := Length(Fdat_files);
1061end;
1062
1063
1064
1065
1066function TOniDataADB.GetExtensionsList: TStringArray;
1067var
1068 i: LongWord;
1069begin
1070 SetLength(Result, Length(Fdat_extensionsmap));
1071 for i := 0 to High(Result) do
1072 begin
1073 with Fdat_extensionsmap[i] do
1074 begin
1075 Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
1076 ' (' + IntToStr(ExtCount) + ')';
1077 end;
1078 end;
1079end;
1080
1081
1082
1083
1084function TOniDataADB.GetExtendedExtensionsList: TExtensionsMap;
1085var
1086 i, j: LongWord;
1087 temps: String;
1088 Data: Tdata;
1089begin
1090 SetLength(Result, 0);
1091 FQuery.SQL.Text := 'SELECT ext,ident FROM extlist ORDER BY ext ASC;';
1092 FQuery.Open;
1093 if FQuery.RecordCount > 0 then
1094 begin
1095 SetLength(Result, FQuery.RecordCount);
1096 i := 0;
1097 repeat
1098 temps := FQuery.FieldByName('ext').AsString;
1099 for j := 0 to 3 do
1100 Result[i].Extension[j] := temps[4 - j];
1101 Data := DecodeHexString(FQuery.FieldByName('ident').AsString);
1102 for j := 0 to 7 do
1103 Result[i].Ident[j] := Data[j];
1104 Inc(i);
1105 FQuery.Next;
1106 until FQuery.EOF;
1107 end;
1108 FQuery.Close;
1109end;
1110
1111
1112
1113
1114function TOniDataADB.GetNamedFilesMap: TNamedFilesMap;
1115var
1116 i: LongWord;
1117 temp: Integer;
1118 temps: String;
1119 temparray: array of record
1120 id: Integer;
1121 fullname: String[50];
1122 end;
1123begin
1124 SetLength(temparray, 0);
1125 FQuery.SQL.Text :=
1126 'SELECT id,(extension+name) AS xname FROM datfiles WHERE Length(name)>0 ORDER BY extension,name ASC;';
1127 FQuery.Open;
1128 if FQuery.RecordCount > 0 then
1129 begin
1130 repeat
1131 temp := FQuery.FieldByName('id').AsInteger;
1132 temps := FQuery.FieldByName('xname').AsString;
1133
1134 SetLength(temparray, Length(temparray) + 1);
1135 if Length(temparray) > 1 then
1136 begin
1137 for i := High(temparray) - 1 downto 0 do
1138 begin
1139 if StringSmaller(temps, temparray[i].fullname) then
1140 begin
1141 temparray[i + 1] := temparray[i];
1142 if i = 0 then
1143 begin
1144 temparray[i].id := temp;
1145 temparray[i].fullname := temps;
1146 end;
1147 end
1148 else
1149 begin
1150 temparray[i + 1].id := temp;
1151 temparray[i + 1].fullname := temps;
1152 Break;
1153 end;
1154 end;
1155 end
1156 else
1157 begin
1158 temparray[0].id := temp;
1159 temparray[0].fullname := temps;
1160 end;
1161 FQuery.Next;
1162 until FQuery.EOF;
1163 end;
1164 FQuery.Close;
1165 SetLength(Result, Length(temparray));
1166 for i := 0 to High(temparray) do
1167 begin
1168 Result[i].FileNumber := temparray[i].id;
1169 Result[i].blubb := 0;
1170 end;
1171end;
1172
1173
1174
1175
1176function TOniDataADB.LoadDatFile(fileid: LongWord): Tdata;
1177var
1178 mem: TStream;
1179begin
1180 if fileid < Self.GetFilesCount then
1181 begin
1182 FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
1183 FQuery.Open;
1184 if FQuery.RecordCount > 0 then
1185 begin
1186 mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
1187 SetLength(Result, mem.Size);
1188 mem.Seek(0, soFromBeginning);
1189 mem.Read(Result[0], mem.Size);
1190 mem.Free;
1191 end;
1192 FQuery.Close;
1193 end;
1194end;
1195
1196
1197
1198
1199procedure TOniDataADB.UpdateDatFile(fileid: LongWord; Data: Tdata);
1200var
1201 MimeCoder: TStringFormat_MIME64;
1202 mem: TMemoryStream;
1203begin
1204 if fileid < Self.GetFilesCount then
1205 begin
1206 mimecoder := TStringFormat_MIME64.Create;
1207 mem := TMemoryStream.Create;
1208 mem.Write(Data[0], Length(Data));
1209 mem.Seek(0, soFromBeginning);
1210 FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
1211 MimeCoder.StrTo(mem.Memory, mem.Size) + '"), size=' + IntToStr(mem.Size) +
1212 ' WHERE id=' + IntToStr(fileid) + ';';
1213 FQuery.ExecSQL;
1214 mem.Free;
1215 mimecoder.Free;
1216 end;
1217 UpdateListCache;
1218end;
1219
1220
1221
1222
1223procedure TOniDataADB.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
1224var
1225 mem: TStream;
1226begin
1227 if fileid < Self.GetFilesCount then
1228 begin
1229 FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
1230 FQuery.Open;
1231 if FQuery.RecordCount > 0 then
1232 begin
1233 mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
1234 mem.Seek(offset, soFromBeginning);
1235 mem.Read(target^, size);
1236 mem.Free;
1237 end;
1238 FQuery.Close;
1239 end;
1240end;
1241
1242
1243
1244
1245procedure TOniDataADB.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
1246var
1247 MimeCoder: TStringFormat_MIME64;
1248 mem: TMemoryStream;
1249 Data: Tdata;
1250begin
1251 if fileid < Self.GetFilesCount then
1252 begin
1253 Data := Self.LoadDatFile(fileid);
1254 mimecoder := TStringFormat_MIME64.Create;
1255 mem := TMemoryStream.Create;
1256 mem.Write(Data[0], Length(Data));
1257 mem.Seek(offset, soFromBeginning);
1258 mem.Write(target^, size);
1259 mem.Seek(0, soFromBeginning);
1260 FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
1261 MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
1262 FQuery.ExecSQL;
1263 mem.Free;
1264 mimecoder.Free;
1265 end;
1266end;
1267
1268
1269
1270
1271function TOniDataADB.GetRawList(fileid: LongWord): TRawList;
1272var
1273 i: LongWord;
1274begin
1275 SetLength(Result, 0);
1276 FQuery.SQL.Text := 'SELECT [src_link_offset],[size],[sep] FROM rawmap WHERE [src_id]=' +
1277 IntToStr(fileid) + ' ORDER BY src_link_offset ASC;';
1278 FQuery.Open;
1279 if FQuery.RecordCount > 0 then
1280 begin
1281 FQuery.First;
1282 SetLength(Result, FQuery.RecordCount);
1283 i := 0;
1284 repeat
1285 Result[i].src_id := fileid;
1286 Result[i].src_offset := FQuery.FieldByName('src_link_offset').AsInteger;
1287 Result[i].raw_addr := 0;
1288 Result[i].raw_size := FQuery.FieldByName('size').AsInteger;
1289 Result[i].loc_sep := FQuery.FieldByName('sep').AsBoolean;
1290 Inc(i);
1291 FQuery.Next;
1292 until FQuery.EOF;
1293 end;
1294 FQuery.Close;
1295end;
1296
1297
1298
1299
1300procedure TOniDataADB.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
1301var
1302 mem: TStream;
1303begin
1304 if fileid < Self.GetFilesCount then
1305 begin
1306 FQuery.SQL.Text := 'SELECT data FROM rawmap WHERE (src_id=' +
1307 IntToStr(fileid) + ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
1308 FQuery.Open;
1309 if FQuery.RecordCount > 0 then
1310 begin
1311 mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
1312 mem.Seek(0, soFromBeginning);
1313 mem.Read(target^, mem.size);
1314 mem.Free;
1315 end;
1316 FQuery.Close;
1317 end;
1318end;
1319
1320
1321
1322
1323procedure TOniDataADB.UpdateRawFile(fileid, dat_offset: LongWord;
1324 size: LongWord; target: Pointer);
1325var
1326 MimeCoder: TStringFormat_MIME64;
1327 mem: TMemoryStream;
1328begin
1329 if fileid < Self.GetFilesCount then
1330 begin
1331 mimecoder := TStringFormat_MIME64.Create;
1332 mem := TMemoryStream.Create;
1333 mem.Write(target^, size);
1334 mem.Seek(0, soFromBeginning);
1335 FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
1336 mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
1337 ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
1338 FQuery.ExecSQL;
1339 mem.Free;
1340 mimecoder.Free;
1341 end;
1342end;
1343
1344
1345
1346
1347procedure TOniDataADB.LoadRawFilePart(fileid, dat_offset: LongWord;
1348 offset, size: LongWord; target: Pointer);
1349var
1350 Data: Tdata;
1351 mem: TMemoryStream;
1352begin
1353 if fileid < Self.GetFilesCount then
1354 begin
1355 SetLength(Data, Self.GetRawInfo(fileid, dat_offset).raw_size);
1356 Self.LoadRawFile(fileid, dat_offset, @Data[0]);
1357 mem := TMemoryStream.Create;
1358 mem.Write(Data[offset], size);
1359 mem.Read(target^, size);
1360 mem.Free;
1361 end;
1362end;
1363
1364
1365
1366
1367procedure TOniDataADB.UpdateRawFilePart(fileid, dat_offset: LongWord;
1368 offset, size: LongWord; target: Pointer);
1369var
1370 MimeCoder: TStringFormat_MIME64;
1371 mem: TMemoryStream;
1372 Data: Tdata;
1373begin
1374 if fileid < Self.GetFilesCount then
1375 begin
1376 SetLength(Data, Self.GetRawInfo(fileid, offset).raw_size);
1377 Self.LoadRawFile(fileid, offset, @Data[0]);
1378 mimecoder := TStringFormat_MIME64.Create;
1379 mem := TMemoryStream.Create;
1380 mem.Write(Data[0], Length(Data));
1381 mem.Seek(offset, soFromBeginning);
1382 mem.Write(target^, size);
1383 mem.Seek(0, soFromBeginning);
1384 FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
1385 mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
1386 ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
1387 FQuery.ExecSQL;
1388 mem.Free;
1389 mimecoder.Free;
1390 end;
1391end;
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403function CreateDataConnection(filename: String; backend: Integer): TOniData;
1404var
1405 answer: Boolean;
1406 i: Integer;
1407begin
1408 if Length(DataConnections) > 0 then
1409 begin
1410 for i := 0 to High(DataConnections) do
1411 begin
1412 if ExtractFileName(DataConnections[i].FFileName) = ExtractFileName(filename) then
1413 begin
1414 if DataConnections[i].FFileName <> filename then
1415 begin
1416 Result := nil;
1417 ShowMessage('You can not open two files with the same name at a time.');
1418 end
1419 else
1420 Result := DataConnections[i];
1421 Exit;
1422 end;
1423 end;
1424 end;
1425
1426 if not FileExists(filename) then
1427 begin
1428 ShowMessage('File "' + filename + '" does not exist!');
1429 Result := nil;
1430 Exit;
1431 end;
1432
1433 SetLength(DataConnections, Length(DataConnections) + 1);
1434 i := High(DataConnections);
1435 case backend of
1436 ODB_Dat:
1437 DataConnections[i] := TOniDataDat.Create(filename, answer);
1438 ODB_ADB:
1439 DataConnections[i] := TOniDataADB.Create(filename, answer);
1440 else
1441 ShowMessage('Unknown Backend');
1442 Result := nil;
1443 Exit;
1444 end;
1445
1446 if answer then
1447 begin
1448 Result := DataConnections[i];
1449// Result := True;
1450 end
1451 else
1452 begin
1453 ShowMessage('File not loaded');
1454 DataConnections[i].Close;
1455 DataConnections[i].Free;
1456 DataConnections[i] := nil;
1457 SetLength(DataConnections, Length(DataConnections) - 1);
1458 Result := nil;
1459 end;
1460end;
1461
1462
1463function ConnectionExists(filename: String): TOniData;
1464var
1465 i: Integer;
1466begin
1467 Result := nil;
1468 if Length(DataConnections) > 0 then
1469 for i := 0 to High(DataConnections) do
1470 if DataConnections[i].FFileName = filename then
1471 begin
1472 Result := DataConnections[i];
1473 Exit;
1474 end;
1475end;
1476
1477
1478procedure CloseDataConnection(connection: TOniData);
1479var
1480 i: Integer;
1481 found: Boolean;
1482begin
1483 if Assigned(connection) then
1484 begin
1485 found := False;
1486 for i := 0 to High(DataConnections) do
1487 begin
1488 if not found then
1489 begin
1490 if DataConnections[i] = connection then
1491 begin
1492 DataConnections[i].Close;
1493// DataConnections[i].Free;
1494 DataConnections[i] := nil;
1495 found := True;
1496 end;
1497 end
1498 else
1499 begin
1500 DataConnections[i - 1] := DataConnections[i];
1501 end;
1502 end;
1503 if found then
1504 SetLength(DataConnections, Length(DataConnections) - 1);
1505 end;
1506end;
1507
1508
1509function GetEmptyFileInfo: TFileInfo;
1510begin
1511 Result.ID := -1;
1512 Result.FileName := '';
1513 Result.FileNameHex := '';
1514 Result.Extension := '';
1515 Result.Name := '';
1516 Result.Size := 0;
1517 Result.FileType := 0;
1518 Result.DatAddr := 0;
1519 Result.opened := False;
1520end;
1521
1522
1523end.
Note: See TracBrowser for help on using the repository browser.