source: oup/releases/0.31a/Unit15_Classes.pas@ 455

Last change on this file since 455 was 34, checked in by alloc, 18 years ago
File size: 33.3 KB
Line 
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 GetFileInfo(fileid:LongWord):TFileInfo; override;
98 function GetFilesList(ext:String; pattern:String; NoEmptyFiles:Boolean):TStringArray; override;
99 function GetFilesCount:LongWord; override;
100 function GetExtensionsList:TStringArray; override;
101 function GetExtendedExtensionsList:TExtensionsMap; override;
102
103 function LoadDatFile(fileid:LongWord):Tdata; override;
104 procedure UpdateDatFile(fileid:LongWord; data:Tdata); override;
105 procedure LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer); override;
106 procedure UpdateDatFilePart(fileid,offset,size:LongWord; target:Pointer); override;
107
108 function GetRawList(fileid:LongWord):TRawList; override;
109 procedure LoadRawFile(fileid,dat_offset:LongWord; target:Pointer); override;
110 procedure UpdateRawFile(fileid,dat_offset:LongWord; size:LongWord; target:Pointer); override;
111 procedure LoadRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer); override;
112 procedure UpdateRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer); override;
113 published
114 end;
115
116
117const
118 ODB_None=-1;
119 ODB_Dat=0;
120 ODB_ADB=1;
121
122var
123 OniDataConnection:TOniData;
124
125function CreateDataConnection(filename:String; backend:Integer):Boolean;
126procedure CloseDataConnection;
127
128
129
130
131implementation
132uses Unit2_Functions;
133
134
135
136(*
137 Implementation of TOniData
138*)
139
140function TOniData.GetFileIDByName(name:String):Integer;
141 var
142 files:TStringArray;
143 i: Integer;
144 begin
145 Result:=-1;
146 files:=Self.GetFilesList('',name,false);
147 if Length(files)>0 then
148 for i:=0 to High(files) do
149 if Pos(name,files[i])=Pos('-',files[i])+1 then begin
150// if MidStr(files[i],Pos('-',files[i])+1,Length(files[i])-Pos('-',files[i])-5)=name then begin
151 Result:=Self.ExtractFileID(files[i]);
152 Break;
153 end;
154 end;
155
156function TOniData.ExtractFileID(name:String):Integer;
157 begin
158 if name[5]='-' then
159 Result:=HexToLong(MidStr(name,1,4))
160 else
161 Result:=StrToInt(MidStr(name,1,5));
162 end;
163
164function TOniData.GetRawInfo(fileid,dat_offset:LongWord):TRawInfo;
165 var
166 i:LongWord;
167 raw_list:TRawList;
168 begin
169 raw_list:=Self.GetRawList(fileid);
170 Result.src_id:=0;
171 Result.src_offset:=0;
172 Result.raw_addr:=0;
173 Result.raw_size:=0;
174 for i:=0 to High(raw_list) do begin
175 if raw_list[i].src_offset=dat_offset then begin
176 Result.src_id:=fileid;
177 Result.src_offset:=raw_list[i].src_offset;
178 Result.raw_addr:=raw_list[i].raw_addr;
179 Result.raw_size:=raw_list[i].raw_size;
180 Result.loc_sep:=raw_list[i].loc_sep;
181 Break;
182 end;
183 end;
184 end;
185
186
187
188
189
190
191
192(*
193================================================================================
194 Implementation of TOniDataDat
195*)
196
197constructor TOniDataDat.Create(DatFilename:String; var Result:Boolean);
198 const
199 header_ident1_pc:Array[0..$13] of Byte=
200 ($1F,$27,$DC,$33,$DF,$BC,$03,$00,$31,$33,$52,$56,$40,$00,$14,$00,$10,$00,$08,$00);
201 header_ident1_mac:Array[0..$13] of Byte=
202 ($61,$30,$C1,$23,$DF,$BC,$03,$00,$31,$33,$52,$56,$40,$00,$14,$00,$10,$00,$08,$00);
203 header_ident2:Array[0..$F] of Byte=
204 ($99,$CF,$40,$00,$90,$4F,$63,$00,$F4,$55,$5F,$00,$90,$4F,$63,$00);
205 var
206 i:LongWord;
207 header_pc,header_mac:Boolean;
208 begin
209 FUnloadWhenUnused:=True;
210 FDatOpened:=False;
211 FRawOpened:=False;
212 if not FileExists(DatFilename) then begin
213 ShowMessage('File doesn''t exist!!!');
214 Result:=False;
215 Exit;
216 end;
217 FFileName:=DatFilename;
218 Fdat_file:=TFileStream.Create(FFileName, fmOpenRead);
219 Fdat_file.Read(Fdat_header,SizeOf(Fdat_header));
220 header_pc:=True;
221 header_mac:=True;
222 for i:=0 to High(Fdat_header.Ident) do begin
223 FLevelInfo.Ident[i]:=Fdat_header.Ident[i];
224 if Fdat_header.Ident[i]<>header_ident1_pc[i] then begin
225 header_pc:=False;
226 end;
227 if Fdat_header.Ident[i]<>header_ident1_mac[i] then begin
228 header_mac:=False;
229 end;
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 Fdat_file.Free;
400 if UnloadWhenUnused then
401 Fdat_file.Free
402 else
403 FDatOpened:=True;
404 end;
405 end;
406
407
408
409function TOniDataDat.GetRawList(fileid:LongWord):TRawList;
410 var
411 i:LongWord;
412 begin
413 SetLength(Result,0);
414 for i:=0 to High(RawListHandlers) do
415 if UpperCase(RawListHandlers[i].Ext)=UpperCase(Fdat_files[fileid].extension) then
416 if RawListHandlers[i].needed then begin
417 Result:=RawListHandlers[i].Handler(fileid);
418 Break;
419 end else
420 Break;
421 end;
422
423procedure TOniDataDat.LoadRawOffset(loc_sep:Boolean; raw_addr,size:LongWord; target:Pointer);
424 begin
425 if not loc_sep then begin
426 if FUnloadWhenUnused or not FRawOpened then
427 Fraw_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.raw'),fmOpenReadWrite);
428 if raw_addr<=Fraw_file.Size then begin
429 Fraw_file.Seek(raw_addr,soFromBeginning);
430 Fraw_file.Read(target^,size);
431 end;
432 if UnloadWhenUnused then
433 Fraw_file.Free
434 else
435 FRawOpened:=True
436 end else begin
437 if FUnloadWhenUnused or not FSepOpened then
438 Fsep_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.sep'),fmOpenReadWrite);
439 if raw_addr<=Fsep_file.Size then begin
440 Fsep_file.Seek(raw_addr,soFromBeginning);
441 Fsep_file.Read(target^,size);
442 end;
443 if UnloadWhenUnused then
444 Fsep_file.Free
445 else
446 FSepOpened:=True;
447 end;
448 end;
449
450procedure TOniDataDat.LoadRawFile(fileid,dat_offset:LongWord; target:Pointer);
451 var
452 raw_info:TRawInfo;
453 begin
454 if fileid<Self.GetFilesCount then begin
455 raw_info:=Self.GetRawInfo(fileid,dat_offset);
456 if not raw_info.loc_sep then begin
457 if FUnloadWhenUnused or not FRawOpened then
458 Fraw_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.raw'),fmOpenReadWrite);
459 Fraw_file.Seek(raw_info.raw_addr,soFromBeginning);
460 Fraw_file.Read(target^,raw_info.raw_size);
461 if UnloadWhenUnused then
462 Fraw_file.Free
463 else
464 FRawOpened:=True
465 end else begin
466 if FUnloadWhenUnused or not FSepOpened then
467 Fsep_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.sep'),fmOpenReadWrite);
468 Fsep_file.Seek(raw_info.raw_addr,soFromBeginning);
469 Fsep_file.Read(target^,raw_info.raw_size);
470 if UnloadWhenUnused then
471 Fsep_file.Free
472 else
473 FSepOpened:=True;
474 end;
475 end;
476 end;
477
478procedure TOniDataDat.UpdateRawFile(fileid,dat_offset:LongWord; size:LongWord; target:Pointer);
479 var
480 raw_info:TRawInfo;
481 begin
482 if fileid<Self.GetFilesCount then begin
483 raw_info:=Self.GetRawInfo(fileid,dat_offset);
484 if not raw_info.loc_sep then begin
485 if FUnloadWhenUnused or not FRawOpened then
486 Fraw_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.raw'),fmOpenReadWrite);
487 Fraw_file.Seek(raw_info.raw_addr,soFromBeginning);
488 Fraw_file.Write(target^,raw_info.raw_size);
489 if UnloadWhenUnused then
490 Fraw_file.Free
491 else
492 FRawOpened:=True
493 end else begin
494 if FUnloadWhenUnused or not FSepOpened then
495 Fsep_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.sep'),fmOpenReadWrite);
496 Fsep_file.Seek(raw_info.raw_addr,soFromBeginning);
497 Fsep_file.Write(target^,raw_info.raw_size);
498 if UnloadWhenUnused then
499 Fsep_file.Free
500 else
501 FSepOpened:=True;
502 end;
503 end;
504 end;
505
506procedure TOniDataDat.LoadRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer);
507 var
508 raw_info:TRawInfo;
509 data:Tdata;
510 mem:TMemoryStream;
511 begin
512 if fileid<Self.GetFilesCount then begin
513 raw_info:=Self.GetRawInfo(fileid,dat_offset);
514 SetLength(data, raw_info.raw_size);
515 Self.LoadRawFile(fileid,dat_offset,@data[0]);
516 mem:=TMemoryStream.Create;
517 mem.Write(data[offset],size);
518 mem.Read(target^,size);
519 mem.Free;
520 end;
521 end;
522
523procedure TOniDataDat.UpdateRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer);
524 var
525 raw_info:TRawInfo;
526 begin
527 if fileid<Self.GetFilesCount then begin
528 raw_info:=Self.GetRawInfo(fileid,dat_offset);
529 if not raw_info.loc_sep then begin
530 if FUnloadWhenUnused or not FRawOpened then
531 Fraw_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.raw'),fmOpenReadWrite);
532 Fraw_file.Seek(raw_info.raw_addr+offset,soFromBeginning);
533 Fraw_file.Write(target^,raw_info.raw_size);
534 if UnloadWhenUnused then
535 Fraw_file.Free
536 else
537 FRawOpened:=True
538 end else begin
539 if FUnloadWhenUnused or not FSepOpened then
540 Fsep_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.sep'),fmOpenReadWrite);
541 Fsep_file.Seek(raw_info.raw_addr+offset,soFromBeginning);
542 Fsep_file.Write(target^,raw_info.raw_size);
543 if UnloadWhenUnused then
544 Fsep_file.Free
545 else
546 FSepOpened:=True;
547 end;
548 end;
549 end;
550
551function TOniDataDat.AppendRawFile(loc_sep:Boolean; size:LongWord; target:Pointer):LongWord; //Returns new Address
552 begin
553 if not loc_sep then begin
554 if FUnloadWhenUnused or not FRawOpened then
555 Fraw_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.raw'),fmOpenReadWrite);
556 Result:=Fraw_file.Size;
557 Fraw_file.Seek(0,soFromEnd);
558 Fraw_file.Write(target^,size);
559 if UnloadWhenUnused then
560 Fraw_file.Free
561 else
562 FRawOpened:=True
563 end else begin
564 if FUnloadWhenUnused or not FSepOpened then
565 Fsep_file:=TFileStream.Create(AnsiReplaceStr(FFileName,'.dat','.sep'),fmOpenReadWrite);
566 Result:=Fsep_file.Size;
567 Fsep_file.Seek(0,soFromEnd);
568 Fsep_file.Write(target^,size);
569 if UnloadWhenUnused then
570 Fsep_file.Free
571 else
572 FSepOpened:=True;
573 end;
574 end;
575
576
577
578
579
580
581
582
583
584
585
586(*
587================================================================================
588 Implementation of TOniDataADB
589*)
590
591constructor TOniDataADB.Create(OLDBFilename:String; var Result:Boolean);
592 var
593 i,j:Byte;
594 temps:String;
595 begin
596 if not FileExists(OLDBFilename) then begin
597 ShowMessage('File doesn''t exist!!!');
598 Result:=False;
599 Exit;
600 end;
601 FFileName:=OLDBFilename;
602 FDatabase:=TABSDatabase.Create(nil);
603 FDatabase.DatabaseName:='OLDBcon';
604 FDatabase.DatabaseFileName:=OLDBFilename;
605 FDatabase.Open;
606 FQuery:=TABSQuery.Create(FDatabase);
607 FQuery.DatabaseName:='OLDBcon';
608 FQuery.SQL.Text:='SELECT [name],[value] FROM globals ORDER BY [name] ASC';
609 FQuery.Open;
610 FQuery.First;
611 repeat
612 if FQuery.FieldByName('name').AsString='dbversion' then begin
613 if FQuery.FieldByName('value').AsString<>DBversion then begin
614 ShowMessage('Database-file '+#13+#10+
615 '"'+OLDBFilename+'"'+#13+#10+
616 'has wrong version. (Required: '+DBversion+'; found: '+
617 FQuery.FieldByName('value').AsString+')');
618 FQuery.Close;
619 Result:=False;
620 Exit;
621 end;
622 end;
623 if FQuery.FieldByName('name').AsString='lvl' then begin
624 FLevelInfo.LevelNumber:=StrToInt(FQuery.FieldByName('value').AsString);
625 end;
626 if FQuery.FieldByName('name').AsString='ident' then begin
627 temps:=FQuery.FieldByName('value').AsString;
628 for i:=0 to High(FLevelInfo.Ident) do begin
629 j:=i*2+1;
630 case temps[j] of
631 '0'..'9': FLevelInfo.Ident[i]:=Ord(temps[j])-48;
632 'A'..'F': FLevelInfo.Ident[i]:=Ord(temps[j])-55;
633 end;
634 FLevelInfo.Ident[i]:=FLevelInfo.Ident[i]*16;
635 case temps[j+1] of
636 '0'..'9': FLevelInfo.Ident[i]:=FLevelInfo.Ident[i]+Ord(temps[j+1])-48;
637 'A'..'F': FLevelInfo.Ident[i]:=FLevelInfo.Ident[i]+Ord(temps[j+1])-55;
638 end;
639 end;
640 end;
641 if FQuery.FieldByName('name').AsString='ident' then begin
642 temps:=FQuery.FieldByName('value').AsString;
643 Fos_mac:=temps='MAC';
644 end;
645 FQuery.Next;
646 until FQuery.EoF;
647 FQuery.Close;
648
649 Result:=True;
650 FBackend:=ODB_ADB;
651 end;
652
653procedure TOniDataADB.Close;
654 begin
655 FDatabase.Close;
656 FDatabase.Free;
657 Self.Free;
658 end;
659
660
661
662function TOniDataADB.GetFileInfo(fileid:LongWord):TFileInfo;
663 begin
664 if fileid<Self.GetFilesCount then begin
665 FQuery.SQL.Text:='SELECT * FROM datfiles WHERE id='+IntToStr(fileid)+' ORDER BY id ASC;';
666 FQuery.Open;
667 if FQuery.RecordCount=1 then begin
668 FQuery.First;
669 Result.ID:=FQuery.FieldByName('id').AsInteger;
670 Result.Name:=FQuery.FieldByName('name').AsString;
671 Result.Extension:=FQuery.FieldByName('extension').AsString;
672 Result.FileName:=FormatNumber(Result.ID,5,'0')+'-'+Result.Name+'.'+Result.Extension;
673 Result.Size:=FQuery.FieldByName('size').AsInteger;
674 Result.FileType:=FQuery.FieldByName('contenttype').AsInteger;
675 Result.DatAddr:=0;
676 Result.opened:=False;
677 end;
678 FQuery.Close;
679 end else begin
680 Result.ID:=-1;
681 end;
682 end;
683
684function TOniDataADB.GetFilesList(ext:String; pattern:String; NoEmptyFiles:Boolean):TStringArray;
685 var
686 i:LongWord;
687 where:String;
688 where_ext:String;
689 begin
690 where:='';
691 if Length(ext)>0 then begin
692 if Length(where)>0 then
693 where:=where+' AND ';
694 if Pos(',',ext)>0 then begin
695 i:=1;
696 where_ext:='';
697 while i<Length(ext) do begin
698 if Length(where_ext)>0 then
699 where_ext:=where_ext+' OR ';
700 where_ext:=where_ext+'(extension="'+MidStr(ext,i,4)+'")';
701 i:=i+5;
702 end;
703 where:=where+'('+where_ext+')';
704 end else begin
705 where:=where+'(extension="'+ext+'")';
706 end;
707 end;
708 if Length(pattern)>0 then begin
709 if Length(where)>0 then
710 where:=where+' AND ';
711 where:=where+'(name LIKE "%'+pattern+'%")';
712 end;
713 if NoEmptyFiles then begin
714 if Length(where)>0 then
715 where:=where+' AND ';
716 where:=where+'(contenttype<>2)';
717 end;
718 if Length(where)>0 then
719 where:=' WHERE '+where;
720 FQuery.SQL.Text:='SELECT id,name,extension FROM datfiles'+where+' ORDER BY id ASC;';
721 FQuery.Open;
722 if FQuery.RecordCount>0 then begin
723 FQuery.First;
724 SetLength(Result,FQuery.RecordCount);
725 i:=0;
726 repeat
727 Result[i]:=FormatNumber(FQuery.FieldByName('id').AsInteger,5,'0')+'-'+FQuery.FieldByName('name').AsString+'.'+FQuery.FieldByName('extension').AsString;
728 Inc(i);
729 FQuery.Next;
730 until FQuery.EOF;
731 end;
732 FQuery.Close;
733 end;
734
735function TOniDataADB.GetFilesCount:LongWord;
736 begin
737 FQuery.SQL.Text:='SELECT Count(*) AS cnumber FROM datfiles;';
738 FQuery.Open;
739 if FQuery.RecordCount>0 then begin
740 FQuery.First;
741 Result:=FQuery.FieldByName('cnumber').AsInteger;
742 end else Result:=0;
743 FQuery.Close;
744 end;
745
746function TOniDataADB.GetExtensionsList:TStringArray;
747 var
748 i:LongWord;
749 begin
750 SetLength(Result,0);
751 FQuery.SQL.Text:='SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
752 FQuery.Open;
753 if FQuery.RecordCount>0 then begin
754 SetLength(Result,FQuery.RecordCount);
755 i:=0;
756 repeat
757 Result[i]:=FQuery.FieldByName('extension').AsString+' ('+IntToStr(FQuery.FieldByName('x').AsInteger)+')';
758 Inc(i);
759 FQuery.Next;
760 until FQuery.EOF;
761 end;
762 FQuery.Close;
763 end;
764
765function TOniDataADB.GetExtendedExtensionsList:TExtensionsMap;
766 var
767 i,j:LongWord;
768 temps:String;
769 data:Tdata;
770 begin
771 SetLength(Result,0);
772 FQuery.SQL.Text:='SELECT extension,ident FROM extlist ORDER BY extension ASC;';
773 FQuery.Open;
774 if FQuery.RecordCount>0 then begin
775 SetLength(Result,FQuery.RecordCount);
776 i:=0;
777 repeat
778 temps:=FQuery.FieldByName('extension').AsString;
779 for j:=0 to 3 do Result[i].Extension[j]:=temps[3-j];
780 data:=DecodeHexString(FQuery.FieldByName('ident').AsString);
781 for j:=0 to 7 do Result[i].Ident[j]:=data[j];
782 Inc(i);
783 FQuery.Next;
784 until FQuery.EOF;
785 end;
786 FQuery.Close;
787 end;
788
789
790
791function TOniDataADB.LoadDatFile(fileid:LongWord):Tdata;
792 var
793 mem:TStream;
794 begin
795 if fileid<Self.GetFilesCount then begin
796 FQuery.SQL.Text:='SELECT data FROM datfiles WHERE id='+IntToStr(fileid)+';';
797 FQuery.Open;
798 if FQuery.RecordCount>0 then begin
799 mem:=FQuery.CreateBlobStream(FQuery.FieldByName('data'),bmRead);
800 SetLength(Result,mem.Size);
801 mem.Seek(0,soFromBeginning);
802 mem.Read(Result[0],mem.Size);
803 mem.Free;
804 end;
805 FQuery.Close;
806 end;
807 end;
808
809procedure TOniDataADB.UpdateDatFile(fileid:LongWord; data:Tdata);
810 var
811 MimeCoder: TStringFormat_MIME64;
812 mem:TMemoryStream;
813 begin
814 if fileid<Self.GetFilesCount then begin
815 mimecoder:=TStringFormat_MIME64.Create;
816 mem:=TMemoryStream.Create;
817 mem.Write(data[0],Length(data));
818 mem.Seek(0,soFromBeginning);
819 FQuery.SQL.Text:='UPDATE datfiles SET data=MimeToBin("'+MimeCoder.StrTo(mem.Memory, mem.Size)+'") WHERE id='+IntToStr(fileid)+';';
820 FQuery.ExecSQL;
821 mem.Free;
822 mimecoder.Free;
823 end;
824 end;
825
826procedure TOniDataADB.LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer);
827 var
828 mem:TStream;
829 begin
830 if fileid<Self.GetFilesCount then begin
831 FQuery.SQL.Text:='SELECT data FROM datfiles WHERE id='+IntToStr(fileid)+';';
832 FQuery.Open;
833 IF FQuery.RecordCount>0 THEN BEGIN
834 mem:=FQuery.CreateBlobStream(FQuery.FieldByName('data'),bmRead);
835 mem.Seek(offset,soFromBeginning);
836 mem.Read(target^,size);
837 mem.Free;
838 END;
839 FQuery.Close;
840 END;
841 END;
842
843procedure TOniDataADB.UpdateDatFilePart(fileid,offset,size:LongWord; target:Pointer);
844 var
845 MimeCoder: TStringFormat_MIME64;
846 mem:TMemoryStream;
847 data:Tdata;
848 begin
849 if fileid<Self.GetFilesCount then begin
850 data:=Self.LoadDatFile(fileid);
851 mimecoder:=TStringFormat_MIME64.Create;
852 mem:=TMemoryStream.Create;
853 mem.Write(data[0],Length(data));
854 mem.Seek(offset,soFromBeginning);
855 mem.Write(target^,size);
856 mem.Seek(0,soFromBeginning);
857 FQuery.SQL.Text:='UPDATE datfiles SET data=MimeToBin("'+MimeCoder.StrTo(mem.Memory, mem.Size)+'") WHERE id='+IntToStr(fileid)+';';
858 FQuery.ExecSQL;
859 mem.Free;
860 mimecoder.Free;
861 end;
862 end;
863
864
865
866function TOniDataADB.GetRawList(fileid:LongWord):TRawList;
867 var
868 i:LongWord;
869 Query:TABSQuery;
870 begin
871 SetLength(Result,0);
872 FQuery.SQL.Text:='SELECT [src_link_offset],[size] FROM rawmap WHERE [src_id]='+IntToStr(fileid)+' ORDER BY src_link_offset ASC;';
873 FQuery.Open;
874 if FQuery.RecordCount>0 then begin
875 FQuery.First;
876 SetLength(Result,FQuery.RecordCount);
877 i:=0;
878 repeat
879 Result[i].src_id:=fileid;
880 Result[i].src_offset:=FQuery.FieldByName('src_link_offset').AsInteger;
881 Result[i].raw_addr:=0;
882 Result[i].raw_size:=FQuery.FieldByName('size').AsInteger;
883 Inc(i);
884 FQuery.Next;
885 until FQuery.EOF;
886 end;
887 FQuery.Close;
888 end;
889
890procedure TOniDataADB.LoadRawFile(fileid,dat_offset:LongWord; target:Pointer);
891 var
892 mem:TStream;
893 begin
894 if fileid<Self.GetFilesCount then begin
895 FQuery.SQL.Text:='SELECT data FROM rawmap WHERE (src_id='+IntToStr(fileid)+') AND (src_link_offset='+IntToStr(dat_offset)+');';
896 FQuery.Open;
897 if FQuery.RecordCount>0 then begin
898 mem:=FQuery.CreateBlobStream(FQuery.FieldByName('data'),bmRead);
899 mem.Seek(0,soFromBeginning);
900 mem.Read(target^,mem.size);
901 mem.Free;
902 end;
903 FQuery.Close;
904 end;
905 end;
906
907procedure TOniDataADB.UpdateRawFile(fileid,dat_offset:LongWord; size:LongWord; target:Pointer);
908 var
909 MimeCoder: TStringFormat_MIME64;
910 mem:TMemoryStream;
911 begin
912 if fileid<Self.GetFilesCount then begin
913 mimecoder:=TStringFormat_MIME64.Create;
914 mem:=TMemoryStream.Create;
915 mem.Write(target^,size);
916 mem.Seek(0,soFromBeginning);
917 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)+');';
918 FQuery.ExecSQL;
919 mem.Free;
920 mimecoder.Free;
921 end;
922 end;
923
924procedure TOniDataADB.LoadRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer);
925 var
926 data:Tdata;
927 mem:TMemoryStream;
928 begin
929 if fileid<Self.GetFilesCount then begin
930 SetLength(data, Self.GetRawInfo(fileid,dat_offset).raw_size);
931 Self.LoadRawFile(fileid,dat_offset,@data[0]);
932 mem:=TMemoryStream.Create;
933 mem.Write(data[offset],size);
934 mem.Read(target^,size);
935 mem.Free;
936 end;
937 end;
938
939procedure TOniDataADB.UpdateRawFilePart(fileid,dat_offset:LongWord; offset,size:LongWord; target:Pointer);
940 var
941 MimeCoder: TStringFormat_MIME64;
942 mem:TMemoryStream;
943 data:Tdata;
944 begin
945 if fileid<Self.GetFilesCount then begin
946 SetLength(data, Self.GetRawInfo(fileid,offset).raw_size);
947 Self.LoadRawFile(fileid,offset,@data[0]);
948 mimecoder:=TStringFormat_MIME64.Create;
949 mem:=TMemoryStream.Create;
950 mem.Write(data[0],Length(data));
951 mem.Seek(offset,soFromBeginning);
952 mem.Write(target^,size);
953 mem.Seek(0,soFromBeginning);
954 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)+');';
955 FQuery.ExecSQL;
956 mem.Free;
957 mimecoder.Free;
958 end;
959 end;
960
961
962
963
964
965
966
967
968
969
970
971function CreateDataConnection(filename:String; backend:Integer):Boolean;
972 var
973 answer:Boolean;
974 begin
975 if Assigned(OniDataConnection) then begin
976 OniDataConnection.Close;
977 OniDataConnection.Free;
978 OniDataConnection:=Nil;
979 end;
980 case backend of
981 ODB_Dat: OniDataConnection:=TOniDataDat.Create(filename, answer);
982 ODB_ADB: OniDataConnection:=TOniDataADB.Create(filename, answer);
983 else
984 ShowMessage('Unknown Backend');
985 Result:=False;
986 Exit;
987 end;
988
989 if answer then begin
990// ShowMessage('file loaded');
991// ShowMessage('Files: '+IntToStr(OniDataConnection.GetFilesCount));
992 Result:=True;
993 end else begin
994 ShowMessage('File not loaded');
995 OniDataConnection.Close;
996 OniDataConnection.Free;
997 Result:=False;
998 end;
999 end;
1000
1001procedure CloseDataConnection;
1002 begin
1003 if Assigned(OniDataConnection) then begin
1004 OniDataConnection.Close;
1005 OniDataConnection:=Nil;
1006 end;
1007 end;
1008
1009end.
Note: See TracBrowser for help on using the repository browser.