AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

tReader-Objekt unter 10.4.1

Ein Thema von michaelg · begonnen am 5. Okt 2020 · letzter Beitrag vom 8. Okt 2020
Antwort Antwort
michaelg

Registriert seit: 20. Apr 2008
57 Beiträge
 
#1

tReader-Objekt unter 10.4.1

  Alt 5. Okt 2020, 17:27
Moin zusammen,

ich habe bei der Umstellung von 10.3.3 auf 10.4.1 ein Problem mit Umlauten erkannt. Es geht um das Einlesen eines Streams mit Benutzung von tReader. In System.Classes.pas steht in der 10.3.3 für den Typ "vaString" folgendes:

Code:
   
    vaString:
      begin
        Read(L, SizeOf(Byte));
        SetLength(LResult, L);
        Read(LResult, L);
        Result := TEncoding.Default.GetString(LResult);
      end;
In 10.4.1 steht folgendes für diesen Typ:

Code:
   vaString:
      begin
        Read(S[0], SizeOf(Byte));
        Read(S[1], NativeInt(S[0]));
        Result := UTF8IdentToString(@S);
      end;
Die Variable "S" ist dort als ShortString definiert und ein Umlaut wie "ä" (hex E4) kommt so nicht mehr korrekt an. Die Dateien behaupten, sie wären als ANSI gespeichert. Und ReadValue gibt für die Strings "vaString" an.

Ich möchte nicht in der System.Classes rumrühren, gibts einen Workaround oder irgendeine globale Definition, die das korrigiert? Ich meine jetzt nicht den String Byte für Byte durchgehen und die Umlaute hartcodiert umzustellen auf einen anderen Wert.

Weiß jemand, warum das umgestellt wurde?

Grüße
Michael
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
36.978 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: tReader-Objekt unter 10.4.1

  Alt 5. Okt 2020, 18:11
Da hat wohl jemand Mist gebaut und nicht bedacht, dass diese Streams auch von anderen benutzt werden können. (wie z.B. von dir oder uns ... zum Glück bin ich noch nicht so weit, mit der Umstellung auf 10.4)

Auch bei "älteren" DFMs, welche noch binär gespeichert sind oder noch nicht umgestellt wurden (nicht als Text-DFM), wird es somit Probleme geben.
In der EXE-Ressource sind die zwar binär hinterlegt, aber da dort mit der selben TReader/TWriter-Verion gelesen wird, wie der Compiler es abspeicherte, ist das wohl noch niemandem ausgefallen.


Da kannst du nur an den Hersteller wenden, dass die das gefälligst beheben.
Bisher, und das muß eigentlich auch so bleiben, war vaString ein ShortString mit ANSI.

Per se ist es gut das ANSI aus DFMs (diesen Streams) zu verbannen, denn in einem deutschen Windows kompiliert und in einem anderem Windows gestartet, z.B. in französisch/englisch/russisch/chinesisch/..., da hatte man schon immer Spaß.
Aber das darf nicht das Lesen "alter" Streams beeinflussen.
Beim neu Speichern darf in vaString einfach nur ausschließlich ASCII [#0..#127] rein und der Rest muß in vaUTF8String. Und vaString ist und bleibt ANSI, beim Lesen.



Wobei ich mir fast sicher bin, dass ich unsere Streams nur als Text speichere und somit hoffentlich vielleicht keine Probleme bekomme,
falls ich auch beim FastReport da nichts übersehn hab.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 5. Okt 2020 um 21:33 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
1.055 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: tReader-Objekt unter 10.4.1

  Alt 5. Okt 2020, 20:22
Ist dieser Fehler schon in QP erfasst? Falls nicht bitte zügig tun und die Report Nummer hier melden.
  Mit Zitat antworten Zitat
michaelg

Registriert seit: 20. Apr 2008
57 Beiträge
 
#4

AW: tReader-Objekt unter 10.4.1

  Alt 5. Okt 2020, 22:08
Habe es gemeldet unter RSP-31215:

https://quality.embarcadero.com/browse/RSP-31215
  Mit Zitat antworten Zitat
michaelg

Registriert seit: 20. Apr 2008
57 Beiträge
 
#5

AW: tReader-Objekt unter 10.4.1

  Alt 8. Okt 2020, 12:35
Da ich nicht warten wollte, bis Embarcardero soweit ist, habe ich einen kleinen Workaround gebaut. Ich benutze dann nicht tReader, sondern tMGReader zum Auslesen der Stringvalues.

Vielleicht kann es ja übergangsweise noch jemand gebrauchen.


Code:
//**********************************************************************************************
// MGReader.pas
//
// Unit für den Workaround des bei Embacadero gemeldeten Fehlers RSP-31215
// Mit dem tMGReader werden die Umlaute wieder korrekt gelesen
//
// Link zum Fehler: https://quality.embarcadero.com/browse/RSP-31215
//
// Autor: Michael Groß
// Stand: 08.10.2020
//
//***************************************************************************************

unit MGReader;

interface

uses
  System.Classes, System.SysUtils, System.RTLConsts;

type
  tMGReader=class(tReader)
    private
    public
      function ReadString:String; reintroduce;
  end;

implementation

procedure ReadError(Ident: PResStringRec); overload;
  begin
    raise EReadError.CreateRes(Ident) at ReturnAddress;
  end;

procedure PropValueError;
  begin
    ReadError(@SInvalidPropertyValue);
  end;

function TMGReader.ReadString:String;
  var
    L: Integer;
    LResult: TBytes;
  //  S: ShortString;
  begin
    L := 0;
    case ReadValue of
      vaWString:
        begin
          Read(L, SizeOf(Integer));
          SetLength(LResult, L*sizeof(WideChar));
          Read(LResult, L*sizeof(WideChar));
          Result := TEncoding.Unicode.GetString(LResult);
        end;
      vaUTF8String:
        begin
          Read(L, SizeOf(Integer));
          SetLength(LResult, L);
          Read(LResult, L);
          Result := TEncoding.UTF8.GetString(LResult);
        end;
      (*
      das war Original bei 10.4.1
      vaString:
        begin
          Read(S[0], SizeOf(Byte));
          Read(S[1], NativeInt(S[0]));
          Result := UTF8IdentToString(@S);
        end;
      *)
      vaString: //übernommen aus 10.3.3, damit funktionieren die Umlaute wieder
        begin
          Read(L, SizeOf(Byte));
          SetLength(LResult, L);
          Read(LResult, L);
          Result := TEncoding.Default.GetString(LResult);
        end;
      vaLString:
        begin
          Read(L, SizeOf(Integer));
          SetLength(LResult, L);
          Read(LResult, L);
          Result := TEncoding.Default.GetString(LResult);
        end;
      else
        PropValueError;
    end;
  end;

end.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf