source: oup/releases/0.32a/Unit15_Classes.pas@ 522

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