Subject | Re: UDF & unicode_FSS & delphi widestring ... |
---|---|
Author | Svend Meyland Nicolaisen |
Post date | 2007-12-18T16:41:45Z |
Well actually 8 is also a little to much. One Unicode character needs
between 1 and 4 bytes in UTF-8 encoding. So it should have been
Len:=Length(Res)*4+1. Additionally unicode codepoints above 0xffff takes two
UTF-16 LE characters so you might get away with only multiplying by 3.
Alternatively you could let WideCharToMultiByte calculate the required
buffer size by calling it twize setting the buffer length to 0 the first
time.
I dont know MakeResultString but you propably can do the following:
function F_StringTo2WHex(const Str: PChar): PChar; var res : wideString;
Len: Integer;
S: string;
Begin
Len:=StrLen(Str);
SetLength(Res,Len);
Len:=MultiByteToWideChar(CP_UTF8,0,Str,-1,PWideChar(Res),Len+1);
if Len=0
Some Error Handling
else
begin
SetLength(Res,Len-1);
Do what you want with the widestring Res
Len:=Length(Res)*4+1;
SetLength(S,Len);
Len:=WideCharToMultiByte(CP_UTF8,0,PWideChar(Res),-1,PChar(S),Len+1,nil,nil)
;
if Len=0 then
Some error handling
else
begin
SetLength(S,Len-1);
Result:=MakeResultString(S,nil,0);
end;
end;
end;
Please review the code carefully yourself, because I havent. :-) You
propably also want to split the convertion between UTF8 and UTF16 into
seperate functions.
/Svend
________________________________
From: firebird-support@yahoogroups.com
[mailto:firebird-support@yahoogroups.com] On Behalf Of mnavahan
Sent: 18. december 2007 14:18
To: firebird-support@yahoogroups.com
Subject: [firebird-support] Re: UDF & unicode_FSS & delphi widestring ...
--- In firebird-support@yahoogroups.com
<mailto:firebird-support%40yahoogroups.com> , "Svend Meyland Nicolaisen"
Hi
thx of help but some line not understand by me :
Len:=Length(Res)*8;
S:=ib_util_malloc(Len);
why *8 ?
also i do not use ib_util_malloc
i use MakeResultString and in start need one function echo text from UDF :
function EchoText(ShStr: PChar): PChar;
var
s : string;
begin
WriteDebug('Left() - Enter');
S := String(ShStr);
result := MakeResultString(PChar(s), nil, 0); end;
function MakeResultString(Source, OptionalDest: PChar; Len: DWORD):
PChar;
begin
result := OptionalDest;
if (Len = 0) then
Len := StrLen(Source) + 1;
if (result = nil) then begin
{$ifdef FREE_IT}
result := malloc(Len);
{$else}
with ThreadLocals do begin
if (FPCharSize < Len) or
(FPCharSize > Len + cSignificantlyLarger) then begin FPCharSize := 0; than
while (FPCharSize < Len) do Inc(FPCharSize, cSignificantlyLarger);
ReallocMem(FPChar, FPCharSize); end; result := FPChar; end; {$endif} end;
between 1 and 4 bytes in UTF-8 encoding. So it should have been
Len:=Length(Res)*4+1. Additionally unicode codepoints above 0xffff takes two
UTF-16 LE characters so you might get away with only multiplying by 3.
Alternatively you could let WideCharToMultiByte calculate the required
buffer size by calling it twize setting the buffer length to 0 the first
time.
I dont know MakeResultString but you propably can do the following:
function F_StringTo2WHex(const Str: PChar): PChar; var res : wideString;
Len: Integer;
S: string;
Begin
Len:=StrLen(Str);
SetLength(Res,Len);
Len:=MultiByteToWideChar(CP_UTF8,0,Str,-1,PWideChar(Res),Len+1);
if Len=0
Some Error Handling
else
begin
SetLength(Res,Len-1);
Do what you want with the widestring Res
Len:=Length(Res)*4+1;
SetLength(S,Len);
Len:=WideCharToMultiByte(CP_UTF8,0,PWideChar(Res),-1,PChar(S),Len+1,nil,nil)
;
if Len=0 then
Some error handling
else
begin
SetLength(S,Len-1);
Result:=MakeResultString(S,nil,0);
end;
end;
end;
Please review the code carefully yourself, because I havent. :-) You
propably also want to split the convertion between UTF8 and UTF16 into
seperate functions.
/Svend
________________________________
From: firebird-support@yahoogroups.com
[mailto:firebird-support@yahoogroups.com] On Behalf Of mnavahan
Sent: 18. december 2007 14:18
To: firebird-support@yahoogroups.com
Subject: [firebird-support] Re: UDF & unicode_FSS & delphi widestring ...
--- In firebird-support@yahoogroups.com
<mailto:firebird-support%40yahoogroups.com> , "Svend Meyland Nicolaisen"
Hi
thx of help but some line not understand by me :
Len:=Length(Res)*8;
S:=ib_util_malloc(Len);
why *8 ?
also i do not use ib_util_malloc
i use MakeResultString and in start need one function echo text from UDF :
function EchoText(ShStr: PChar): PChar;
var
s : string;
begin
WriteDebug('Left() - Enter');
S := String(ShStr);
result := MakeResultString(PChar(s), nil, 0); end;
function MakeResultString(Source, OptionalDest: PChar; Len: DWORD):
PChar;
begin
result := OptionalDest;
if (Len = 0) then
Len := StrLen(Source) + 1;
if (result = nil) then begin
{$ifdef FREE_IT}
result := malloc(Len);
{$else}
with ThreadLocals do begin
if (FPCharSize < Len) or
(FPCharSize > Len + cSignificantlyLarger) then begin FPCharSize := 0; than
while (FPCharSize < Len) do Inc(FPCharSize, cSignificantlyLarger);
ReallocMem(FPChar, FPCharSize); end; result := FPChar; end; {$endif} end;