Getting XML string from response stream using Indy's IDTCPClient

First, let me give you some back ground. This code is only a subset of the code for the component. Secondly, I did not write this component, given the time to do so, I would rewrite it using TidHTTP instead of  IDTCPClient, because it would be more at my level. i do not have the experience for low level socket connections. Having said that, here is my problem

I have this component


 
private
    { Private declarations }
    FRawRequest : String;
    FRawResponse: String;
  ...
  protected
    { Protected declarations }
  public
    { Public declarations }
     ...
    ResponseJSON_V: TJSONValue;
    ResponseXML_v: String;
    ResponseStream: TMemoryStream;
    Constructor Create( AOwner : TComponent ); override;
    Destructor Destroy; Override;
    Procedure GenerateXML; 
    Procedure GenerateJSON;
    function EncodeUrl(aDecodedUrl: String): String;
    function DecodeUrl(aEncodedUrl: String): String;
    Function LiveGET(aRawHeader:String):String;
  published
  ...
  end;

procedure Register;


implementation

Function StreamToArray(Strm:TStream):TArray<Byte>;
Begin
 Strm.Position := 0;
 SetLength(Result,Strm.Size);
 Strm.Read(Result[0],Strm.Size);
End;


Constructor TMyConnector.Create(AOwner: TComponent);
begin
  inherited;
  FPort     := 80;
  FHost     := 'dev.xxxxxxxxxx.com';
  FSock     := TIDTCPClient.Create(Self);
  FSock.Port:= FPort;
  Fsock.Host:= Fhost;


end;


destructor TMyConnector.Destroy;
begin
  if FSock<>nil then
  begin
    if Connected then Connected := False;
    FreeAndNil(FSock);
  end;
  inherited;
end;


function TMyConnector.EncodeUrl(aDecodedUrl: String): String;
begin
 result:= tIdUri.URLEncode(aDecodedUrl);
end;


function TMyConnector.DecodeUrl(aEncodedUrl: String): String;
begin
 result:= TIdURI.URLEncode(aEncodedUrl);
end;



Procedure TMyConnector.GenerateJSON;
begin
if ResponseStream <> nil then
  Begin
   ResponseJSON_V := TJSONObject.ParseJSONValue(StreamToArray(ResponseStream),0) as TJSONValue;
  End;
end;


{Procedure TMyConnector.GenerateXML;
var
 S: String;
begin
if ResponseStream <> nil then
  Begin
   try
    while FSock.IOHandler.CheckForDataOnSource(30) do
    begin
       S := FSock.IOHandler.InputBufferAsString;
    end;
  finally
    ResponseStr_v:= S;
  end;
  End;
end; }


Procedure TMyConnector.GenerateXML;
begin
  StreamToArray(ResponseStream)
end; }


Procedure TMyConnector.GenerateXML;
var
 S: String; SS: TStringStream;
begin
 if ResponseStream <> nil then begin
   S := '';
   SS := TStringStream.Create(S, TEncoding.UTF8, False);
   try
     SS.LoadFromStream(ResponseStream);
     // original: ResponseXML_v := S;   - so ResponseXML_v is jsut a string....
     ResponseXML_v:= SS.DataString;
   finally
     SS.Destroy;
   end;
 end;
end;



function TMyConnector.LiveGET(aRawHeader: String): String;
begin

 if Not Connected then Connected := True;
if Connected then
  begin
  FRawRequest :=  'GET /'+ EncodeUrl(aRawHeader) + ' HTTP/'+HTTPVerText+#13#10+
                  'Host: '+FHost+#13#10+

                  'Cookie: UserHPos=IOGLO00003000090000C000BS; '+
                  'LOSID=qsBiy/wEDCq6tOXFzGbOlTD1lmo5AXdFnCkbzzPn6+qCeheYVyTcumRrjsqh+Hds4Fr2gZDazfDzGN1RA+nnHuQQeBy78ZUgctrZyyy9MnGl2qI/ulkV6EPxAfmmLg/lopRq99f5gAcG/dgtytAJjS+aD5DqtHGrAqjiqgtkwuA=; '+
                  'LoginHPos=IOGLO00003000090000C000BS; '+
                  'UIHPos=IOGLO00003000020000500003; '+
                  'LOSG=61939308-7C83-47ED-B909-2D2D10AD7026; '+
                  'fControllingBusiness=IOGLO000030000900001000050000200001'+#13#10+

                  'Connection: Close'+#13#10+
                  #13#10;

   FSock.Socket.Write(FRawRequest);
   FRawResponse := FSock.Socket.ReadLn(#13#10#13#10,nil);

  Result := FRawResponse;
  if responseStream = nil then responseStream:= TMemoryStream.Create else

  ResponseStream.SetSize(0);

   FSock.Socket.ReadStream(ResponseStream,-1,True);

  if Connected and (Not KeepAlive) then Connected := False;
  end;
end;

end.

Open in new window



I can't seem to get to be able to get my XML from the responsestream

my response looks like this:



HTTP/1.0 200 OK
Content-Length: 2069
Date: Wed, 20 Nov 2013 15:00:11 GMT
Content-Type: text/xml; charset=UTF-8

Any help would be appreciated
LVL 1
livestuffAsked:
Who is Participating?
 
livestuffAuthor Commented:
I have figured this out on my own. I AM SHOCKED there were no Delphi experts that could not solve this here.  ANyway, I google MemorySTream to String and found the function StreamToString, and simply looked at the GenerateJSON method to create my own GenerateXML method using StreamToString. AND IT WORKS!

function StreamToString(aStream: TStream): string;
var
  SS: TStringStream;
begin
  if aStream <> nil then
  begin
    SS := TStringStream.Create('');
    try
      SS.CopyFrom(aStream, 0);  // No need to position at 0 nor provide size
      Result := SS.DataString;
    finally
      SS.Free;
    end;
  end else
  begin
    Result := '';
  end;
end;

Procedure GenerateXML;
begin
if ResponseStream <> nil then
  Begin
   ResponseXML_V := StreamToString(ResponseStream);
  End;
end;
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.