You are not logged in.
Pages: 1
Hi,
I've a TMemorystream containing a fastreport file (xml) that I want to save onto a blob field but this code doesn't work
try
Stream := TMemoryStream.Create;
Stream.Position := 0;
Report.SaveToStream(Stream);
ShowMessage(ReadStringFromStream(Stream)); <--- Empty string although Stream.Size = 1828
finally
Stream.Free;
end;
Offline
Report.SaveToStream(Stream);
Stream.seek(0,0);
Last edited by DigDiver (2014-05-26 06:12:31)
Offline
Sorry but it doesn't work for me, I've already an empty string !!
Offline
Indeed.
I've just enhanced the doc about ReadStringFromStream() to make it clear.
See http://synopse.info/fossil/info/518822d716
Online
Hi AB,
It doesn't work for me When I've updated the source with the latest one, I got this compilation error in syncommons.pas at line 25231
[Erreur fatale] SynCommons.pas(25231): Erreur interne : C3950
I'm on D7 and win8
Last edited by tech (2014-05-26 09:01:27)
Offline
I forgot the MaxAllowedSize parameter then I put :
Report.SaveToStream(msStream);
msStream.seek(0,soBeginning);
msStream.Read(L,4);
ShowMessage(ReadStringFromStream(msStream, L));
and I got an Out of memory here
function ReadStringFromStream(S: TStream; MaxAllowedSize: integer): RawUTF8;
var L: integer;
begin
result := '';
L := 0;
if (S.Read(L,4)<>4) or (L<=0) or (L>MaxAllowedSize) then
exit;
SetLength(Result,L); <--------------------- out of memory L = 1702240364
if S.Read(pointer(result)^,L)<>L then
result := '';
end;
Offline
ReadStringFromStream() does not work with any stream.
It does work only as reverse function to WriteStringToStream.
For instance:
WriteStringToStream(Stream,aUTF8Text);
Stream.Seek(0,soBeginning);
str := ReadStringFromStream(Stream);
So for your purpose, you should NOT use ReadStringFromStream() at all.
The easiest is in fact to use our TRawByteStringStream class, as such:
var Stream: TRawByteStringStream;
...
Stream := TRawByteStringStream.Create;
try
Report.SaveToStream(Stream);
// Stream.DataString now contains the text
finally
Stream.Free;
end;
Note that TRawByteStringStream uses 8 bit string (i.e. a RawByteString) so your Report.SaveToStream() should create UTF-8 content.
BTW, I do not have any problem with Delphi 7 compilation of the latest trunk revision.
Perhaps quit and reopen the IDE, try to delete all you .dcu files, and force a rebuild of the project.
Online
Ok AB it works now with TRawByteStringStream thnx,
BTW, the compilation error persists although I restarted the IDE and tryed to compile "01 - In Memory ORM" sample.
Offline
Hi AB,
The TRawByteStringStream works fine but I've the UTF-8 content problem. Normaly fastreport creates a UTF-8 content but when I put a text "Libellé" on the report and save it, I got on the database "Libelé".
How can I fix that ?
BTW, the new version of mORMot compiles fine with D7.
Offline
"Libelé" is "Libellé" encoded in UTF-8.
Prior to Delphi 2009, the Delphi string type does not have an encoding, so it assumes that it is encoded with the system code page of non unicode applications.
You can use RawUTF8ToString() to convert a RawUTF8 into a Delphi 7 ansi string.
But within mORMot, UTF-8 is used everywhere, up to the database.
Which DB are you using?
Online
Now I'm using SQLite but for the future I'll use perhaps Firebird.
I don't see where can I use RawUTF8ToString() on the Report.saveToStream ?
Thnx
Offline
The class :
TSQLEtat = class(TSQLRecord)
private
fLibelle : RawUTF8;
fFiche : RawUTF8;
fEtat : TSQLRawBlob;
published
property ManCode : RawUTF8 index 10 read fManCode write fManCode stored AS_UNIQUE;
property Fiche : RawUTF8 index 20 read fFiche write fFiche;
property Etat : TSQLRawBlob read fEtat write fEtat;
end;
The function to save the report :
function TF_Etat.frxDesigner1SaveReport(Report: TfrxReport;
SaveAs: Boolean): Boolean;
var Stream: TRawByteStringStream;
fEtat : TSQLEtat;
begin
try
fEtat := TSQLEtat.Create;
Stream := TRawByteStringStream.Create;
Stream.Position := 0;
Report.SaveToStream(Stream);
Stream.seek(0,soBeginning);
fEtat.Etat := S2U(Stream.DataString);
globalClient.Add(fetat, true);
finally
fEtat.Free;
Stream.Free;
end;
end;
The function to load the report :
function TF_Etat.LoadFromStream():boolean;
var Stream : TMemoryStream;
begin
if not globalClient.RetrieveBlobFields(fEtat) then
begin
result := False;
exit;
end
else
result := True;
try
Stream := TMemoryStream.Create;
WriteStringToStream(Stream, fEtat.Etat);
if (Stream.Size > 0) and (fEtat.Etat <> '') then
begin
Stream.Position := 0;
frxReport.LoadFromStream(Stream);
frxReport.ShowReport();
end
else
result := False;
finally
Stream.Free;
end;
end;
Last edited by tech (2014-06-18 15:44:08)
Offline
You are storing a BLOB in the database, not UTF-8.
I would rather define a TEXT field here:
TSQLEtat = class(TSQLRecord)
private
fLibelle : RawUTF8;
fFiche : RawUTF8;
fEtat : RawUTF8;
published
property ManCode : RawUTF8 index 10 read fManCode write fManCode stored AS_UNIQUE;
property Fiche : RawUTF8 index 20 read fFiche write fFiche;
property Etat : RawUTF8 read fEtat write fEtat; // without "index ??" to force a CLOB
end;
And then the following line should write good UTF-8, as expected:
fEtat.Etat := S2U(Stream.DataString);
You may also leave "Etat: TSQLRawBlob", then UTF-8 will be stored as BLOB.
And reported as such.
Online
I've changed the TSQRawBlob by RawUTF8 but it doesn't work for me, I've already this following line on the save function
fEtat.Etat := S2U(Stream.DataString);
I think that because of this line that I got that "Libelé", now we need to convert U2S for this line
WriteStringToStream(Stream, fEtat.Etat);
Offline
Yes, and the exe created a new db file.
Offline
Hi AB,
I've convert the TMemoryStream to TStringStream and that works fine with U2S on the loadfromStream function
function TF_Etat.LoadFromStream():boolean;
var Stream : TStringStream; <---------------------------------- Modification
begin
if not globalClient.RetrieveBlobFields(fEtat) then
begin
result := False;
exit;
end
else
result := True;
try
Stream := TStringStream.Create(u2S(fEtat.Etat)); <----------------- Conversion u2s
//WriteStringToStream(Stream, fEtat.Etat);
if (Stream.Size > 0) and (fEtat.Etat <> '') then
begin
Stream.Position := 0;
frxReport.LoadFromStream(Stream);
frxReport.ShowReport();
end
else
result := False;
finally
Stream.Free;
end;
end;
Thnx
Offline
Pages: 1