Solved

Getting XML string from response stream using Indy's IDTCPClient

Posted on 2013-11-20
1
830 Views
Last Modified: 2013-11-21
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
0
Comment
Question by:livestuff
1 Comment
 
LVL 1

Accepted Solution

by:
livestuff earned 0 total points
ID: 39667093
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

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This article will show, step by step, how to integrate R code into a R Sweave document
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

806 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question