--- oup/rewrite/DataAccess/Access_OUP_ADB.pas 2007/01/18 17:15:59 93 +++ oup/current/DataAccess/Access_OUP_ADB.pas 2007/03/28 17:53:54 134 @@ -1,74 +1,79 @@ unit Access_OUP_ADB; interface -uses DataAccess; +uses DataAccess, ABSMain, TypeDefs, Classes; type TAccess_OUP_ADB = class(TDataAccess) private -{ FDatabase: TABSDatabase; - FQuery: TABSQuery; - Fdat_files: TFiles; + FDatabase: TABSDatabase; + FQuery: TABSQuery; + Fdat_files: TFiles; Fdat_extensionsmap: TExtensionsMap; protected public - constructor Create(OLDBFilename: String; var Result: Boolean); override; + constructor Create(DBFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override; procedure Close; override; procedure UpdateListCache; - // function GetDatLinks(srcid:LongWord):TDatLinks; - function GetFileInfo(fileid: Integer): TFileInfo; override; - function GetFilesList(ext: String; pattern: String; - NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override; - function GetFilesCount: LongWord; override; - function GetExtensionsList: TStringArray; override; - function GetExtendedExtensionsList: TExtensionsMap; override; - function GetNamedFilesMap: TNamedFilesMap; - - function LoadDatFile(fileid: LongWord): Tdata; override; - procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override; - procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override; - procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override; - - function GetRawList(fileid: LongWord): TRawList; override; - procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override; - procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord; - target: Pointer); override; - procedure LoadRawFilePart(fileid, dat_offset: LongWord; - offset, size: LongWord; target: Pointer); override; - procedure UpdateRawFilePart(fileid, dat_offset: LongWord; - offset, size: LongWord; target: Pointer); override; + + function GetLinksToFile(FileID: Integer): TLinks; + + function GetFileInfo(FileID: Integer): TFileInfo; override; + function GetFilesList(Ext: String; Pattern: String; + NoEmptyFiles: Boolean; SortType: TSortType): TStrings; override; + function GetFileCount: Integer; override; + function GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; override; + + procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; override; + procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; override; + procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override; + procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override; + + function GetDatLinks(FileID: Integer): TDatLinkList; override; + function GetDatLink(FileID, DatOffset: Integer): TDatLink; override; + function GetRawList(FileID: Integer): TRawDataList; override; + function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override; + + procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override; + procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override; + procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override; + procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override; published -} end; + end; implementation +uses + SysUtils, Data, Functions, ABSDecUtil, DB, DatLinks; + (* ================================================================================ Implementation of TOniDataADB *) -{ -constructor TOniDataADB.Create(OLDBFilename: String; var Result: Boolean); -var - i, j: Byte; - temps: String; + +constructor TAccess_OUP_ADB.Create(DBFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); begin - if not FileExists(OLDBFilename) then + Msg := SM_UnknownError; + if not FileExists(DBFilename) then begin - ShowMessage('File doesn''t exist!!!'); - Result := False; + Msg := SM_FileNotFound; Exit; end; - FFileName := OLDBFilename; + FFileName := DBFilename; + FDatabase := TABSDatabase.Create(nil); - FDatabase.DatabaseName := 'OLDBcon'; - FDatabase.DatabaseFileName := OLDBFilename; + FDatabase.Exclusive := True; + FDatabase.MultiUser := False; + FDatabase.DatabaseName := 'OLDBcon' + IntToStr(ConnectionID); + FDatabase.DatabaseFileName := DBFilename; FDatabase.Open; FQuery := TABSQuery.Create(FDatabase); - FQuery.DatabaseName := 'OLDBcon'; + FQuery.DisableControls; + FQuery.DatabaseName := 'OLDBcon' + IntToStr(ConnectionID); FQuery.SQL.Text := 'SELECT [name],[value] FROM globals ORDER BY [name] ASC'; FQuery.Open; FQuery.First; @@ -77,60 +82,43 @@ begin begin if FQuery.FieldByName('value').AsString <> DBversion then begin - ShowMessage('Database-file ' + #13 + #10 + - '"' + OLDBFilename + '"' + #13 + #10 + - 'has wrong version. (Required: ' + DBversion + '; found: ' + - FQuery.FieldByName('value').AsString + ')'); + Msg := SM_IncompatibleDBVersion; FQuery.Close; - Result := False; Exit; end; end; if FQuery.FieldByName('name').AsString = 'lvl' then + FLevelNumber := StrToInt(FQuery.FieldByName('value').AsString); + if FQuery.FieldByName('name').AsString = 'DataOS' then begin - FLevelInfo.LevelNumber := StrToInt(FQuery.FieldByName('value').AsString); - end; - if FQuery.FieldByName('name').AsString = 'ident' then - begin - temps := FQuery.FieldByName('value').AsString; - for i := 0 to High(FLevelInfo.Ident) do - begin - j := i * 2 + 1; - case temps[j] of - '0'..'9': - FLevelInfo.Ident[i] := Ord(temps[j]) - 48; - 'A'..'F': - FLevelInfo.Ident[i] := Ord(temps[j]) - 55; - end; - FLevelInfo.Ident[i] := FLevelInfo.Ident[i] * 16; - case temps[j + 1] of - '0'..'9': - FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 48; - 'A'..'F': - FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 55; - end; - end; - end; - if FQuery.FieldByName('name').AsString = 'ident' then - begin - temps := FQuery.FieldByName('value').AsString; - Fos_mac := temps = 'MAC'; + if FQuery.FieldByName('value').AsString = 'WIN' then + FDataOS := DOS_WIN + else if FQuery.FieldByName('value').AsString = 'WINDEMO' then + FDataOS := DOS_WINDEMO + else if FQuery.FieldByName('value').AsString = 'MAC' then + FDataOS := DOS_MAC + else if FQuery.FieldByName('value').AsString = 'MACBETA' then + FDataOS := DOS_MACBETA; end; FQuery.Next; until FQuery.EOF; FQuery.Close; - UpdateListCache; + Msg := SM_OK; + FBackend := DB_ADB; + + FConnectionID := ConnectionID; + FChangeRights := [CR_EditDat, CR_EditRaw, CR_ResizeDat, CR_ResizeRaw]; - Result := True; - FBackend := ODB_ADB; + UpdateListCache; end; -procedure TOniDataADB.Close; +procedure TAccess_OUP_ADB.Close; begin + FQuery.Free; FDatabase.Close; FDatabase.Free; Self.Free; @@ -138,46 +126,40 @@ end; -procedure TOniDataADB.UpdateListCache; +procedure TAccess_OUP_ADB.UpdateListCache; var - i: LongWord; + i: Integer; temps: String; begin FQuery.SQL.Text := 'SELECT id,name,extension,[size],contenttype FROM datfiles ORDER BY id ASC;'; FQuery.Open; + SetLength(Fdat_files, FQuery.RecordCount); if FQuery.RecordCount > 0 then begin FQuery.First; - SetLength(Fdat_files, FQuery.RecordCount); i := 0; repeat Fdat_files[i].ID := FQuery.FieldByName('id').AsInteger; Fdat_files[i].Name := FQuery.FieldByName('name').AsString; Fdat_files[i].Extension := FQuery.FieldByName('extension').AsString; - Fdat_files[i].FileName := FormatNumber(Fdat_files[i].ID, 5, '0') + '-' + - Fdat_files[i].Name + '.' + Fdat_files[0].Extension; - Fdat_files[i].FileNameHex := IntToHex(Fdat_files[i].ID, 4) + '-' + - Fdat_files[i].Name + '.' + Fdat_files[0].Extension; Fdat_files[i].Size := FQuery.FieldByName('size').AsInteger; - Fdat_files[i].FileType := HexToLong(FQuery.FieldByName('contenttype').AsString); + Fdat_files[i].FileType := StrToInt('$'+FQuery.FieldByName('contenttype').AsString); Fdat_files[i].DatAddr := 0; - Fdat_files[i].opened := False; Inc(i); FQuery.Next; until FQuery.EOF; end; FQuery.Close; - SetLength(Fdat_extensionsmap, 0); FQuery.SQL.Text := 'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;'; FQuery.Open; + SetLength(Fdat_extensionsmap, FQuery.RecordCount); if FQuery.RecordCount > 0 then begin - SetLength(Fdat_extensionsmap, FQuery.RecordCount); i := 0; repeat - temps := FQuery.FieldByName('extension').AsString[1]; + temps := FQuery.FieldByName('extension').AsString; Fdat_extensionsmap[i].Extension[3] := temps[1]; Fdat_extensionsmap[i].Extension[2] := temps[2]; Fdat_extensionsmap[i].Extension[1] := temps[3]; @@ -191,69 +173,87 @@ begin end; -function TOniDataADB.GetFileInfo(fileid: Integer): TFileInfo; + +function TAccess_OUP_ADB.GetLinksToFile(FileID: Integer): TLinks; var i: Integer; begin + SetLength(Result.ByName, 0); + FQuery.SQL.Text := 'SELECT src_link_offset, src_id FROM linkmap WHERE target_id = ' + IntToStr(FileID) + ' ORDER BY src_id ASC;'; + FQuery.Open; + SetLength(Result.ByID, FQuery.RecordCount); + if FQuery.RecordCount > 0 then + begin + i := 0; + repeat + Result.ByID[i].SrcOffset := FQuery.FieldByName('src_link_offset').AsInteger; + Result.ByID[i].Destination := FQuery.FieldByName('src_id').AsInteger; + Inc(i); + FQuery.Next; + until FQuery.EOF; + end; + FQuery.Close; +end; + + + +function TAccess_OUP_ADB.GetFileInfo(fileid: Integer): TFileInfo; +begin if fileid = -1 then begin Result := inherited GetFileInfo(fileid); Exit; end; - if fileid < Self.GetFilesCount then - begin - for i := 0 to High(Fdat_files) do - if Fdat_files[i].ID = fileid then - Break; - if i < Length(Fdat_files) then - Result := Fdat_files[i] - else - Result.ID := -1; - end + if fileid < Self.GetFileCount then + Result := Fdat_files[fileid] else - begin Result.ID := -1; - end; end; -function TOniDataADB.GetFilesList(ext: String; pattern: String; - NoEmptyFiles: Boolean; sort: TSortType): TStringArray; +function TAccess_OUP_ADB.GetFilesList(ext: String; pattern: String; + NoEmptyFiles: Boolean; SortType: TSortType): TStrings; var - i: LongWord; - list: TStringList; + i: Integer; + list: TStringList; id, name, extension: String; fields: TStrings; procedure getfields; begin - fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]); - if sort in [stIDAsc, stIDDesc] then + fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]); + if SortType in [ST_IDAsc, ST_IDDesc] then begin id := fields.Strings[0]; name := fields.Strings[1]; extension := fields.Strings[2]; end; - if sort in [stNameAsc, stNameDesc] then + if SortType in [ST_NameAsc, ST_NameDesc] then begin id := fields.Strings[1]; name := fields.Strings[0]; extension := fields.Strings[2]; end; - if sort in [stExtAsc, stExtDesc] then + if SortType in [ST_ExtAsc, ST_ExtDesc] then begin id := fields.Strings[1]; name := fields.Strings[2]; extension := fields.Strings[0]; end; + if SortType in [ST_ExtNameAsc, ST_ExtNameDesc] then + begin + id := fields.Strings[2]; + name := fields.Strings[1]; + extension := fields.Strings[0]; + end; end; begin list := TStringList.Create; list.Sorted := True; - for i := 0 to High(Fdat_files) do + for i := 0 to GetFileCount - 1 do begin if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and ((Length(pattern) = 0) or @@ -261,194 +261,111 @@ begin begin if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then begin - if AppSettings.FilenumbersAsHex then - id := IntToHex(Fdat_files[i].ID, 4) - else - id := FormatNumber(Fdat_files[i].ID, 5, '0'); + id := FormatNumber(Fdat_files[i].ID, 5, '0'); name := Fdat_files[i].Name; extension := Fdat_files[i].Extension; - case sort of - stIDAsc, stIDDesc: list.Add(id + ';' + name + ';' + extension); - stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension); - stExtAsc, stExtDesc: list.Add(extension + ';' + id + ';' + name); + case SortType of + ST_IDAsc, ST_IDDesc: list.Add(id + ';' + name + ';' + extension); + ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension); + ST_ExtAsc, ST_ExtDesc: list.Add(extension + ';' + id + ';' + name); + ST_ExtNameAsc, ST_ExtNameDesc: list.Add(name + ';' + extension + ';' + id); end; end; end; end; - SetLength(Result, list.Count); - fields := TStringList.Create; - if sort in [stIDAsc, stNameAsc, stExtAsc] then - for i := 0 to list.Count - 1 do - begin - getfields; - Result[i] := id + '-' + name + '.' + extension; - end - else - for i := list.Count - 1 downto 0 do - begin - getfields; - Result[list.Count - i - 1] := id + '-' + name + '.' + extension; - end; + if not Assigned(Result) then + Result := TStringList.Create; + if list.Count > 0 then + begin + fields := TStringList.Create; + if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc, ST_ExtNameAsc] then + for i := 0 to list.Count - 1 do + begin + getfields; + Result.Add(id + '-' + name + '.' + extension); + end + else + for i := list.Count - 1 downto 0 do + begin + getfields; + Result.Add(id + '-' + name + '.' + extension); + end; + fields.Free; + end; list.Free; - fields.Free; end; -function TOniDataADB.GetFilesCount: LongWord; +function TAccess_OUP_ADB.GetFileCount: Integer; begin Result := Length(Fdat_files); end; - - -function TOniDataADB.GetExtensionsList: TStringArray; +function TAccess_OUP_ADB.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; var - i: LongWord; + i: Integer; begin - SetLength(Result, Length(Fdat_extensionsmap)); - for i := 0 to High(Result) do + if not Assigned(Result) then + Result := TStringList.Create; + if Result is TStringList then + TStringList(Result).Sorted := True; + for i := 0 to Length(Fdat_extensionsmap) - 1 do begin with Fdat_extensionsmap[i] do begin - Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] + - ' (' + IntToStr(ExtCount) + ')'; + case ExtListFormat of + EF_ExtOnly: + Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0]); + EF_ExtCount: + Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0] + + ' (' + IntToStr(ExtCount) + ')'); + end; end; end; end; - - -function TOniDataADB.GetExtendedExtensionsList: TExtensionsMap; -var - i, j: LongWord; - temps: String; - Data: Tdata; -begin - SetLength(Result, 0); - FQuery.SQL.Text := 'SELECT ext,ident FROM extlist ORDER BY ext ASC;'; - FQuery.Open; - if FQuery.RecordCount > 0 then - begin - SetLength(Result, FQuery.RecordCount); - i := 0; - repeat - temps := FQuery.FieldByName('ext').AsString; - for j := 0 to 3 do - Result[i].Extension[j] := temps[4 - j]; - Data := DecodeHexString(FQuery.FieldByName('ident').AsString); - for j := 0 to 7 do - Result[i].Ident[j] := Data[j]; - Inc(i); - FQuery.Next; - until FQuery.EOF; - end; - FQuery.Close; -end; - - - - -function TOniDataADB.GetNamedFilesMap: TNamedFilesMap; +procedure TAccess_OUP_ADB.LoadDatFile(FileID: Integer; var Target: TStream); var - i: LongWord; - temp: Integer; - temps: String; - temparray: array of record - id: Integer; - fullname: String[50]; - end; + mem: TStream; + streampos: Integer; begin - SetLength(temparray, 0); - FQuery.SQL.Text := - 'SELECT id,(extension+name) AS xname FROM datfiles WHERE Length(name)>0 ORDER BY extension,name ASC;'; - FQuery.Open; - if FQuery.RecordCount > 0 then - begin - repeat - temp := FQuery.FieldByName('id').AsInteger; - temps := FQuery.FieldByName('xname').AsString; - - SetLength(temparray, Length(temparray) + 1); - if Length(temparray) > 1 then - begin - for i := High(temparray) - 1 downto 0 do - begin - if StringSmaller(temps, temparray[i].fullname) then - begin - temparray[i + 1] := temparray[i]; - if i = 0 then - begin - temparray[i].id := temp; - temparray[i].fullname := temps; - end; - end - else - begin - temparray[i + 1].id := temp; - temparray[i + 1].fullname := temps; - Break; - end; - end; - end - else - begin - temparray[0].id := temp; - temparray[0].fullname := temps; - end; - FQuery.Next; - until FQuery.EOF; - end; - FQuery.Close; - SetLength(Result, Length(temparray)); - for i := 0 to High(temparray) do + if fileid < GetFileCount then begin - Result[i].FileNumber := temparray[i].id; - Result[i].blubb := 0; - end; -end; - - + if not Assigned(Target) then + Target := TMemoryStream.Create; + streampos := Target.Position; -function TOniDataADB.LoadDatFile(fileid: LongWord): Tdata; -var - mem: TStream; -begin - if fileid < Self.GetFilesCount then - begin FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';'; FQuery.Open; if FQuery.RecordCount > 0 then begin mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead); - SetLength(Result, mem.Size); mem.Seek(0, soFromBeginning); - mem.Read(Result[0], mem.Size); + Target.CopyFrom(mem, mem.Size); mem.Free; end; FQuery.Close; + + Target.Seek(streampos, soFromBeginning); end; end; - - - -procedure TOniDataADB.UpdateDatFile(fileid: LongWord; Data: Tdata); +procedure TAccess_OUP_ADB.UpdateDatFile(FileID: Integer; Src: TStream); var MimeCoder: TStringFormat_MIME64; mem: TMemoryStream; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin mimecoder := TStringFormat_MIME64.Create; mem := TMemoryStream.Create; - mem.Write(Data[0], Length(Data)); - mem.Seek(0, soFromBeginning); + mem.CopyFrom(Src, Src.Size); FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' + MimeCoder.StrTo(mem.Memory, mem.Size) + '"), size=' + IntToStr(mem.Size) + ' WHERE id=' + IntToStr(fileid) + ';'; @@ -456,49 +373,50 @@ begin mem.Free; mimecoder.Free; end; - UpdateListCache; end; - -procedure TOniDataADB.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); +procedure TAccess_OUP_ADB.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); var + streampos: Integer; mem: TStream; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin + if not Assigned(Target) then + Target := TMemoryStream.Create; + streampos := Target.Position; + FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';'; FQuery.Open; if FQuery.RecordCount > 0 then begin mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead); mem.Seek(offset, soFromBeginning); - mem.Read(target^, size); + Target.CopyFrom(mem, size); mem.Free; end; FQuery.Close; + Target.Seek(streampos, soFromBeginning); end; end; - -procedure TOniDataADB.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); +procedure TAccess_OUP_ADB.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); var MimeCoder: TStringFormat_MIME64; mem: TMemoryStream; - Data: Tdata; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin - Data := Self.LoadDatFile(fileid); - mimecoder := TStringFormat_MIME64.Create; - mem := TMemoryStream.Create; - mem.Write(Data[0], Length(Data)); - mem.Seek(offset, soFromBeginning); - mem.Write(target^, size); + mem := nil; + LoadDatFile(fileid, TStream(mem)); + mem.Seek(Offset, soFromBeginning); + mem.CopyFrom(Src, Size); mem.Seek(0, soFromBeginning); + mimecoder := TStringFormat_MIME64.Create; FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' + MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';'; FQuery.ExecSQL; @@ -509,10 +427,50 @@ end; +function TAccess_OUP_ADB.GetDatLink(FileID, DatOffset: Integer): TDatLink; +begin + Result := DatLinksManager.GetDatLink(FConnectionID, FileID, DatOffset); + FQuery.SQL.Text := 'SELECT target_id FROM linkmap WHERE src_id = ' + IntToStr(FileID) + ' and src_link_offset = ' + IntToStr(DatOffset) + ';'; + FQuery.Open; + if FQuery.RecordCount > 0 then + Result.DestID := FQuery.FieldByName('target_id').AsInteger; + FQuery.Close; +end; -function TOniDataADB.GetRawList(fileid: LongWord): TRawList; + +function TAccess_OUP_ADB.GetDatLinks(FileID: Integer): TDatLinkList; var - i: LongWord; + i: Integer; + SrcOffset, DestID: Integer; +begin + Result := DatLinksManager.GetDatLinks(FConnectionID, FileID); + if Length(Result) > 0 then + begin + FQuery.SQL.Text := 'SELECT src_link_offset, target_id FROM linkmap WHERE src_id = ' + IntToStr(FileID) + ' ORDER BY src_link_offset ASC;'; + FQuery.Open; + if FQuery.RecordCount > 0 then + begin + repeat + SrcOffset := FQuery.FieldByName('src_link_offset').AsInteger; + DestID := FQuery.FieldByName('target_id').AsInteger; + for i := 0 to High(Result) do + if Result[i].SrcOffset = SrcOffset then + Break; + if i < Length(Result) then + Result[i].DestID := DestID + else + Result[i].DestID := -1; + FQuery.Next; + until FQuery.EOF; + end; + FQuery.Close; + end; +end; + + +function TAccess_OUP_ADB.GetRawList(FileID: Integer): TRawDataList; +var + i: Integer; begin SetLength(Result, 0); FQuery.SQL.Text := 'SELECT [src_link_offset],[size],[sep] FROM rawmap WHERE [src_id]=' + @@ -524,11 +482,11 @@ begin SetLength(Result, FQuery.RecordCount); i := 0; repeat - Result[i].src_id := fileid; - Result[i].src_offset := FQuery.FieldByName('src_link_offset').AsInteger; - Result[i].raw_addr := 0; - Result[i].raw_size := FQuery.FieldByName('size').AsInteger; - Result[i].loc_sep := FQuery.FieldByName('sep').AsBoolean; + Result[i].SrcID := fileid; + Result[i].SrcOffset := FQuery.FieldByName('src_link_offset').AsInteger; + Result[i].RawAddr := 0; + Result[i].RawSize := FQuery.FieldByName('size').AsInteger; + Result[i].LocSep := FQuery.FieldByName('sep').AsBoolean; Inc(i); FQuery.Next; until FQuery.EOF; @@ -537,46 +495,70 @@ begin end; +function TAccess_OUP_ADB.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; +var + i: Integer; + rawlist: TRawDataList; +begin + rawlist := GetRawList(FileID); + if Length(rawlist) > 0 then + begin + for i := 0 to High(rawlist) do + if rawlist[i].SrcOffset = DatOffset then + Break; + if i < Length(rawlist) then + Result := rawlist[i] + else begin + Result.SrcID := -1; + Result.SrcOffset := -1; + Result.RawAddr := -1; + Result.RawSize := -1; + end; + end; +end; -procedure TOniDataADB.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); + +procedure TAccess_OUP_ADB.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); var mem: TStream; + streampos: Integer; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin + if not Assigned(Target) then + Target := TMemoryStream.Create; + streampos := Target.Position; FQuery.SQL.Text := 'SELECT data FROM rawmap WHERE (src_id=' + - IntToStr(fileid) + ') AND (src_link_offset=' + IntToStr(dat_offset) + ');'; + IntToStr(FileID) + ') AND (src_link_offset=' + IntToStr(DatOffset) + ');'; FQuery.Open; if FQuery.RecordCount > 0 then begin mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead); mem.Seek(0, soFromBeginning); - mem.Read(target^, mem.size); + Target.CopyFrom(mem, mem.Size); mem.Free; end; FQuery.Close; + Target.Seek(streampos, soFromBeginning); end; end; - - -procedure TOniDataADB.UpdateRawFile(fileid, dat_offset: LongWord; - size: LongWord; target: Pointer); +procedure TAccess_OUP_ADB.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); var MimeCoder: TStringFormat_MIME64; mem: TMemoryStream; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin mimecoder := TStringFormat_MIME64.Create; mem := TMemoryStream.Create; - mem.Write(target^, size); + mem.CopyFrom(Src, Src.Size); mem.Seek(0, soFromBeginning); 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) + ');'; + mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(FileID) + + ') AND (src_link_offset=' + IntToStr(DatOffset) + ');'; FQuery.ExecSQL; mem.Free; mimecoder.Free; @@ -586,53 +568,51 @@ end; -procedure TOniDataADB.LoadRawFilePart(fileid, dat_offset: LongWord; - offset, size: LongWord; target: Pointer); +procedure TAccess_OUP_ADB.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); var - Data: Tdata; mem: TMemoryStream; + streampos: Integer; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin - SetLength(Data, Self.GetRawInfo(fileid, dat_offset).raw_size); - Self.LoadRawFile(fileid, dat_offset, @Data[0]); - mem := TMemoryStream.Create; - mem.Write(Data[offset], size); - mem.Read(target^, size); + if not Assigned(Target) then + Target := TMemoryStream.Create; + streampos := Target.Position; + mem := nil; + LoadRawFile(FileID, DatOffset, TStream(mem)); + mem.Seek(Offset, soFromBeginning); + Target.CopyFrom(mem, Size); mem.Free; + Target.Seek(streampos, soFromBeginning); end; end; -procedure TOniDataADB.UpdateRawFilePart(fileid, dat_offset: LongWord; - offset, size: LongWord; target: Pointer); +procedure TAccess_OUP_ADB.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); var MimeCoder: TStringFormat_MIME64; mem: TMemoryStream; - Data: Tdata; begin - if fileid < Self.GetFilesCount then + if fileid < GetFileCount then begin - SetLength(Data, Self.GetRawInfo(fileid, offset).raw_size); - Self.LoadRawFile(fileid, offset, @Data[0]); - mimecoder := TStringFormat_MIME64.Create; - mem := TMemoryStream.Create; - mem.Write(Data[0], Length(Data)); + mem := nil; + LoadRawFile(fileid, offset, TStream(mem)); mem.Seek(offset, soFromBeginning); - mem.Write(target^, size); + mem.CopyFrom(Src, Size); mem.Seek(0, soFromBeginning); + mimecoder := TStringFormat_MIME64.Create; 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) + ');'; + ') AND (src_link_offset=' + IntToStr(DatOffset) + ');'; FQuery.ExecSQL; mem.Free; mimecoder.Free; end; end; -} + end.