source: oup/current/old_sqlite/Unit2_functions.pas@ 10

Last change on this file since 10 was 10, checked in by alloc, 18 years ago
  • Property svn:executable set to *
File size: 15.3 KB
Line 
1UNIT Unit2_functions;
2INTERFACE
3USES Classes, Dialogs, SysUtils, StrUtils, Math, SQLiteTable3,
4 Unit3_data, Unit4_Exporters, ABSMain{, DB};
5
6TYPE
7 TExportSet=SET OF (DO_dat,DO_raw,DO_convert,DO_toone);
8
9FUNCTION GetFilesList(ext:String; pattern:String; NoEmptyFiles:Boolean):TStringList;
10FUNCTION GetExtensionsList:TStringList;
11
12FUNCTION Decode_Int(buffer:Tdata):LongWord;
13FUNCTION Encode_Int(input:LongWord):Tdata;
14FUNCTION Decode_Float(buffer:Tdata):Single;
15FUNCTION Encode_Float(input:Single):Tdata;
16
17FUNCTION LoadDatInfos(filename:String):Boolean;
18PROCEDURE OpenDatabase(FileName:String);
19
20FUNCTION LoadDatFile(fileid:LongWord):Tdata;
21PROCEDURE UpdateDatFile(fileid:LongWord; data:Tdata);
22FUNCTION LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
23FUNCTION UpdateDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
24
25FUNCTION LoadRawFile(fileid,datlinkoffset,size:LongWord; target:Pointer):Boolean;
26FUNCTION UpdateRawFile(fileid,datlinkoffset,size:LongWord; target:Pointer):Boolean;
27
28FUNCTION ExportFile(fileid:LongWord; filename:String; settings:TExportSet; path:String):Integer;
29
30FUNCTION FormatNumber(value:LongWord; width:Byte; leadingzeros:Char):String;
31FUNCTION FormatFileSize(size:LongWord):String;
32FUNCTION CreateHexString(data:Tdata; HexOnly:Boolean):String;
33FUNCTION GetWinFileName(name:String):String;
34FUNCTION GetExtractPath:String;
35
36
37IMPLEMENTATION
38
39TYPE
40 TValueSwitcher=Record
41 CASE IsFloat: Boolean OF
42 True: (ValueFloat:Single);
43 False: (ValueInt:LongWord);
44 END;
45
46FUNCTION Decode_Int(buffer:Tdata):LongWord;
47 BEGIN
48 Result:=buffer[0]+buffer[1]*256+buffer[2]*256*256+buffer[3]*256*256*256;
49 END;
50FUNCTION Encode_Int(input:LongWord):Tdata;
51 BEGIN
52 Result[0]:=input MOD 256;
53 input:=input DIV 256;
54 Result[1]:=input MOD 256;
55 input:=input DIV 256;
56 Result[2]:=input MOD 256;
57 input:=input DIV 256;
58 Result[3]:=input MOD 256;
59 END;
60FUNCTION Decode_Float(buffer:Tdata):Single;
61 VAR _valueswitcher:TValueSwitcher;
62 BEGIN
63 _valueswitcher.ValueInt:=Decode_Int(buffer);
64 Result:=_valueswitcher.ValueFloat;
65 END;
66FUNCTION Encode_Float(input:Single):Tdata;
67 VAR _valueswitcher:TValueSwitcher;
68 BEGIN
69 _valueswitcher.ValueFloat:=input;
70 Result:=Encode_Int(_valueswitcher.ValueInt);
71 END;
72
73
74FUNCTION GetFilesList(ext:String; pattern:String; NoEmptyFiles:Boolean):TStringList;
75 VAR
76 i:LongWord;
77 where:String;
78 Tbl:TSQLiteTable;
79 BEGIN
80 SetLength(Result,0);
81 IF opened_state=opened_dat THEN BEGIN
82 FOR i:=0 TO dat_header.Files-1 DO BEGIN
83 IF ( (Length(ext)=0) OR (dat_files[i].Extension=ext) ) AND
84 ( (Length(pattern)=0) OR (Pos(pattern,dat_files[i].Name)>0) ) THEN BEGIN
85 IF NoEmptyFiles THEN BEGIN
86 IF (dat_files[i].FileType AND $02)=0 THEN BEGIN
87 SetLength(Result,Length(Result)+1);
88 Result[High(Result)]:=dat_files[i].FileName;
89 END;
90 END ELSE BEGIN
91 SetLength(Result,Length(Result)+1);
92 Result[High(Result)]:=dat_files[i].FileName;
93 END;
94 END;
95 END;
96 END ELSE BEGIN
97 where:='';
98 IF Length(ext)>0 THEN BEGIN
99 IF Length(where)>0 THEN where:=where+' AND ';
100 where:=where+'(extension="'+ext+'")';
101 END;
102 IF Length(pattern)>0 THEN BEGIN
103 IF Length(where)>0 THEN where:=where+' AND ';
104 where:=where+'(name LIKE "%'+pattern+'%")';
105 END;
106 IF NoEmptyFiles THEN BEGIN
107 IF Length(where)>0 THEN where:=where+' AND ';
108 where:=where+'((contenttype & 2)=0)';
109 END;
110 IF Length(where)>0 THEN where:=' WHERE '+where;
111 Tbl:=DB.GetTable('SELECT id,name,extension FROM datfiles'+where+' ORDER BY id ASC;');
112 IF Tbl.Count>0 THEN BEGIN
113 SetLength(Result,Tbl.Count);
114 i:=0;
115 REPEAT
116 Result[i]:=FormatNumber(Tbl.FieldAsInteger('id'),5,'0')+'-'+Tbl.FieldAsString('name')+'.'+Tbl.FieldAsString('extension');
117 Inc(i);
118 Tbl.Next;
119 UNTIL Tbl.EOF;
120 END;
121 END;
122 END;
123
124FUNCTION GetExtensionsList:TStringList;
125 VAR
126 i:LongWord;
127 Tbl:TSQLiteTable;
128 BEGIN
129 SetLength(Result,0);
130 IF opened_state=opened_dat THEN BEGIN
131 FOR i:=0 TO dat_header.Extensions-1 DO BEGIN
132 SetLength(Result,Length(Result)+1);
133 WITH dat_extensionsmap[i] DO BEGIN
134 Result[High(Result)]:=Extension[3]+Extension[2]+Extension[1]+Extension[0]+' ('+IntToStr(ExtCount)+')';
135 END;
136 END;
137 END ELSE BEGIN
138 Tbl:=DB.GetTable('SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;');
139 IF Tbl.Count>0 THEN BEGIN
140 SetLength(Result,Tbl.Count);
141 i:=0;
142 REPEAT
143 Result[i]:=Tbl.FieldAsString('extension')+' ('+IntToStr(Tbl.FieldAsInteger('x'))+')';
144 Inc(i);
145 Tbl.Next;
146 UNTIL Tbl.EOF;
147 END;
148 END;
149 END;
150
151FUNCTION LoadDatInfos(filename:String):Boolean;
152 VAR i:LongWord;
153 dat_file:TFileStream;
154 BEGIN
155 Result:=True;
156 opened_state:=opened_dat;
157 dat_filename:=filename;
158 raw_filename:=MidStr(filename,1,Length(filename)-3)+'raw';
159 dat_file:=TFileStream.Create(filename, fmOpenRead);
160 dat_file.Read(dat_header,SizeOf(dat_header));
161 FOR i:=0 TO High(dat_header.Ident) DO
162 IF dat_header.Ident[i]<>header_ident1[i] THEN BEGIN
163 Result:=False;
164 Exit;
165 END;
166 SetLength(dat_filesmap,dat_header.Files);
167 SetLength(dat_files,dat_header.Files);
168 FOR i:=0 TO dat_header.Files-1 DO dat_file.Read(dat_filesmap[i],SizeOf(dat_filesmap[i]));
169 FOR i:=0 TO dat_header.Files-1 DO BEGIN
170 dat_files[i].Extension:=dat_filesmap[i].Extension;
171 dat_files[i].Extension:=ReverseString(dat_files[i].Extension);
172 dat_files[i].Size:=dat_filesmap[i].FileSize;
173 dat_files[i].FileType:=dat_filesmap[i].FileType;
174 dat_files[i].DatAddr:=dat_filesmap[i].DataAddr-8+dat_header.DataAddr;
175 IF (dat_filesmap[i].FileType AND $01)=0 THEN BEGIN
176 dat_file.Seek(dat_filesmap[i].NameAddr+dat_header.NamesAddr,soFromBeginning);
177 SetLength(dat_files[i].Name,100);
178 dat_file.Read(dat_files[i].Name[1],100);
179 dat_files[i].Name:=MidStr(dat_files[i].Name,1+4,Pos(#0,dat_files[i].Name)-1-4);
180 END ELSE BEGIN
181 dat_files[i].Name:='';
182 END;
183 dat_files[i].FileName:=FormatNumber(i,5,'0')+'-'+dat_files[i].Name+'.'+dat_files[i].Extension;
184 END;
185 dat_file.Seek($40+dat_header.Files*$14,soFromBeginning);
186 SetLength(dat_namedfilesmap,dat_header.NamedFiles);
187 FOR i:=0 TO dat_header.NamedFiles-1 DO dat_file.Read(dat_namedfilesmap[i],SizeOf(dat_namedfilesmap[i]));
188
189 dat_file.Seek($40+dat_header.Files*$14+dat_header.NamedFiles*$8,soFromBeginning);
190 SetLength(dat_extensionsmap,dat_header.Extensions);
191 FOR i:=0 TO dat_header.Extensions-1 DO dat_file.Read(dat_extensionsmap[i],SizeOf(dat_extensionsmap[i]));
192
193 dat_file.Free;
194 END;
195
196
197FUNCTION LoadDatFile(fileid:LongWord):Tdata;
198 VAR
199 dat_file:TFileStream;
200 Tbl:TSQLiteTable;
201 mem:TMemoryStream;
202 BEGIN
203 IF opened_state=opened_dat THEN BEGIN
204 dat_file:=TFileStream.Create(dat_filename, fmOpenRead);
205 dat_file.Seek(dat_files[fileid].DatAddr,soFromBeginning);
206 SetLength(Result,dat_files[fileid].Size);
207 dat_file.Read(Result[0],dat_files[fileid].Size);
208 dat_file.Free;
209 END ELSE BEGIN
210 Tbl:=DB.GetTable('SELECT data FROM datfiles WHERE id='+IntToStr(fileid)+';');
211 IF Tbl.Count>0 THEN BEGIN
212 mem:=Tbl.FieldAsBlob('data');
213 SetLength(Result,mem.Size);
214 mem.Seek(0,soFromBeginning);
215 mem.Read(Result[0],mem.Size);
216 mem.Free;
217 END;
218 END;
219 END;
220PROCEDURE UpdateDatFile(fileid:LongWord; data:Tdata);
221 VAR
222 dat_file:TFileStream;
223 Tbl:TSQLiteTable;
224 BEGIN
225 IF opened_state=opened_dat THEN BEGIN
226 dat_file:=TFileStream.Create(dat_filename, fmOpenReadWrite);
227 dat_file.Seek(dat_files[fileid].DatAddr,soFromBeginning);
228 dat_file.Write(data[0],Length(data));
229 dat_file.Free;
230 END ELSE BEGIN
231 END;
232 END;
233
234FUNCTION LoadDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
235 VAR
236 dat_file:TFileStream;
237 Tbl:TSQLiteTable;
238 mem:TMemoryStream;
239 BEGIN
240 Result:=False;
241 IF opened_state=opened_dat THEN BEGIN
242 dat_file:=TFileStream.Create(dat_filename, fmOpenRead);
243 Result:=True;
244 dat_file.Seek(dat_files[fileid].DatAddr+offset,soFromBeginning);
245 dat_file.Read(target^,size);
246 dat_file.Free;
247 END ELSE BEGIN
248 Tbl:=DB.GetTable('SELECT data FROM datfiles WHERE id='+IntToStr(fileid)+';');
249 IF Tbl.Count>0 THEN BEGIN
250 Result:=True;
251 mem:=Tbl.FieldAsBlob('data');
252 mem.Seek(offset,soFromBeginning);
253 mem.Read(target^,size);
254 mem.Free;
255 END;
256 END;
257 END;
258FUNCTION UpdateDatFilePart(fileid,offset,size:LongWord; target:Pointer):Boolean;
259 VAR
260 dat_file:TFileStream;
261 Tbl:TSQLiteTable;
262 BEGIN
263 Result:=False;
264 IF opened_state=opened_dat THEN BEGIN
265 dat_file:=TFileStream.Create(dat_filename, fmOpenReadWrite);
266 Result:=True;
267 dat_file.Seek(dat_files[fileid].DatAddr+offset,soFromBeginning);
268 dat_file.Write(target^,size);
269 dat_file.Free;
270 END ELSE BEGIN
271 END;
272 END;
273
274FUNCTION LoadRawFile(fileid,datlinkoffset,size:LongWord; target:Pointer):Boolean;
275 VAR
276 filestream:TFileStream;
277 raw_addr:LongWord;
278 Tbl:TSQLiteTable;
279 mem:TMemoryStream;
280 BEGIN
281 Result:=False;
282 IF opened_state=opened_dat THEN BEGIN
283 Result:=True;
284 LoadDatFilePart(fileid,datlinkoffset,4,@raw_addr);
285 filestream:=TFileStream.Create(AnsiReplaceStr(dat_filename,'.dat','.raw'),fmOpenRead);
286 filestream.Seek(raw_addr,soFromBeginning);
287 filestream.Read(target^,size);
288 filestream.Free;
289 END ELSE BEGIN
290 Tbl:=DB.GetTable('SELECT data FROM rawmap WHERE (src_id='+IntToStr(fileid)+') AND (src_link_offset='+IntToStr(datlinkoffset)+');');
291 IF Tbl.Count>0 THEN BEGIN
292 Result:=True;
293 mem:=Tbl.FieldAsBlob('data');
294 mem.Seek(0,soFromBeginning);
295 mem.Read(target^,size);
296 mem.Free;
297 END;
298 END;
299 END;
300FUNCTION UpdateRawFile(fileid,datlinkoffset,size:LongWord; target:Pointer):Boolean;
301 VAR
302 filestream:TFileStream;
303 raw_addr:LongWord;
304 BEGIN
305 Result:=False;
306 IF opened_state=opened_dat THEN BEGIN
307 Result:=True;
308 LoadDatFilePart(fileid,datlinkoffset,4,@raw_addr);
309 filestream:=TFileStream.Create(AnsiReplaceStr(dat_filename,'.dat','.raw'),fmOpenReadWrite);
310 filestream.Seek(raw_addr,soFromBeginning);
311 filestream.Write(target^,size);
312 filestream.Free;
313 END ELSE BEGIN
314 END;
315 END;
316
317
318FUNCTION FormatNumber(value:LongWord; width:Byte; leadingzeros:Char):String;
319 BEGIN
320 Result:=AnsiReplaceStr(Format('%'+IntToStr(width)+'u',[value]),' ',leadingzeros);
321 END;
322
323FUNCTION FormatFileSize(size:LongWord):String;
324 BEGIN
325 IF size>=1000*1024*1024 THEN BEGIN
326 Result:=FloatToStrF(size/1024/1024/1024,ffFixed,5,1)+' GB';
327 END ELSE BEGIN
328 IF size>=1000*1024 THEN BEGIN
329 Result:=FloatToStrF(size/1024/1024,ffFixed,5,1)+' MB';
330 END ELSE BEGIN
331 IF size>=1000 THEN BEGIN
332 Result:=FloatToStrF(size/1024,ffFixed,5,1)+' KB';
333 END ELSE BEGIN
334 Result:=IntToStr(size)+' B';
335 END;
336 END;
337 END;
338 END;
339
340FUNCTION CreateHexString(data:Tdata; HexOnly:Boolean):String;
341 VAR
342 string_build,ascii_version:String;
343 i:LongWord;
344 BEGIN
345 string_build:='';
346 ascii_version:='';
347 FOR i:=0 TO High(data) DO BEGIN
348 IF NOT HexOnly THEN
349 IF (i MOD 16)=0 THEN
350 string_build:=string_build+'0x'+IntToHex(i,6)+' ';
351 string_build:=string_build+IntToHex(data[i],2);
352 IF NOT HexOnly THEN BEGIN
353 IF data[i]>=32 THEN ascii_version:=ascii_version+Chr(data[i])
354 ELSE ascii_version:=ascii_version+'.';
355 IF ((i+1) MOD 2)=0 THEN string_build:=string_build+#32;
356 IF ((i+1) MOD 16)=0 THEN BEGIN
357 string_build:=string_build+#32+ascii_version+CrLf;
358 ascii_version:='';
359 END;
360 END;
361 END;
362 Result:=string_build;
363 END;
364
365
366FUNCTION ExportFile(fileid:LongWord; filename:String; settings:TExportSet; path:String):Integer;
367 VAR
368 i:Byte;
369 extension:String;
370 BEGIN
371 Result:=export_noerror;
372 extension:=RightStr(filename,4);
373 IF DO_toone IN settings THEN BEGIN
374 ExportDatFile(fileid,path+'\'+GetWinFileName(filename));
375 END ELSE BEGIN
376 IF DO_dat IN settings THEN ExportDatFile(fileid,path+'\'+GetWinFileName(filename));
377 IF DO_raw IN settings THEN BEGIN
378 FOR i:=1 TO Length(ExportHandlers)+1 DO BEGIN
379 IF i<=Length(ExportHandlers) THEN BEGIN
380 IF ExportHandlers[i].Ext=extension THEN BEGIN
381 IF ExportHandlers[i].needed THEN BEGIN
382 CASE ExportHandlers[i].Handler(fileid,path+'\'+GetWinFileName(filename),(DO_convert IN settings)) OF
383 0: Result:=0;
384 ELSE
385 Result:=export_handlererror;
386 END;
387 END;
388 Break;
389 END;
390 END ELSE BEGIN
391 Result:=export_nohandler;
392 END;
393 END;
394 END;
395 END;
396 END;
397
398
399FUNCTION GetWinFileName(name:String):String;
400 BEGIN
401 Result:=name;
402 Result:=AnsiReplaceStr(Result,'\','__');
403 Result:=AnsiReplaceStr(Result,'/','__');
404 Result:=AnsiReplaceStr(Result,'>','__');
405 Result:=AnsiReplaceStr(Result,'<','__');
406 END;
407
408FUNCTION GetExtractPath:String;
409 BEGIN
410 Result:=ExtractFilePath(dat_filename)+'\extracted_'+ExtractFileName(dat_filename);
411 END;
412
413
414PROCEDURE OpenDatabase(FileName:String);
415 VAR
416 i:Byte;
417 data:Tdata;
418 temps:String;
419 Tbl: TSQLiteTable;
420 BEGIN
421 IF NOT FileExists(FileName) THEN BEGIN
422 ShowMessage('File doesn''t exist!!!');
423 Exit;
424 END;
425 DB:=TSQLiteDatabase.Create(FileName);
426 Tbl:=DB.GetTable('SELECT name,value FROM globals ORDER BY name ASC');
427 REPEAT
428 IF Tbl.FieldAsString('name')='dbversion' THEN BEGIN
429 IF Tbl.FieldAsString('value')<>DBversion THEN BEGIN
430 ShowMessage('Database-file '+CrLf+'"'+FileName+'"'+CrLf+'has wrong version. (Required: '+DBversion+'; found: '+Tbl.FieldAsString('value')+')');
431 Exit;
432 END;
433 END;
434 IF Tbl.FieldAsString('name')='lvl' THEN BEGIN
435 database_level:=StrToInt(Tbl.FieldAsString('value'));
436 END;
437 IF Tbl.FieldAsString('name')='ident' THEN BEGIN
438 temps:=Tbl.FieldAsString('value');
439 FOR i:=0 TO High(database_ident) DO BEGIN
440 CASE temps[(i*2)+1+0] OF
441 '0'..'9': database_ident[i]:=Ord(temps[(i*2)+1+0])-48;
442 'A'..'F': database_ident[i]:=Ord(temps[(i*2)+1+0])-55;
443 END;
444 database_ident[i]:=database_ident[i]*16;
445 CASE temps[(i*2)+1+1] OF
446 '0'..'9': database_ident[i]:=database_ident[i]+Ord(temps[(i*2)+1+0])-48;
447 'A'..'F': database_ident[i]:=database_ident[i]+Ord(temps[(i*2)+1+0])-55;
448 END;
449 END;
450 END;
451 Tbl.Next;
452 UNTIL Tbl.EOF;
453 Tbl.Free;
454 opened_state:=opened_db;
455 END;
456
457
458
459
460END.
Note: See TracBrowser for help on using the repository browser.