Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   FreePascal Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode (https://www.delphipraxis.net/199677-verwenden-der-lazutf8-unit-veraendert-ergebnis-von-tiduri-urldecode.html)

mjustin 11. Feb 2019 14:42

Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Test 1: Free Pascal 3.0.4 Programm ohne Unit LazUTF8:

Delphi-Quellcode:
program FPCTest;

uses IdURI;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.
Ausgabe: ÄÖÜ

Test 2: wie Test 1, aber mit Unit LazUTF8 (für UTF-8 Unterstützung, hier beschrieben)

Delphi-Quellcode:
program FPCTest;

uses IdURI, LazUTF8;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.
Ausgabe: ???

Man kann zwar TIdURI.URLDecode direkt im Indy Sourcecode anpassen, in etwa so:


Delphi-Quellcode:
  {$IFDEF FPC}
  Result := string(AByteEncoding.GetString(LBytes));
  {$ELSE}
  {$IFDEF STRING_IS_ANSI}
  EnsureEncoding(ADestEncoding, encOSDefault);
  CheckByteEncoding(LBytes, AByteEncoding, ADestEncoding);
  SetString(Result, PAnsiChar(LBytes), Length(LBytes));
  {$ELSE}
  Result := AByteEncoding.GetString(LBytes);
  {$ENDIF}
  {$ENDIF}
- aber dabei ist es nicht möglich, anhand eines Flags zu "erkennen" ob der Code mit oder ohne der Unit LazUTF8 kompiliert wird.

Relativ naheliegend wäre ein eigenes Symbol zu definieren:

Delphi-Quellcode:
  {$IFDEF USES_LAZUTF8}
  Result := string(AByteEncoding.GetString(LBytes));
  {$ELSE}
  {$IFDEF STRING_IS_ANSI}
  EnsureEncoding(ADestEncoding, encOSDefault);
  CheckByteEncoding(LBytes, AByteEncoding, ADestEncoding);
  SetString(Result, PAnsiChar(LBytes), Length(LBytes));
  {$ELSE}
  Result := AByteEncoding.GetString(LBytes);
  {$ENDIF}
  {$ENDIF}

Oder habe ich noch eine Möglichkeit übersehen, mit der man das Ändern des Indy-Quelltext vermeiden könnte?

hoika 11. Feb 2019 14:44

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Hallo,
und wenn die die Unit-Reihenfolge umdrehst?

Hier http://wiki.freepascal.org/Unicode_S...n-LCL_programs steht ja auch
Then add LazUTF8 unit in the uses section of main program file.
It must be near the beginning, just after the critical memory managers and threading stuff (e.g. cmem, heaptrc, cthreads).

mjustin 11. Feb 2019 14:48

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Zitat:

Zitat von hoika (Beitrag 1425274)
Hallo,
und wenn die die Unit-Reihenfolge umdrehst?

Hier http://wiki.freepascal.org/Unicode_S...n-LCL_programs steht ja auch
Then add LazUTF8 unit in the uses section of main program file

Für das Ausführen des initialization Abschnitts in LazUTF8 macht das keinen Unterschied, so oder so wird erst initialisiert bevor UrlDecode ausgeführt wird.

hoika 11. Feb 2019 17:44

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Hallo,
geht ja noch weiter.
Warum steht da near beginning?

Die letzte Unit kann ja die Initialisierungen der anderen wieder aufheben.

Aber bei Lazarus bin ich raus ...

mjustin 11. Feb 2019 17:55

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Zitat:

Zitat von hoika (Beitrag 1425290)
Hallo,
geht ja noch weiter.
Warum steht da near beginning?

"just after the critical memory managers and threading stuff (e.g. cmem, heaptrc, cthreads)."

Das hat den Zweck, Fehler auszuschliessen die durch verspätete Initialisierung entstehen könnten.

Damit is gemeint, dass wenn man zum Beispiel

Delphi-Quellcode:
uses
  MemoryManager, ThreadStuff,
  MyUnit1, MyUnit2, OtherUnit, OtherStuff,
  LazUTF8;
schreibt, und in MyUnit1, MyUnit2, OtherUnit, OtherStuff bereits initialization Code enthalten ist, der vor dem in LazUTF8 ausgeführt wird, dann ist dort noch nicht die UTF-8 Unterstützung aktiviert und "üble Dinge könnten passieren".

Empfohlen wird daher LazUTF8 direkt nach Memory Manager und Thread-Unterstützungs Units zu platzieren:

Delphi-Quellcode:
uses
  MemoryManager, ThreadStuff,
  LazUTF8,
  MyUnit1, MyUnit2, OtherUnit, OtherStuff;
So kann nicht mehr viel schief gehen.

Delphi.Narium 11. Feb 2019 18:24

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Und was passiert bei
Delphi-Quellcode:
program FPCTest;

uses LazUTF8, IdURI;
// statt bisher
// uses IdURI, LazUTF8;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.

mjustin 11. Feb 2019 20:24

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1425293)
Und was passiert bei
Delphi-Quellcode:
program FPCTest;

uses LazUTF8, IdURI;
// statt bisher
// uses IdURI, LazUTF8;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.

Ausgabe: ???

=> die Reihenfolge der Units hat keine Auswirkung auf das Ergebnis

CCRDude 12. Feb 2019 11:13

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Wenn Du LazUTF8 verwendest, willst Du ja auch UTF8...
Klar wäre es schöner, wenn hier eine automatische Typenkonvertierung stattfinden würde, aber so musst Du halt per Hand ran:
1. wie wäre es den Rückgabewer an die Codepage der Konsole, auf der Du ausgibst, anzupassen (vermutlich mit UTF8ToWinCP)?
2. Oder mit SetConsoleOutputCP die Codepage der Konsole auf UTF8 zu ändern?

mjustin 12. Feb 2019 13:39

AW: Verwenden der LazUTF8 Unit verändert Ergebnis von TIdURI.URLDecode
 
Zitat:

Zitat von CCRDude (Beitrag 1425321)
Wenn Du LazUTF8 verwendest, willst Du ja auch UTF8...
Klar wäre es schöner, wenn hier eine automatische Typenkonvertierung stattfinden würde, aber so musst Du halt per Hand ran:
1. wie wäre es den Rückgabewer an die Codepage der Konsole, auf der Du ausgibst, anzupassen (vermutlich mit UTF8ToWinCP)?
2. Oder mit SetConsoleOutputCP die Codepage der Konsole auf UTF8 zu ändern?


Die Konsole ist nicht entscheidend, dieses Programm liefert "URLDecode hat das erwartete Ergebnis zur├╝ckgegeben"
Delphi-Quellcode:
program FPCTest;

uses IdURI, LazUTF8;

begin
  if TIdURI.URLDecode('%C3%84%C3%96%C3%9C') <> 'ÄÖÜ' then
    WriteLn('URLDecode hat nicht das erwartete Ergebnis zurückgegeben')
  else
    WriteLn('URLDecode hat das erwartete Ergebnis zurückgegeben');

  ReadLn;
end.
Einen Workaround für TIdURI.URLDecode habe ich ja schon oben besschrieben:

Delphi-Quellcode:
  {$IFDEF FPC}
  Result := string(AByteEncoding.GetString(LBytes));
  {$ELSE}
  {$IFDEF STRING_IS_ANSI}
  EnsureEncoding(ADestEncoding, encOSDefault);
  CheckByteEncoding(LBytes, AByteEncoding, ADestEncoding);
  SetString(Result, PAnsiChar(LBytes), Length(LBytes));
  {$ELSE}
  Result := AByteEncoding.GetString(LBytes);
  {$ENDIF}
  {$ENDIF}
Was aber noch zu verbessern wäre: wie könnte man geschickt (mit minimalen Änderungen an Indy) erkennen ob LazUTF8 bereits initialisiert wurde?


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:58 Uhr.

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