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

Last change on this file since 92 was 92, checked in by alloc, 15 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.