On 06 Sep 2013, at 13:54, Hans-Peter Diettrich wrote:

> Jonas Maebe schrieb:
>>  o merged cpstrrtl branch (includes unicode branch). In general, this adds
>>    support for arbitrarily encoded ansistrings to many routines related to
>>    file system access (and some others).
>>      WARNING: while the parameters of many routines have been changed from
>>    "ansistring" to "rawbytestring" to avoid data loss due to conversions,
>>    this is not a panacea. If you pass a string concatenation to such a
>>    parameter and not all strings in this concatenation have the same
>>    code page, all strings and the result will be converted to
>>    DefaultSystemCodePage (= ansi code page by default).
> 
> That conversion IMO is done by the every concatenation, apart from subroutine 
> considerations.

I think you mean "afaik" rather than "IMO". Anyway, the resulting code page of 
a concatenation is normally the code page of whatever you assign the string to 
(so if you assign to an utf8string, the resulting code page will be CP_UTF8). 
RawByteString is different in two ways:
a) if all concatenated strings have the same code page, the result also gets 
that code page
b) if there are different code pages involved, the result gets 
DefaultSystemCodePage

I think we could actually introduce a global variable in the system unit that 
changes the behaviour of b) to "the result will have a code page that can 
represent all characters from the concatenated strings", which by default is 
off. Turning it on should even break most Delphi code, since when a parameter 
or variable is RawByteString then the code should be able to deal with any 
possible single byte code page anyway.

> Delphi has overloaded functions for RawByteString and AnsiString(0).

Does this really compile in Delphi?

type
  tcp866 = type ansistring(866);
  tutf8string = type ansistring(65001);

procedure test(const a: ansistring); overload;
begin
  writeln('ansistring');
end;

procedure test(const a: rawbytestring); overload;
begin
  writeln('rawbytestring');
end;

procedure test(const a: tutf8string); overload;
begin
  writeln('utf8string');
end;


var
  a: ansistring;
  b: tcp866;
begin
  test('abc');
  a:='ab';
  b:='c';
  test(a);
  test(b);
  test(a+b);
end.

Besides, utf8 *overloads* would be useless since even if the above compiles and 
has some sensible behaviour, such overloads would only be called if you pass in 
an utf8string. That already works correctly today. The problem is when passing 
in concatentations of strings.

> I'm not sure how efficient a RawByteString version ever can be. By default it 
> has to convert the string into Unicode (Delphi: UTF-16),

No, see Sven's answer.

> and the result back to CP_ACP. In these cases it looks more efficient to call 
> the Unicode version immediately, and leave *eventual* further conversions to 
> the compiler. Some routines may implement common processing of true SBCS, but 
> I'm not sure how many these are.

Even if you are on a platform with UTF-16 system interfaces, if you call the 
routine with a single byte string, then calling the rawbytestring version will 
always be more efficient than the unicodestring version because the code size 
will be smaller (the conversions are inside the wrapper rather than everywhere 
in your code where you call this routine). These routines do not convert more 
than necessary.

>>  + SetMultiByteFileSystemCodePage() procedure to override the value of
>>    DefaultFileSystemCodePage
>>  + ToSingleByteFileSystemEncodedFileName() function to convert a string to to
>>    DefaultFileSystemCodePage (does *not* take care of OS-specific quirks like
>>    Darwin always returning file names in decomposed UTF-8)
>>  + support for CP_OEMCP
>>  * textrec/filerec now store the filename by default using widechar. It is
>>    possible to switch back to ansichars using the FPC_ANSI_TEXTFILEREC 
>> define.
>>    In that case, from now on the filename will always be stored in
>>    DefaultFileSystemEncoding
> 
> Does there exist a FileSystemString type, for easy use in RTL and application 
> code?

No, and you should be completely oblivious to it. Adding new magic code pages 
or string types to the existing mess would not be helpful. Use utf8string or 
unicodestring if you want to ensure that you don't have data loss. The 
DefaultFileSystemCodePage only exists to ensure that
a) no data is lost between you giving a string to an RTL routine and calling a 
single byte OS API
b) file names returned by single byte OS APIs are correctly handled/interpreted 
by the RTL and get their code page set correctly


Jonas_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to