1 |
unit Unit15_Classes; |
2 |
interface |
3 |
uses Unit3_data, Unit9_data_structures, Classes, SysUtils, StrUtils, Dialogs, ABSDecUtil, ABSMain, DB; |
4 |
|
5 |
|
6 |
type |
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 |
|
117 |
const |
118 |
ODB_None=-1; |
119 |
ODB_Dat=0; |
120 |
ODB_ADB=1; |
121 |
|
122 |
var |
123 |
OniDataConnection:TOniData; |
124 |
|
125 |
function CreateDataConnection(filename:String; backend:Integer):Boolean; |
126 |
procedure CloseDataConnection; |
127 |
|
128 |
|
129 |
|
130 |
|
131 |
implementation |
132 |
uses Unit2_Functions; |
133 |
|
134 |
|
135 |
|
136 |
(* |
137 |
Implementation of TOniData |
138 |
*) |
139 |
|
140 |
function 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 |
|
156 |
function 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 |
|
164 |
function 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 |
|
197 |
constructor 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 |
|
281 |
procedure 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 |
|
294 |
function 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 |
|
302 |
function 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 |
|
321 |
function TOniDataDat.GetFilesCount:LongWord; |
322 |
begin |
323 |
Result:=Fdat_header.Files; |
324 |
end; |
325 |
|
326 |
function 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 |
|
338 |
function 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 |
|
349 |
function 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 |
|
364 |
procedure 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 |
|
378 |
procedure 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 |
|
392 |
procedure 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 |
|
409 |
function 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 |
|
423 |
procedure 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 |
|
450 |
procedure 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 |
|
478 |
procedure 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 |
|
506 |
procedure 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 |
|
523 |
procedure 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 |
|
551 |
function 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 |
|
591 |
constructor 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 |
|
653 |
procedure TOniDataADB.Close; |
654 |
begin |
655 |
FDatabase.Close; |
656 |
FDatabase.Free; |
657 |
Self.Free; |
658 |
end; |
659 |
|
660 |
|
661 |
|
662 |
function 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 |
|
684 |
function 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 |
|
735 |
function 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 |
|
746 |
function 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 |
|
765 |
function 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 |
|
791 |
function 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 |
|
809 |
procedure 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 |
|
826 |
procedure 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 |
|
843 |
procedure 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 |
|
866 |
function 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 |
|
890 |
procedure 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 |
|
907 |
procedure 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 |
|
924 |
procedure 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 |
|
939 |
procedure 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 |
|
971 |
function 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 |
|
1001 |
procedure CloseDataConnection; |
1002 |
begin |
1003 |
if Assigned(OniDataConnection) then begin |
1004 |
OniDataConnection.Close; |
1005 |
OniDataConnection:=Nil; |
1006 |
end; |
1007 |
end; |
1008 |
|
1009 |
end. |