четверг, 30 октября 2014 г.

Рефакторинг. Преодоление "алгоритма маляра".

По мотивам - ToDo. Написать как замена "ассемблера" на нормальное ООП привело к отказу от "алгоритма маляра"

Было:

procedure   Tm3StorageStream.Seek(AOffset     : Int64;
                                  AOrigin     : TSeekOrigin;
                                  var AResult : Int64;
                                  var AReturn : HRESULT
                                 );
 
 procedure    __Seek(const APosition: Int64;
                     var   AResult: Int64
                    );
 var
       LCount:                   Int64;
       LPosition1:               Int64;
       LPosition2:               Int64;
       LPosition3:               Int64;
 begin
 
  with f_StreamHeader.TOCItemDataPtr^.RBody do
   begin
 
    if ((APosition >= 0) and (APosition <= RRealSize))
     then
      begin
 
       if (APosition = FPosition)
        then
        else
         begin
 
          LPosition1:=FPosition-FTOCBuffBodyOffset;
 
          if ((APosition >= LPosition1) and (APosition < (LPosition1+TOCBuffBodySize)))
           then
            begin
 
             FTOCBuffBodyOffset:=APosition-LPosition1;
 
            end
           else
            begin
 
             with f_StreamHeader.FRootStreamManager do
              begin
 
               SaveTOCBuffData(RTOCBuffRootPosition, f_CurFilePos,
                               FTOCBuffData^, FTOCBuffDataCompare^,
                               FTOCBuffDataModifed, ReadOnly);
 
               LPosition2:=Int64(-1);
               LPosition3:=RTOCBuffRootPosition;
 
               LCount:=APosition div FTOCBuffBodySize;
 
               while (LCount <> 0) do
                begin
 
                 LoadTOCBuffData(LPosition2,LPosition3,LPosition2,
                                 FTOCBuffData^,FTOCBuffDataCompare^,
                                 FTOCBuffDataModifed,False);
 
                 LPosition3:=FTOCBuffData^.RNextPosition;
 
                 Dec(LCount);
 
                end;
 
               LoadTOCBuffData(LPosition2,LPosition3, f_CurFilePos,
                               FTOCBuffData^,FTOCBuffDataCompare^,
                               FTOCBuffDataModifed,True);
 
               FTOCBuffBodyOffset:=APosition mod FTOCBuffBodySize;
 
              end;
 
            end;
 
          FPosition:=APosition;
 
         end;
 
      end
     else
      begin
 
       Exit;
 
      end;
 
   end;
 
  AResult:=APosition;
 
 end;
 
begin
 
 if SUCCEEDED(AReturn)
  then
   begin
 
    case AOrigin of
 
     soBeginning: begin
 
                       __Seek(AOffset,AResult);
 
                      end;
 
     soCurrent: begin
 
                       __Seek(AOffset+FPosition,AResult);
 
                      end;
 
     soEnd: begin
 
                       __Seek(AOffset + f_StreamHeader.TOCItemDataPtr^.RBody.RRealSize, aResult);
 
                      end;
 
     else             begin
 
                       OleError(E_UNEXPECTED);
 
                      end;
 
    end;
     
   end;
 
end;

Стало:

procedure Tm3NewStorageStreamPrim.Seek(anOffset: Int64;
  anOrigin: TSeekOrigin;
  var theResult: Int64;
  var theReturn: hResult);
//#UC START# *4FA27D5302C5_5448F0A40180_var*

 procedure __Seek(const aPosition: Int64;
                  var   theResult: Int64);
 var
  l_Next : Tm3StorageBlock;
  l_BlockIndex : Int64;
 begin//__Seek
  if ((APosition >= 0) and (APosition <= f_HeaderData.RRealSize)) then
  begin
   if (APosition <> f_Position) then
   begin
    l_BlockIndex := APosition div f_HeaderData.Stream.ClusterBodySize;

    if (l_BlockIndex <> f_Block.Index) then
    begin
     if (l_BlockIndex = 0) then
     begin
      FreeAndNil(f_Block);
      f_Block := Tm3StorageBlock.Create(f_HeaderData);
     end//l_BlockIndex = 0
     else
     if (l_BlockIndex > f_Block.Index) then
     begin
      while (l_BlockIndex <> f_Block.Index) do
      begin
       l_Next := f_Block.CreateNext;
       try
        l_Next.SetRefTo(f_Block);
       finally
        FreeAndNil(l_Next);
       end;//try..finally
      end;//l_BlockIndex <> f_Block.Index
     end//l_BlockIndex > f_Block.Index
     else
     if (l_BlockIndex < f_Block.Index) then
     begin
      while (l_BlockIndex <> f_Block.Index) do
      begin
       l_Next := f_Block.CreatePrev;
       try
        l_Next.SetRefTo(f_Block);
       finally
        FreeAndNil(l_Next);
       end;//try..finally
      end;//l_BlockIndex <> f_Block.Index
     end;//l_BlockIndex > f_Block.Index
    end;//l_BlockIndex <> f_Block.Index

    Assert(l_BlockIndex = f_Block.Index);

    f_Block.SetPositionInStream(aPosition);
    f_Position := aPosition;
   end;//APosition <> FPosition
  end//((APosition >= 0) and (APosition <= RRealSize))
  else
   Assert(false, 'Смещаемся за границу потока');
  theResult := f_Position;
 end;//__Seek

//#UC END# *4FA27D5302C5_5448F0A40180_var*
begin
//#UC START# *4FA27D5302C5_5448F0A40180_impl*
 if SUCCEEDED(theReturn) then
 begin
  case anOrigin of
   soBeginning:
    __Seek(anOffset, theResult);
   soCurrent:
    __Seek(anOffset + f_Position, theResult);
   soEnd:
    __Seek(anOffset + f_HeaderData.RRealSize, theResult);
   else
   begin
    Assert(false, 'Неверный anOrigin');
    OleError(E_UNEXPECTED);
   end;//else
  end;//case anOrigin
 end;//SUCCEEDED(theReturn)
//#UC END# *4FA27D5302C5_5448F0A40180_impl*
end;//Tm3NewStorageStreamPrim.Seek

Или в "самом актуальном прочтении":

procedure Tm3NewStorageStreamPrim.Seek(anOffset: Int64;
  anOrigin: TSeekOrigin;
  var theResult: Int64;
  var theReturn: hResult);
//#UC START# *4FA27D5302C5_5448F0A40180_var*

 procedure __Seek(const aPosition: Int64;
                  var   theResult: Int64);
 var
  l_Next : Tm3StorageBlock;
  l_BlockIndex : Int64;
 begin//__Seek
  if ((APosition >= 0) and (APosition <= f_HeaderData.RRealSize)) then
  begin
   if (APosition <> f_Position) then
   begin
    Assert(f_Block <> nil);
    f_Block.MoveTo(aPosition, f_Block);
   end;//APosition <> FPosition
  end//((APosition >= 0) and (APosition <= RRealSize))
  else
   Assert(false, 'Смещаемся за границу потока');
  theResult := f_Position;
 end;//__Seek

//#UC END# *4FA27D5302C5_5448F0A40180_var*
begin
//#UC START# *4FA27D5302C5_5448F0A40180_impl*
 if SUCCEEDED(theReturn) then
 begin
  case anOrigin of
   soBeginning:
    __Seek(anOffset, theResult);
   soCurrent:
    __Seek(anOffset + f_Position, theResult);
   soEnd:
    __Seek(anOffset + f_HeaderData.RRealSize, theResult);
   else
   begin
    Assert(false, 'Неверный anOrigin');
    // - это "предусловие", оно НЕ ДОЛЖНО нарушаться
    OleError(E_UNEXPECTED);
   end;//else
  end;//case anOrigin
 end;//SUCCEEDED(theReturn)
//#UC END# *4FA27D5302C5_5448F0A40180_impl*
end;//Tm3NewStorageStreamPrim.Seek

Комментариев нет:

Отправить комментарий