source: oup/current/Code_OniDataClass.pas@ 43

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

DevTree 0.33a.

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