Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   TStringStream - ein Bug oder was mache ich falsch? (https://www.delphipraxis.net/196616-tstringstream-ein-bug-oder-mache-ich-falsch.html)

Elrond 4. Jun 2018 09:22

Delphi-Version: 10.2 Tokyo

TStringStream - ein Bug oder was mache ich falsch?
 
Hallo Zusammen,

der TStringStream arbeitet nicht wie erwartet. Wenn ich auf den gespeicherten String via DataString zugreifen möchte, fehlt einfach ein Großteil des Strings. Das gleiche wenn ich den String direkt in eine Textdatei speichern möchte. Der direkte Zugriff über den Bytestream klappt dagegen (macht das Framework). Ich habe schon unterschiedliche Encodings probiert, keine Abhilfe, auch hat der zurückgegebene String keine Encodingprobleme, er bricht einfach nach knapp 36T Zeichen ab.

Der betreffende Quelltext:

Code:

function TOcServiceDocumentServerModule.GetSwagger(URLEncoding:Boolean): TStream;
var
  Doc: TOpenApiDocument;
  Builder: TOcOpenApiBuilder;
  Writer: TJsonWriter;
  Serializer: TSerializer;
  resultStr: String;

begin
  Builder := TOcOpenApiBuilder.Create((Module as TOcXDataServerModule).XModel);
  Doc := Builder.GetDocument;
 
  try
    Writer := nil;
    Serializer := nil;
    Result := TStringStream.Create;
 // Result := TFileStream.Create('bla.txt', fmCreate);
    try
      Writer := TJsonWriter.Create(Result);
      Serializer := TSerializer.Create;
      Serializer.Write(Doc, Writer);

     //(Result as TStringStream).SaveToFile('bla.txt');
      
   if URLEncoding then begin
      resultStr := (Result as TStringStream).DataString;
       resultStr := StringReplace(resultStr, '<', '%3C', [rfIgnoreCase]);
       resultStr := StringReplace(resultStr, '>', '%3E', [rfIgnoreCase]);
       Result := TStringStream.Create(resultStr);
   end;
    except
      FreeAndNil(Result);
      raise;
    end;
  finally
    Serializer.Free;
    Writer.Free;
  end;
end;

Rollo62 4. Jun 2018 09:56

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Versuch mal im TStringStream.Create( LString ); eine Arbeitsvariable anzugeben
http://docwiki.embarcadero.com/CodeE...tring_(Delphi)

Rollo

TiGü 4. Jun 2018 10:07

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Ohne genaue Kenntnis von TOpenApiDocument, TOcOpenApiBuilder, TJsonWriter (ist nicht der Delphi eigene) und TSerializer ist es schwierig dir da weiterzuhelfen.
Aber ein Hinweis: Wenn URLEncoding == true ist, dann überschreibst du das Result und hast ein Speicherleck vom ersten erzeugten Stream.

Elrond 4. Jun 2018 10:40

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Zitat:

Zitat von Rollo62 (Beitrag 1403790)
Versuch mal im TStringStream.Create( LString ); eine Arbeitsvariable anzugeben
http://docwiki.embarcadero.com/CodeE...tring_(Delphi)

Rollo

Ich habe es mit der Variable probiert aber das gleiche Ergebnis.

Code:
   Result := TStringStream.Create(s);
Zitat:

Zitat von TiGü (Beitrag 1403791)
Ohne genaue Kenntnis von TOpenApiDocument, TOcOpenApiBuilder, TJsonWriter (ist nicht der Delphi eigene) und TSerializer ist es schwierig dir da weiterzuhelfen.
Aber ein Hinweis: Wenn URLEncoding == true ist, dann überschreibst du das Result und hast ein Speicherleck vom ersten erzeugten Stream.

Der TJsonWriter und TSerializer (von TMS) sollten eigentlich nur ein Objekt (ein beliebiges, in diesen Fall TOpenApiDocument) in json (String) serialisieren.
Genau das passiert auch, im TStream Objekt befindet das vollständige json, verwende ich wie angedeutet ein TFileStream und speicher ihn in eine Datei ist auch alles da, mache ich das selbe mit TStringStream fehlt einfach die Hälfte.

Um es konkreter zu Formulieren: Verwende ich TStringStream, funktioniert am Ende alles, ich erhalte das Vollständige json wenn ich über http Anfrage. Wenn ich jedoch wie im Beispiel das json verändern möchte und über DataString darauf zugreife fehlt ein Großteil des Strings.

Neutral General 4. Jun 2018 10:42

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Bin mir nicht sicher, ob das beim TStringStream notwendig ist, aber versuch vielleicht mal nach dem Serialisieren Result.Position auf 0 zu setzen.

Uwe Raabe 4. Jun 2018 10:43

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Kannst du das Problem auf einen minimalen Testfall reduzieren und den hier einstellen?

TiGü 4. Jun 2018 10:53

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Ein reindebuggen in TEncoding.GetString wäre hier eigentlich am sinnvollsten.
Ist Inhalt und Länge des übergebenen TBytes-Array gleich wie bei der TBytesStream-Lösung?

Tendenziell kannst du eh komplett auf TBytesStream wechseln und nur bei URLEncoding == true mithilfe einer TEncoding-Instanz dir einen String zum bearbeiten erstellen.

Ist möglicherweise DataString korrekt im Umfang, aber dein Problem ergibt sich erst nach den beiden StringReplace-Aufrufen?

Frei nach Lenin:
Zitat:

Debuggen, debuggen und nochmals debuggen.

Elrond 4. Jun 2018 12:41

AW: TStringStream - ein Bug oder was mache ich falsch?
 
Okay ich hab es, Streams eben...

Hat nichts mit Delphi ansich zu tun, ist eine unglückliche Verkettung von Umständen. Mit TByteStream trat das gleiche Problem auf, also habe ich mal tiefer in den Quelltext von TJsonWriter geschaut und Bingo. Das übergebene TStream Objekt wird erst bei der Freigabe von TJsonWriter geflusht, das bedeutet der restliche Inhalt der bis jetzt fehlte befand sich im Buffer.

Um sicherzugehen, dass das Problem beim TStringStream liegt habe ich als Ersatz TFileStream verwendet, wo es auch geklappt hat. Aber es hat nur geklappt weil ich ihn nicht direkt geflusht oder freigegeben habe, somit wurde er erst am Ende des Programms freigeben und zu diesen Zeitpunkt hat der TJsonWriter bereits seinen Buffer geleert (was mich letztlich auf die falsche Fährte lockte).


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz