Jump to content
Mark Williams

TStringStream inconsistent results

Recommended Posts

Posted (edited)

I have an ISAPI DLL written in Delphi 10.4 running on my server. I exchange information in XML format with the DLL via an app also written in Delphi 10.4.

 

Both the server and the user computer are using Microsoft XML 6.0.

 

I use the following function to convert the exchange xml streams to a string and then to load into IXMLDocument.

 

Function ConvertStreamToString(stream:TMemoryStream):String;
  Var
    ss:TStringStream;
begin
  if (Stream <> nil) and (stream.Size>0) then
  begin
      Stream.Position:=0;
      ss:=TStringStream.Create;
      try
        ss.CopyFrom(stream, 0);
        Result:=ss.DataString;
      finally
        ss.Free;
      end;  
  end
  else
    Result := '';
end;

 

I load the xml data with:

 

Doc := LoadXMLData(ConvertStreamToString(Response));

 

This works fine for data received from the server, but not for data submitted to the server.

 

The data is received complete by the server (I save the received stream data to file to test), but something goes wrong with the convertStreamToString function and the LoadXMLData function throws up an error:

Quote

A Declaration was not closed.

Line: 1

<

If I change the stream conversion function to:

SetString(Result, PChar(Stream.Memory), Stream.Size div SizeOf(Char));

This works for the DLL on the server, but fails on the local app. It returns a load of junk throwing up an AV on the call to LoadXMLData.

 

I could have a different functions for the server and the local app, but I would rather have some idea as to why this is happening. I guess it is to do with encoding, but can anyone give me a steer as to how I resolve it please?

Edited by Mark Williams

Share this post


Link to post

My guess is you are looking at the wrong ends - the problem is a difference between what the web server sends to the client and what your client sends to the server. 

Share this post


Link to post

You suspect encoding is an issue but I can't see in your post any discussion of encoding. 

Share this post


Link to post

I suppose you are using TXMLDocument. Then why not using TXMLDocument.LoadFromStream and TXMLDocument.SaveToStream and let the library do the encoding work for you?

  • Like 2

Share this post


Link to post

Also, there's no real benefit of copying your memory stream to a string stream and loading it to the IXMLDocument that way; it just adds one more point-of-failure when it comes to encoding (if not specified, TStringStream considers the data to be ANSI encoded):

constructor TStringStream.Create;
begin
  Create('', TEncoding.Default, False);
end;

What I'd do is save both binary data to the disk and inspect them with a HEX editor. It will quickly reveal the differences what you might have to adjust, like encoding differences, absence / presence of BOMs, etc.

Share this post


Link to post
9 hours ago, Cristian Peța said:

I suppose you are using TXMLDocument. Then why not using TXMLDocument.LoadFromStream and TXMLDocument.SaveToStream and let the library do the encoding work for you?

Agreed. XML carries its own encoding information, which any compliant parser must handle. So always pass raw bytes into an XML parser and let it work out the encoding, don't decode the bytes yourself. 

  • Like 1

Share this post


Link to post
On 4/1/2024 at 7:57 AM, Cristian Peța said:

I suppose you are using TXMLDocument. Then why not using TXMLDocument.LoadFromStream and TXMLDocument.SaveToStream and let the library do the encoding work for you?

That seems to be the answer. Many thanks. I think I initially went with LoadXMLData because it created the XMLDocument for you in the same step. A false economy it seems!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×