This forum is in archive mode. You will not be able to post new content.

Author Topic: Fixed indy components for Lazarus IDE  (Read 6567 times)

0 Members and 1 Guest are viewing this topic.

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Fixed indy components for Lazarus IDE
« on: January 15, 2011, 09:44:58 PM »
Those who tried and of course failed and were lazy to research a little, knows that you cannot install Indy components to Lazarus IDE without changing one file a little. Why these problems appear - I have no idea, but I do know how to fix them.
You have to change the "IdStreamVCL.pas" file like this:

Code: [Select]
{
  $Project$
  $Workfile$
  $Revision$
  $DateUTC$
  $Id$

  This file is part of the Indy (Internet Direct) project, and is offered
  under the dual-licensing agreement described on the Indy website.
  (http://www.indyproject.org/)

  Copyright:
   (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
  $Log$
}

unit IdStreamVCL;

interface

{$I IdCompilerDefines.inc}

uses
  Classes;

type
  TIdBytes = array of Byte;

  TIdStreamHelperVCL = class
  public
    class function ReadBytes(
          const AStream: TStream;
          var VBytes: TIdBytes;
          const ACount: Integer = -1;
          const AOffset: Integer = 0) : Integer; {$IFDEF DOTNET} static; {$ENDIF}
    class function Write(
          const AStream: TStream;
          const ABytes: TIdBytes;
          const ACount: Integer = -1;
          const AOffset: Integer = 0) : Integer; {$IFDEF DOTNET} static; {$ENDIF}
    class function Seek(
          const AStream: TStream;
          const AOffset: Int64;
          const AOrigin: TSeekOrigin) : Int64; {$IFDEF DOTNET} static; {$ENDIF}
  end;

  function IndyLength(const ABuffer: TIdBytes; const ALength: Integer = -1; const AIndex: Integer = 0): Integer;
  function IndyMax(const AValueOne, AValueTwo: Integer): Integer;
  function IndyMin(const AValueOne, AValueTwo: Integer): Integer;

implementation

function IndyMin(const AValueOne, AValueTwo: Integer): Integer;
{$IFDEF USEINLINE}inline;{$ENDIF}
begin
  if AValueOne > AValueTwo then begin
    Result := AValueTwo;
  end else begin
    Result := AValueOne;
  end;
end;

function IndyMax(const AValueOne, AValueTwo: Integer): Integer;
{$IFDEF USEINLINE}inline;{$ENDIF}
begin
  if AValueOne < AValueTwo then begin
    Result := AValueTwo;
  end else begin
    Result := AValueOne;
  end;
end;

function IndyLength(const ABuffer: TIdBytes; const ALength: Integer = -1; const AIndex: Integer = 0): Integer;
{$IFDEF USEINLINE}inline;{$ENDIF}
var
  LAvailable: Integer;
begin
  Assert(AIndex >= 0);
  LAvailable := IndyMax(Length(ABuffer)-AIndex, 0);
  if ALength < 0 then begin
    Result := LAvailable;
  end else begin
    Result := IndyMin(LAvailable, ALength);
  end;
end;

// RLebeau: must use a 'var' and not an 'out' for the VBytes parameter,
// or else any preallocated buffer the caller passes in will get wiped out!

class function TIdStreamHelperVCL.ReadBytes(const AStream: TStream; var VBytes: TIdBytes;
  const ACount, AOffset: Integer): Integer;
var
  LActual: Integer;
begin
  Assert(AStream<>nil);
  Result := 0;

  if VBytes = nil then begin
    SetLength(VBytes, 0);
  end;
  //check that offset<length(buffer)? offset+count?
  //is there a need for this to be called with an offset into a nil buffer?

  LActual := ACount;
  if LActual < 0 then begin
    LActual := AStream.Size - AStream.Position;
  end;

  //this prevents eg reading 0 bytes at Offset=10 from allocating memory
  if LActual = 0 then begin
    Exit;
  end;

  if Length(VBytes) < (AOffset+LActual) then begin
    SetLength(VBytes, AOffset+LActual);
  end;

  Assert(VBytes<>nil);
  Result := AStream.Read(VBytes[AOffset], LActual);
end;

class function TIdStreamHelperVCL.Write(const AStream: TStream; const ABytes: TIdBytes;
  const ACount: Integer; const AOffset: Integer): Integer;
var
  LActual: Integer;
begin
  Result := 0;
  Assert(AStream<>nil);
  //should we raise assert instead of this nil check?
  if ABytes <> nil then begin
    LActual := IndyLength(ABytes, ACount, AOffset);
    // TODO: loop the writing, or use WriteBuffer(), to mimic .NET where
    // System.IO.Stream.Write() writes all provided bytes in a single operation
    if LActual > 0 then begin
      Result := AStream.Write(ABytes[AOffset], LActual);
    end;
  end;
end;

class function TIdStreamHelperVCL.Seek(const AStream: TStream; const AOffset: Int64;
  const AOrigin: TSeekOrigin): Int64;
{$IFNDEF SIZE64STREAM}
const
  cOrigins: array[TSeekOrigin] of Word = (soFromBeginning, soFromCurrent, soFromEnd);
{$ENDIF}
begin
  {$IFDEF SIZE64STREAM}
  Result := AStream.Seek(AOffset, AOrigin);
  {$ELSE}
  Result := AStream.Seek(AOffset and $FFFFFFFF, cOrigins[AOrigin]);
  {$ENDIF}
end;

end.

and now, put them to a location where they won't be bothered, like /components/ folder in your Lazarus installation folder, open the .lpk package with Lazarus and put /fpc/ folder in Compiler Options before installing. Remember to press the "Install" button. Do not compile before installing because it will say that the checksum has changed...

I also made a fixed archive, so you just need to extract and use.
Enjoy: http://www.mediafire.com/?e4tem2kfgraccop

 



Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.