--- oup/rewrite/Helper/Helper_LevelDB.pas 2007/01/18 17:15:59 93 +++ oup/current/Helper/LevelDB.pas 2007/03/28 01:41:10 132 @@ -1,7 +1,5 @@ -unit Helper_LevelDB; - +unit LevelDB; interface - uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, StrUtils; @@ -15,11 +13,11 @@ type lbl_estimation: TLabel; procedure btn_abortokClick(Sender: TObject); private - procedure HandleFile(ext: String; fileid: LongWord; dir_dat2db: Boolean); - procedure stop_convert; + procedure HandleFile(Ext: String; FileID: Integer); + procedure StopConvert; public - procedure CreateDatabase(Source, target: String); - procedure CreateLevel(Source, target: String); + procedure CreateDatabase(Source, Target: String); + procedure CreateLevel(Source, Target: String); end; @@ -27,73 +25,84 @@ var Form_LevelDB: TForm_LevelDB; implementation - {$R *.dfm} - -uses ABSMain, ABSDecUtil, Main, Functions, Data, - OniImgClass, DataStructures, OniDataClass; +uses ABSMain, ABSDecUtil, Main, + ConnectionManager, TypeDefs, DataAccess, OniImgClass, Data; type - THandler = procedure(fileid: LongWord; dir_dat2db: Boolean); - - TConvertHandlers = record + THandler = procedure(FileID: Integer); + TConvertHandler = record Ext: String[4]; - needed: Boolean; Handler: THandler; end; var - ConvertHandlers: array of TConvertHandlers; - loaded_filename: String; - converting: Boolean = False; - abort: Boolean = False; - DataBase: TABSDatabase; - Query: TABSQuery; - MimeCoder: TStringFormat_MIME64; - -var - DatHeader: THeader; - FilesHeader: TFilesMap; - NamedFilesHeader: TNamedFilesMap; - ExtensionsHeader: TExtensionsMap; - Stream_Body, Stream_Names: TMemoryStream; - Stream_Dat, Stream_Raw, Stream_Sep: TFileStream; - OniDataConnection: TOniData; + ConvertHandlers: array of TConvertHandler; +// loaded_filename: String; + Converting: Boolean = False; + Abort: Boolean = False; +function GetOpenMsg(msg: TStatusMessages): String; +begin + case msg of + SM_AlreadyOpened: Result := 'File already opened.'; + SM_FileNotFound: Result := 'File not found.'; + SM_UnknownExtension: Result := 'Unknown extension.'; + SM_IncompatibleFile: Result := 'Incompatible file format.'; + SM_UnknownError: Result := 'Unknown error.'; + end; +end; -procedure TForm_LevelDB.CreateLevel(Source, target: String); +procedure TForm_LevelDB.CreateLevel(Source, Target: String); var - files: LongWord; + DatHeader: THeader; + FilesHeader: TFilesMap; + NamedFilesHeader: TNamedFilesMap; + ExtensionsHeader: TExtensionsMap; - i, j: LongWord; - temps, temps2: String; - Data, rawdata: Tdata; - absolutebegintime, begintime: Double; - step: Byte; - rawlist: TRawList; - extlist: TExtensionsMap; - fileinfo: TFileInfo; - datlinks: TDatLinks; - OniImage: TOniImage; - levelid: LongWord; - timeformat: TFormatSettings; + Stream_Body, Stream_Names: TMemoryStream; + Stream_Dat, Stream_Raw, Stream_Sep: TFileStream; - conIndex: Integer; - connection: TOniData; + BeginTime, FileTime: Double; + Step: Integer; + OniImage: TOniImage; + LevelID: Integer; + TimeFormat: TFormatSettings; + + ConID: Integer; + Connection: TDataAccess; + ConRepMsg: TStatusMessages; + + FileID: Integer; + + Strings: TStrings; + i, j: Integer; + temps: String; + tempi: Integer; + tempb: Byte; + FileInfo: TFileInfo; + DatLinks: TDatLinkList; + RawLinks: TRawDataList; + + DatFileStream, RawFileStream: TMemoryStream; + +// ########################### + datsum, linksum, rawsum: Int64; + freq: Int64; + tempticks1, tempticks2: Int64; +// ########################### const - steps: Byte = 3; - + Steps: Byte = 3; - - procedure DoStep(stepname: String); + procedure DoStep(StepName: String); begin - Inc(step); - if stepname <> 'FIN' then + Inc(Step); + if StepName <> 'FIN' then group_progress.Caption := - 'Creating Dat (Step ' + IntToStr(step) + '/' + IntToStr(steps) + ': ' + stepname + ')' + 'Creating Dat (Step ' + IntToStr(Step) + '/' + IntToStr(Steps) + ': ' + StepName + ')' else group_progress.Caption := 'Creating Dat (FINISHED)'; end; @@ -104,51 +113,86 @@ begin // FILE EXISTS CHECK FÜR DAT/RAW/SEP!!! // - timeformat.ShortTimeFormat := 'hh:nn:ss'; - timeformat.LongTimeFormat := 'hh:nn:ss'; - timeformat.TimeSeparator := ':'; + TimeFormat.ShortTimeFormat := 'hh:nn:ss'; + TimeFormat.LongTimeFormat := 'hh:nn:ss'; + TimeFormat.TimeSeparator := ':'; - connection := ConnectionExists(target); - if connection <> nil then + ConID := ConManager.OpenConnection(Source, ConRepMsg); + if not (ConRepMsg in [SM_OK, SM_AlreadyOpened]) then begin - ShowMessage('Destination-file is opened, close it in order to proceed conversion?'); + ShowMessage('Source-file couldn''t be opened! Aborting' + CrLf + GetOpenMsg(ConRepMsg)); Exit; - end; + end else + Connection := ConManager.Connection[ConID]; - connection := ConnectionExists(source); - if connection <> nil then + ConID := ConManager.FileOpened(Target); + if ConID >= 0 then begin - ShowMessage('Source-file is opened, close it in order to proceed conversion?'); - Exit; + if MessageBox(Self.Handle, PChar('Destination-file is opened, close it in ' + + 'order to proceed conversion?'), PChar('Destination-file opened'), + MB_YESNO + MB_ICONQUESTION) = ID_YES then + begin + if Form_Main.CheckConnectionCloseable(ConID) then + if not ConManager.CloseConnection(ConID, ConRepMsg) then + begin + ShowMessage('Couldn''t close destination-file. Aborting'); + Exit; + end; + end else begin + ShowMessage('Aborting'); + Exit; + end; end; - - if CreateDataConnection(Source, ODB_ADB) = nil then + if FileExists(Target) then begin - ShowMessage('Could not connect to .oldb-file'); - Exit; + if MessageBox(Self.Handle, PChar('Destination-file exists. ' + + 'Overwrite it?'), PChar('Destination-file exists'), + MB_YESNO + MB_ICONWARNING) = ID_YES then + begin + if not DeleteFile(Target) then + begin + ShowMessage('Couldn''t delete file. Aborting'); + Exit; + end; + if FileExists(AnsiReplaceStr(Target, '.dat', '.raw')) then + if not DeleteFile(AnsiReplaceStr(Target, '.dat', '.raw')) then + begin + ShowMessage('Couldn''t delete file. Aborting'); + Exit; + end; + if FileExists(AnsiReplaceStr(Target, '.dat', '.sep')) then + if Connection.DataOS in [DOS_WINDEMO, DOS_MAC, DOS_MACBETA] then + if not DeleteFile(AnsiReplaceStr(Target, '.dat', '.sep')) then + begin + ShowMessage('Couldn''t delete file. Aborting'); + Exit; + end; + end else begin + ShowMessage('Aborting'); + Exit; + end; end; - levelid := OniDataConnection.LevelInfo.LevelNumber; - levelid := (levelid * 2) * 256 * 256 * 256 + $01; - OniImage := TOniImage.Create; - absolutebegintime := Time; + LevelID := Connection.LevelNumber; + LevelID := (LevelID * 2) * 256 * 256 * 256 + $01; + OniImage := TOniImage.Create; Self.Visible := True; Form_Main.Visible := False; - step := 0; - converting := True; - abort := False; + Step := 0; + Converting := True; + Abort := False; btn_abortok.Caption := '&Abort...'; btn_abortok.Default := False; - absolutebegintime := Time; + BeginTime := Time; Stream_Body := TMemoryStream.Create; Stream_Names := TMemoryStream.Create; - Stream_Dat := TFileStream.Create(target, fmCreate); - Stream_Raw := TFileStream.Create(AnsiReplaceStr(target, '.dat', '.raw'), fmCreate); - if OniDataConnection.OSisMac then - Stream_Sep := TFileStream.Create(AnsiReplaceStr(target, '.dat', '.sep'), fmCreate); + Stream_Dat := TFileStream.Create(Target, fmCreate); + Stream_Raw := TFileStream.Create(AnsiReplaceStr(Target, '.dat', '.raw'), fmCreate); + if Connection.DataOS in [DOS_WINDEMO, DOS_MAC, DOS_MACBETA] then + Stream_Sep := TFileStream.Create(AnsiReplaceStr(Target, '.dat', '.sep'), fmCreate); DoStep('Creating header'); progress.Position := 0; @@ -156,13 +200,38 @@ begin lbl_estimation.Caption := 'Estimated finishing time: unknown'; Application.ProcessMessages; - NamedFilesHeader := TOniDataADB(OniDataConnection).GetNamedFilesMap; - extlist := OniDataConnection.GetExtendedExtensionsList; - for i := 0 to High(DatHeader.Ident) do - DatHeader.Ident[i] := OniDataConnection.LevelInfo.Ident[i]; - DatHeader.Files := OniDataConnection.GetFilesCount; + SetLength(NamedFilesHeader, 0); + Strings := TStringList.Create; + Strings := Connection.GetFilesList('', '', False, ST_ExtNameAsc); + for i := 0 to Strings.Count - 1 do + begin + if MidStr(Strings.Strings[i], + Pos('-', Strings.Strings[i]) + 1, + Length(Strings.Strings[i]) - + Pos('.', ReverseString(Strings.Strings[i])) - + Pos('-', Strings.Strings[i]) + ) <> '' then + begin + SetLength(NamedFilesHeader, Length(NamedFilesHeader) + 1); + NamedFilesHeader[High(NamedFilesHeader)].FileNumber := StrToInt(MidStr(Strings.Strings[i], 1, 5)); + NamedFilesHeader[High(NamedFilesHeader)].blubb := 0; + end; + end; + + for i := 0 to High(DatHeader.OSIdent) do + case Connection.DataOS of + DOS_WIN: DatHeader.OSIdent[i] := HeaderOSIdentWin[i]; + DOS_MAC: DatHeader.OSIdent[i] := HeaderOSIdentMac[i]; + DOS_MACBETA: DatHeader.OSIdent[i] := HeaderOSIdentMacBeta[i]; + end; + for i := 0 to High(DatHeader.GlobalIdent) do + DatHeader.GlobalIdent[i] := HeaderGlobalIdent[i]; + DatHeader.Files := Connection.GetFileCount; DatHeader.NamedFiles := Length(NamedFilesHeader); - DatHeader.Extensions := Length(extlist); + + Strings := Connection.GetExtensionsList(EF_ExtCount); + + DatHeader.Extensions := Strings.Count; DatHeader.DataAddr := 0; DatHeader.DataSize := 0; DatHeader.NamesAddr := 0; @@ -172,22 +241,38 @@ begin SetLength(FilesHeader, DatHeader.Files); SetLength(ExtensionsHeader, DatHeader.Extensions); + DoStep('Writing extensions-header'); - progress.Max := Length(OniDataConnection.GetExtensionsList); + progress.Max := Strings.Count; Application.ProcessMessages; - - for i := 0 to High(ExtensionsHeader) do + for i := 0 to Strings.Count - 1 do begin - ExtensionsHeader[i].Ident := extlist[i].Ident; - ExtensionsHeader[i].Extension := extlist[i].Extension; - SetLength(temps, 4); + temps := Strings.Strings[i]; + ExtensionsHeader[i].ExtCount := StrToInt( MidStr( + temps, + Pos('(', temps) + 1, + Pos(')', temps) - Pos('(', temps) - 1 ) ); + temps := MidStr(temps, 1, 4); for j := 0 to 3 do - temps[j + 1] := ExtensionsHeader[i].Extension[3 - j]; - ExtensionsHeader[i].ExtCount := - Length(OniDataConnection.GetFilesList(temps, '', False, stIDAsc)); + ExtensionsHeader[i].Extension[j] := temps[4-j]; + for j := 0 to High(FileTypes) do + if FileTypes[j].Extension = temps then + Break; + if j < Length(FileTypes) then + begin + case Connection.DataOS of + DOS_WIN: ExtensionsHeader[i].Ident := FileTypes[j].IdentWin; + DOS_WINDEMO: ExtensionsHeader[i].Ident := FileTypes[j].IdentMac; + DOS_MAC: ExtensionsHeader[i].Ident := FileTypes[j].IdentMac; + DOS_MACBETA: ExtensionsHeader[i].Ident := FileTypes[j].IdentMac; + end; + end else begin + ShowMessage('Unknown Extension: ' + Strings.Strings[i]); + Exit; + end; progress.Position := i + 1; lbl_progress.Caption := 'Extensions done: ' + IntToStr(i + 1) + '/' + - IntToStr(Length(extlist)); + IntToStr(Strings.Count); Application.ProcessMessages; end; @@ -198,74 +283,76 @@ begin lbl_estimation.Caption := 'Estimated finishing time: unknown'; Application.ProcessMessages; - begintime := Time; - for i := 0 to DatHeader.Files - 1 do + QueryPerformanceFrequency(freq); + datsum := 0; + linksum := 0; + rawsum := 0; + + FileTime := Time; + for FileID := 0 to DatHeader.Files - 1 do begin - fileinfo := OniDataConnection.GetFileInfo(i); + FileInfo := Connection.GetFileInfo(FileID); for j := 0 to 3 do - FilesHeader[i].Extension[j] := fileinfo.Extension[4 - j]; - if fileinfo.Size > 0 then + FilesHeader[FileID].Extension[j] := FileInfo.Extension[4 - j]; + if FileInfo.Size > 0 then begin - // DatLinks:=; - FilesHeader[i].DataAddr := Stream_Body.Size + 8; - Data := OniDataConnection.LoadDatFile(i); - Data[4] := (levelid) and $FF; - Data[5] := (levelid shr 8) and $FF; - Data[6] := (levelid shr 16) and $FF; - Data[7] := (levelid shr 24) and $FF; + QueryPerformanceCounter(tempticks1); + + FilesHeader[FileID].DataAddr := Stream_Body.Size + 8; + DatFileStream := TMemoryStream.Create; + Connection.LoadDatFile(FileID, TStream(DatFileStream)); + DatFileStream.Seek(4, soFromBeginning); + DatFileStream.Write(LevelID, 4); + + QueryPerformanceCounter(tempticks2); + datsum := datsum + (tempticks2 - tempticks1); - if (Pos(UpperCase(fileinfo.Extension), UpperCase(raws)) mod 4) = 1 then + DatLinks := Connection.GetDatLinks(FileID); + if Length(DatLinks) > 0 then begin - rawlist := OniDataConnection.GetRawList(i); - if Length(rawlist) > 0 then + for i := 0 to High(DatLinks) do begin - for j := 0 to High(rawlist) do + DatFileStream.Seek(DatLinks[i].SrcOffset, soFromBeginning); + if DatLinks[i].DestID < 0 then + tempi := 0 + else + tempi := DatLinks[i].DestID * 256 + 1; + DatFileStream.Write(tempi, 4); + end; + end; + + QueryPerformanceCounter(tempticks1); + linksum := linksum + (tempticks1 - tempticks2); + + RawLinks := Connection.GetRawList(FileID); + if Length(RawLinks) > 0 then + begin + for i := 0 to High(RawLinks) do + begin + if RawLinks[i].RawSize > 0 then begin - if rawlist[j].raw_size > 0 then + RawFileStream := TMemoryStream.Create; + Connection.LoadRawFile(FileID, RawLinks[i].SrcOffset, TStream(RawFileStream)); + RawFileStream.Seek(0, soFromBeginning); + if RawLinks[i].LocSep then begin - if (UpperCase(fileinfo.Extension) = 'TXMP') and - ((Data[$88] and $01) > 0) then - begin - OniImage.LoadFromTXMP(Connection, i); - OniImage.GetMipMappedImage(rawdata); - rawlist[j].raw_size := OniImage.GetImageDataSize(True); - Data[$90] := $08; - Data[$89] := 32; -{ if data[$90]<>OniImage.StoreType then begin - data[$90]:=OniImage.StoreType; - data[$89]:=(data[$89] and $CF) or $20; - end; -} end - else - begin - SetLength(rawdata, rawlist[j].raw_size); - OniDataConnection.LoadRawFile(i, rawlist[j].src_offset, @rawdata[0]); - end; - // data[$88]:=data[$88] and $FE; - - if rawlist[j].loc_sep then - begin - rawlist[j].raw_addr := Stream_Sep.Size; - Stream_Sep.Write(rawdata[0], Length(rawdata)); - end - else - begin - rawlist[j].raw_addr := Stream_Raw.Size; - Stream_Raw.Write(rawdata[0], Length(rawdata)); - end; - end - else - rawlist[j].raw_addr := 0; - Data[rawlist[j].src_offset + 0] := (rawlist[j].raw_addr) and $FF; - Data[rawlist[j].src_offset + 1] := (rawlist[j].raw_addr shr 8) and $FF; - Data[rawlist[j].src_offset + 2] := (rawlist[j].raw_addr shr 16) and $FF; - Data[rawlist[j].src_offset + 3] := (rawlist[j].raw_addr shr 24) and $FF; - end; + RawLinks[i].RawAddr := Stream_Sep.Size; + Stream_sep.CopyFrom(RawFileStream, RawFileStream.Size); + end else begin + RawLinks[i].RawAddr := Stream_Raw.Size; + Stream_Raw.CopyFrom(RawFileStream, RawFileStream.Size); + end; + end else + RawLinks[i].RawAddr := 0; + DatFileStream.Seek(RawLinks[i].SrcOffset, soFromBeginning); + DatFileStream.Write(RawLinks[i].RawAddr, 4); end; end; + DatFileStream.Seek(0, soFromBeginning); + Stream_Body.CopyFrom(DatFileStream, DatFileStream.Size); - Stream_Body.Write(Data[0], Length(Data)); - // + QueryPerformanceCounter(tempticks2); + rawsum := rawsum + (tempticks2 - tempticks1); end else FilesHeader[i].DataAddr := 0; @@ -280,14 +367,19 @@ begin FilesHeader[i].FileSize := fileinfo.Size; FilesHeader[i].FileType := fileinfo.FileType; - if ((i mod 10) = 0) and (i >= 100) then + if ((FileID mod 10) = 0) and (FileID >= 100) then lbl_estimation.Caption := 'Estimated time left: ' + TimeToStr( - (Time - begintime) / i * (progress.Max - i + 1) * 1.1, timeformat ); - progress.Position := i + 1; - lbl_progress.Caption := 'Files done: ' + IntToStr(i + 1) + '/' + IntToStr(progress.Max); + (Time - FileTime) / FileID * (progress.Max - FileID + 1) * 1.1, TimeFormat ); + progress.Position := FileID + 1; + lbl_progress.Caption := 'Files done: ' + IntToStr(FileID + 1) + '/' + IntToStr(progress.Max); Application.ProcessMessages; end; + ShowMessage('AvgDats: ' + FloatToStr((datsum / progress.Max) / freq) + #13#10 + + 'AvgLinks: ' + FloatToStr((linksum / progress.Max) / freq) + #13#10 + + 'AvgRaws: ' + FloatToStr((rawsum / progress.Max) / freq) + ); + Stream_Dat.Write(DatHeader, SizeOf(DatHeader)); for i := 0 to High(FilesHeader) do Stream_Dat.Write(FilesHeader[i], SizeOf(FilesHeader[i])); @@ -312,13 +404,14 @@ begin Stream_Body.Free; Stream_Names.Free; Stream_Raw.Free; - if OniDataConnection.OSisMac then + + if Connection.DataOS in [DOS_WINDEMO, DOS_MAC, DOS_MACBETA] then Stream_Sep.Free; progress.Position := progress.Max; lbl_progress.Caption := 'Files done: ' + IntToStr(progress.Max) + '/' + IntToStr(progress.Max); - lbl_estimation.Caption := 'FINISHED (duration: ' + TimeToStr(Time - absolutebegintime, timeformat) + ')'; + lbl_estimation.Caption := 'FINISHED (duration: ' + TimeToStr(Time - Begintime, TimeFormat) + ')'; DoStep('FIN'); btn_abortok.Caption := '&OK'; @@ -328,7 +421,7 @@ begin converting := False; - CloseDataConnection(DataConnections[conIndex]); +// CloseDataConnection(DataConnections[conIndex]); end; @@ -338,7 +431,7 @@ procedure TForm_LevelDB.HandleFile; var i: Byte; begin - for i := 1 to Length(ConvertHandlers) do +{ for i := 1 to Length(ConvertHandlers) do if UpperCase(ConvertHandlers[i].Ext) = UpperCase(ext) then if ConvertHandlers[i].needed then begin @@ -347,13 +440,18 @@ begin end else Break; -end; +}end; procedure TForm_LevelDB.CreateDatabase(Source, target: String); +{ var + DataBase: TABSDatabase; + Query: TABSQuery; + MimeCoder: TStringFormat_MIME64; + i, j: LongWord; temps, temps2: String; Data: Tdata; @@ -380,9 +478,10 @@ const else group_progress.Caption := 'Creating DB (FINISHED)'; end; +} begin - if CreateDataConnection(Source, ODB_Dat) = nil then +{ if CreateDataConnection(Source, ODB_Dat) = nil then begin ShowMessage('Could not connect to .dat-file'); Exit; @@ -585,14 +684,15 @@ begin database.Free; CloseDataConnection(DataConnections[conIndex]); +} end; -procedure TForm_LevelDB.stop_convert; +procedure TForm_LevelDB.StopConvert; begin - btn_abortok.Caption := '&Close'; +{ btn_abortok.Caption := '&Close'; btn_abortok.Default := True; converting := False; lbl_estimation.Caption := 'ABORTED'; @@ -603,7 +703,7 @@ begin begin DeleteFile(loaded_filename); end; -end; +}end; @@ -626,7 +726,7 @@ end; - +{ procedure InsertDatLinkToDB(fileid: LongWord; offset: LongWord); var link: LongWord; @@ -1658,10 +1758,10 @@ begin begin end; end; +} - - +{ procedure InsertHandler(ext: String; needed: Boolean; handler: THandler); begin SetLength(ConvertHandlers, Length(ConvertHandlers) + 1); @@ -1669,9 +1769,9 @@ begin ConvertHandlers[High(ConvertHandlers)].needed := needed; ConvertHandlers[High(ConvertHandlers)].handler := handler; end; - +} begin - InsertHandler('ABNA', False, nil); +{ InsertHandler('ABNA', False, nil); // InsertHandler('AGDB',True,AGDB); InsertHandler('AGDB', False, nil); InsertHandler('AGQC', False, nil); @@ -1769,4 +1869,4 @@ begin InsertHandler('WMM_', False, nil); InsertHandler('WMMB', True, WMMB); InsertHandler('WPGE', True, WPGE); -end. +}end.