Difference between revisions of "FPC Unicode support/fr"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting)
 
(33 intermediate revisions by 4 users not shown)
Line 7: Line 7:
  
 
Le support au niveau du langage de FPC est déjà disponible dans les versions en cours de développement du compilateur (FPC 2.7.1/trunk). Le support au niveau RTL n'est pas encore complet. Cette page donne une vue d'ensemble des comportements relatifs à la page de code pour ces types de chaînes, le niveau actuel du support par la RTL et des possibles voies d'amélioration futures pour ce support.
 
Le support au niveau du langage de FPC est déjà disponible dans les versions en cours de développement du compilateur (FPC 2.7.1/trunk). Le support au niveau RTL n'est pas encore complet. Cette page donne une vue d'ensemble des comportements relatifs à la page de code pour ces types de chaînes, le niveau actuel du support par la RTL et des possibles voies d'amélioration futures pour ce support.
 +
 +
= Compatibilité ascendante =
 +
Si vous avez du code existant qui marche d'une façon connue (*) avec une version antérieure de FPC et que vous ne faites aucun changement, il devrait continuer à fonctionner non modifié avec la nouvelle verison de FPC. Garantir tel est le but principal de la multitude de variables de page de code et leurs valeurs par défaut, comme décrit ci-dessous.
 +
 +
(*) cela veut dire this principalement : vous ne stockez pas de donnée dans une AnsiString qui a été encodée par autre chose que la page de code par défaut du système et par la suite passe cette chaîne tel quelle à une routine RTL de FPC. Par exemple, le code actuel de Lazarus est bien en général, comme vous êtes censés appeler UTF8ToAnsi() avant de passer ses chaînes aux routines RTL de FPC.
  
 
= Code pages =
 
= Code pages =
Line 13: Line 18:
  
 
== Identificateurs de page de code  ==
 
== Identificateurs de page de code  ==
A code page identifier is always stored as a ''TSystemCodePage'', which is an alias for [[Word]]. The value represents the corresponding code page as defined by [http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx Microsoft Windows]. Additionally, there are 3 special code page values:
+
Un identificateur de page de code est toujours enregistré comme un ''TSystemCodePage'', qui est un alias pour [[Word/fr|Word]]. La valeur représente la page de code correspondante telle que définie par [http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx Microsoft Windows]. En plus, il y a 3 valeurs spéciales de code de page :
* CP_ACP: this value represents the currently set "default system code page". See [[#Code page settings]] for more information.
+
* CP_ACP: cette valeur représente la "page de code par défaut" en cours. Voir [[#Réglage de la page de code]] pour plus d'information.  
* CP_OEM: this value represents the OEM code page. On Windows platforms this corresponds to the code page used by the console (e.g. cmd.exe windows). On other platforms this value is interpreted the same as CP_ACP.
+
* CP_OEM: cette valeur représente la page de code OEM. Sur les plates-formes Windows, ceci correspond à la page de code utilisée par la console (par exemple les fenêtres cmd.exe). Sur d'autres plates-formes, cette valeur est interprétée de la même façon que CP_ACP.
* CP_NONE: this value indicates that no code page information has been associated with the string data. The result of any explicit or implicit operation that converts this data to another code page is undefined.
+
* CP_NONE: cette valeur indique qu'aucune information de page de code n'a été associée avec la donnée chaîne. Le résultat de toute opération explicite ou implicite qui convertit cette donnée en une autre page de code est indéfinie
  
Note: code page identifiers are different from codepage names as used in the ''[http://www.freepascal.org/docs-html/prog/progsu88.html {$codepage xxx}]'' directives (which is available in current stable FPC already). Codepage names are the names of individual codepage units exposed by the charset unit, which have names such as ''cp866'' and ''cp1251'' and ''utf8''.
+
Note: les identificateurs de page de code sont différent des noms de page de code tels qu'ils sont utilisés dans la directive ''[http://www.freepascal.org/docs-html/prog/progsu88.html {$codepage xxx}]'' (qui est déjà disponible dans la version stable de FPC). Les noms de page de code sont des noms d'unités individuelles de page de code exposés dans l'unité de jeu de caractères, qui ont des noms tels que ''cp866'' et ''cp1251'' et ''utf8''.
  
== Code page settings ==
+
== Réglage de la page de code ==
The system unit contains several global variables that indicate the default code page used for certain operations.
+
L'unité system contient plusieurs variables globales qui indiquent la page de code par défaut utilisée par certaines opérations.
  
 
=== DefaultSystemCodePage ===
 
=== DefaultSystemCodePage ===
* '''Purpose''': determines how CP_ACP is interpreted
+
* '''Usage''': détermine comment CP_ACP est interprété
* '''Initial value''':
+
* '''Valeur initiale''':
** Windows: The result of the ''GetACP'' OS call, which returns the Windows ANSI code page.
+
** Windows: C'est le résultat de l'appel système à ''GetACP'', qui retourne la page de code ANSI de Windows.
 
** iOS: UTF-8
 
** iOS: UTF-8
** Unix (excluding iOS): Based on the currently set ''LANG'' or ''LC_CTYPE'' environment variables. This is usually UTF-8, but that is not guaranteed to be the case.
+
** Unix (sauf iOS): Basé sur le réglage actuel des variables d'environnement ''LANG'' ou ''LC_CTYPE''. C'est en général UTF-8, mais il n'est pas garanti que cela soit le cas.
** Other platforms: CP_ACP (these platforms currently do not support multiple code pages, and are hardcoded to use their OS-specific code page in all cases)
+
** Autres plates-formes: CP_ACP (ces plates-formes ne supportent actuellement pas les pages de code multiples, et sont codés en dur pour utiliser la page de code spécifique au système dans tous les cas)
* '''Modifications''': you can modify this value by calling ''SetMultiByteConversionCodePage(CodePage: TSystemCodePage)''
+
* '''Modifications''': vous pouvez modifier cette valeur en appelant ''SetMultiByteConversionCodePage(CodePage: TSystemCodePage)''
* '''Notes''': Since the value of this variable can be changed, it is not a good idea to use its value to determine the real OS "default system code page" (unless you do it at program startup and are certain no other unit has changed it in its initialisation code).
+
* '''Notes''': Depuis que cette variable peut être modifiée, ce n'est plus une bonne idée d'utiliser cette valeur pour déterminer la "page de code par défaut" réelle du système (à moins de le faire au démarrage du programme et d'être certain qu'aucune autre unité ne l'a changé dans son code d'initialisation).
  
 
=== DefaultFileSystemCodePage ===
 
=== DefaultFileSystemCodePage ===
* '''Purpose''': defines the code page to which file/path names are translated before they are passed to OS API calls, '''''if''''' the RTL uses a single byte OS API for this purpose on the current platform. This code page is also used for intermediate operations on file paths inside the RTL before making OS API calls.
+
* '''Usage''': Définit la page de code vers laquelle les noms de chemin/fichier sont traduits avant d'être passé lors d'un appel à une API système, '''''si''''' la RTL utilise une API système à simple octet pour cette usage sur la plate-forme courante. Ce page de code est aussi utilisée pour les opérations intermédiaires sur les chemins d'accès dans la RTL avant de faire des appels aux API système. Cette variable n'existe pas dans Delphi et a été introduite dans FPC pour rendre possible le changement de valeur de ''DefaultSystemCodePage'' sans casser les interfaces RTL avec les appels du système de fichier du système d'exploitation.
* '''Initial value''':
+
 
** Windows: UTF-8, because the RTL uses UTF-16 OS API calls (so no data is lost in intermediate operations).
+
* '''Valeur initiale''':
** OS X and iOS: UTF-8 (as defined by Apple)
+
** Windows: UTF-8, parce que la RTL utilise des appels aux API système UTF-16 (donc aucune donnée n'est perdue dans les opérations intermédiaires).
** Unix (excluding OS X and iOS): DefaultSystemCodePage, because the encoding of file names is undefined on Unix platforms (it's an untyped array of bytes that can be interpreted in any way; it is not guaranteed to be valid UTF-8)
+
** OS X and iOS: UTF-8 (comme défini par Apple)
** Other platforms: same as DefaultSystemCodePage
+
** Unix (mis à part OS X et iOS): DefaultSystemCodePage, parce que l'encodage des fichiers est indéfini sur les plates-formes Unix (c'est un tableau non typé d'octets qui peut être interprété comme on veut ; il n'est pas garanti d'être de l'UTF-8 valide)
* '''Modifications''': you can modify this value by calling ''SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage)''
+
** Autres plates-formes: identique à DefaultSystemCodePage
* '''Notes''': the Unix/OS X/iOS settings only apply in case the ''cwstring'' widestring manager is installed, otherwise DefaultFileSystemCodePage will have the same value as DefaultSystemCodePage after program startup.
+
* '''Modifications''': vous pouvez modifier cette valeur en appelant ''SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage)''
 +
* '''Notes''': Les réglages Unix/OS X/iOS s'appliquent seulement dans le cas où le gestionnaire de widestring ''cwstring'' est installé, sinon DefaultFileSystemCodePage aura la même valeur que DefaultSystemCodePage après le démarrage du programme.
  
 
=== DefaultRTLFileSystemCodePage ===
 
=== DefaultRTLFileSystemCodePage ===
* '''Purpose''': defines the code page to which file/path names are translated before they are returned from RawByteString file/path RTL routines. Examples include the file/path names returned by the RawbyteString versions of ''SysUtils.FindFirst'' and ''System.GetDir''. The main reason for its existence is to enable the RTL to provide backward compatibility with earlier versions of FPC, as these always returned strings encoded in whatever the OS' single byte API used (which was usually what is now known as ''DefaultSystemCodePage'').
+
* '''Usage''': définit la page de code vers laquelle les noms de fichier/chemin sont traduits avant d'être retournées par les routines RTL pour les fichier/chemin RawByteString. Des exemples sont dans les noms de fichier/chemin retournés par les versions RawbyteString de ''SysUtils.FindFirst'' et ''System.GetDir''. La principale raison de son existence est de rendre la RTL capable de fournir la compatibilité ascendante avec les versions antérieures de FPC, comme celles-ci retournaient toujours des chaînes encodées pour les API système en simple octet utilisées (qui étaient habituellement ce qui est connu maintenant comme ''DefaultSystemCodePage'').
* '''Initial value'''
+
* '''Valeur initiale'''
** Windows: DefaultSystemCodePage, for backward compatibility.
+
** Windows: DefaultSystemCodePage, pour compatibilité ascendante.
** OS X and iOS: UTF-8, for backward compatibility (it was already always UTF-8 in the past, since that's what the OS file APIs return and we did not convert this data).
+
** OS X and iOS: UTF-8, pour compatibilité ascendante (c'était déjà toujours UTF-8 dans le passé, puisque c'est ce que les API de fichiers de l'OS retourne et nous ne convertissions pas cette donnée).  
** Unix (excluding OS X and iOS): DefaultSystemCodePage, for the same reason as with DefaultFileSystemCodePage. Setting this to a different value than DefaultFileSystemCodePage is a bad idea on these platforms, since any code page conversion can corrupt these strings as their initial encoding is unknown.
+
** Unix (mis à part OS X et iOS): DefaultSystemCodePage, pour la même raison qu'avec DefaultFileSystemCodePage. Régler celle-ci à une autre valeur que DefaultFileSystemCodePage est une mauvaise idées sur ces plates-formes, puisque toute conversion peut corrompre ces chaînes car leur encodage initial est inconnu.
** Other platforms: same as DefaultSystemCodePage
+
** Autres plates-formes: comme pour DefaultSystemCodePage
* '''Modifications''': you can modify this value by calling ''SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage)''
+
* '''Modifications''': Vous pouvez modifier cette valeur en appelant ''SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage)''
* '''Notes''': same as for DefaultFileSystemCodePage.
+
* '''Notes''': les mêmes que pour DefaultFileSystemCodePage.
 +
 
 +
== Page de code du fichier source ==
 +
 
 +
La ''page de code du fichier source''détermine comment [[#String constants|les constantes de chaîne]] sont interprétées et où le compilateur insèrera l'opération de conversion de la page de code à [[#Page de code dynamique|l'affectation d'un type de chaîne vers un autre]].
 +
 
 +
La page de code du fichier source est déterminée de la façon suivante:
 +
* Si le fichier contient une directive ''{$codepage xxx}'' (p.ex. <code>{$codepage UTF8}</code>), alors le page de code du fichier source est cette page de code, sinon
 +
* Si le fichier commence par un UTF-8 BOM, alors la page de code du fichier source est UTF-8, sinon
 +
* Si ''{$modeswitch systemcodepage}'' est active, la page de code du fichier source est la ''DefaultSystemCodePage'' '''''de l'ordinateur sur lequel le compilateur lui-même s'exécute'''''  (i.e., la compilation du code source peut créer un programme qui se comporte différemment sur un autre système; cette bascule est disponible pour la compatibilité avec Delphi et est activée par défaut avec ''{$mode delphiunicode}''), sinon
 +
* la page de code du fichiers source est définie comme CP_ACP (pour compatibilité ascendante avec les versions antéreures de FPC)
  
 
= Strings =
 
= Strings =
Line 58: Line 74:
  
 
=== Shortstring ===
 
=== Shortstring ===
The code page of a shortstring is implicitly CP_ACP and hence will always be equal to the current value of DefaultSystemCodePage.
+
La page de code d'une shortstring est implicitement CP_ACP d'où elle sera toujours égale à la valeur courante de DefaultSystemCodePage.
  
 
=== PAnsiChar/AnsiChar ===
 
=== PAnsiChar/AnsiChar ===
These types are the same as the old PChar/Char types. In all compiler modes except for ''{$mode delphiunicode}'', PChar/Char are also still aliases for PAnsiChar/AnsiChar. Their code page is implicitly CP_ACP and hence will always be equal to the current value of DefaultSystemCodePage.
+
Ces types sont les mêmes que les anciens types PChar/Char. Dans tous les modes du compilateur sauf pour ''{$mode delphiunicode}'', PChar/Char sont aussi encore des alias pour PAnsiChar/AnsiChar. Leur page de code est implicitement CP_ACP et donc toujours égale à la valeur courante de DefaultSystemCodePage.
  
=== PWideChar/PUnicodeChar and WideChar/UnicodeChar ===
+
=== PWideChar/PUnicodeChar et WideChar/UnicodeChar ===
These types remain unchanged. WideChar/UnicodeChar can contain a single UTF-16 code unit, while PWideChar/PUnicodeChar point to a single or an array of UTF-16 code units.
+
Ces types demeurent inchangés. WideChar/UnicodeChar peuvent contenir une simple unité de code UTF-16, alors que PWideChar/PUnicodeChar pointe sur une simple unité de code ou un tableau d'unités de code en UTF-16.
  
In ''{$mode delphiunicode}'', PChar becomes an alias for PWideChar/PUnicodeChar and Char becomes an alias for WideChar/UnicodeChar.
+
En ''{$mode delphiunicode}'', PChar devient un alias de PWideChar/PUnicodeChar et Char devient un alias de WideChar/UnicodeChar.
  
 
=== UnicodeString/WideString ===
 
=== UnicodeString/WideString ===
These types behave the same as in previous versions:
+
Ces types se comporte comme dans les versions précédentes:
* ''Widestring'' is the same as a "COM BSTR" on Windows, and an alias for UnicodeString on all other platforms. Its string data is encoded using UTF-16.
+
* ''Widestring'' est le même qu'un "COM BSTR" dans Windows et un alias de UnicodeString sur toutes les autres plates-formes. Sa chaîne de données est encodée avec de l'UTF-16.
* ''UnicodeString'' is a reference-counted string with a maximum length of high(SizeInt) UTF-16 code units.
+
* ''UnicodeString'' est une chaîne à comptage de référence avec une longueur maximale de high(SizeInt) en unités de code UTF-16.
  
 
=== Ansistring ===
 
=== Ansistring ===
AnsiStrings are reference-counted types with a maximum length of high(SizeInt) bytes. Additionally, they now also have code page information associated with them.
+
Les AnsiStrings sont des chaînes à comptage de références avec une longueur maximal de high(SizeInt) octets. En plus, une information de code de page peut maintenant leur être associée.
  
The most important thing to understand about the new AnsiString type is that it both has a declared/static/preferred/default code page (called ''static code page'' from now on), and a dynamic code page. The static code page tells the compiler that when assigning something to that AnsiString, it should first convert the data to that static code page (except if it is CP_NONE, see [[#RawByteString]] below). The dynamic code page is a property of the AnsiString which, similar to the length and the reference count, defines the actual code page of the data currently held by that AnsiString.
+
La chose la plus importante à comprendre sur le nouveau type AnsiString est qu'il a à la fois une page de code déclarée/statique/préférée/par défaut (appelée ''page de code declarée'' à partir de maintenant), et une page de code dynamique. La page de code declarée dit au compilateur que lorsqu'on affecte quelque chose à cet AnsiString, il devrait d'abord convertir cette donnée vers cette page de code (sauf si c'est CP_NONE, voir [[#RawByteString|RawByteString]] plus bas). La page de code dynamique est une propriété de l'AnsiString qui, tels la longueur et le compteur de référence, définit la page de code en cours des données actuellement tenues par cette AnsiString.
  
==== Static code page ====
+
==== Page de code declarée ====
The static code page of an AnsiString can only be defined by declaring a new type as follows:
+
La page de code declarée d'une AnsiString peut seulement être définie en déclarant un nouveau type comme suit:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
type
 
type
 
   CP866String = type AnsiString(866); // note the extra "type"
 
   CP866String = type AnsiString(866); // note the extra "type"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The static code page of a variable declared as plain ''AnsiString'' is CP_ACP. In effect, the AnsiString type is now semantically defined in the System unit as
+
La page de code declarée d'une variable déclarée comme pure ''AnsiString'' est CP_ACP. En effet, le type AnsiString est maintenant sémantiquement défini dans l'unité System comme:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
type
 
type
 
   AnsiString = type AnsiString(CP_ACP);
 
   AnsiString = type AnsiString(CP_ACP);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Another predefined AnsiString(X) type in the System unit is UTF8String:
+
Un autre type AnsiString(X) prédéfini dans l'unité System est UTF8String:
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
type
 
type
 
   UTF8String = type AnsiString(CP_UTF8);
 
   UTF8String = type AnsiString(CP_UTF8);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Once you have defined such a custom AnsiString(X) type, you can use it to declare variables, parameters, fields etc as usual.
+
Une fois que vous avez défini tel type AnsiString(X), vous pouvez l'utiliser pour déclarer des variables, des paramètres, champs etc comme d'habitude.
 +
 
 +
Notez que CP_UTF16 et CP_UTF16BE ne sont pas valides comme page de code pour les AnsiStrings. Ce qui peut résulter d'une telle définition est indéfini.
 +
 
 +
==== Page de code dynamique ====
 +
Si une chaîne d'une page de code declarée X1 est affectée par une chaîne d'une pafe de code X2, alors:
 +
* si (X1 = CP_NONE) ou (X2 = CP_NONE), voir [[#RawByteString|RawByteString]], sinon
 +
* si (la page de code du source <> CP_ACP), alors si (X2 = CP_ACP) et (X1 = page de code du fichier source) ou vice-versa, aucune conversion ne sera faite (même si à l'exécution, ''DefaultSystemCodePage'' a une valeur différente de la page de code du fichier source). La raison pour la condition (page de code du source <> CP_ACP) est la compatibilité ascendante avec les versions antérieures de FPC (alors qu'elles ne prennent pas en charge AnsiStrings avec des pages de codes arbitraires, elles réinterprètaient toujours AnsiStrings en fonction de la valeur actuelle de la page de code du système). Sinon
 +
* si (X1 <> X2), la donnée chaîne sera convertie de la page de code X1 vers la page de code X2 avant affectation, par laquelle CP_ACP sera interprétée comme la valeur actuelle de ''DefaultSystemCodePage''. Sinon,
 +
* Si (X1 = X2), aucune coversion de page de code ne sera réalisée.
  
==== Dynamic code page ====
+
Ces règles signifient qu'il est parfaitement possible pour une variable AnsiString d'avoir une page de code dynamique qui diffère de sa page de code declarée. P.ex. dans le troisième cas, X1 pourrait être CP_ACP, alors qu'après affectation, il pourrait avoir un page de code dynamique égale à ''DefaultSystemCodePage''.
If a string with a static code page X1 is assigned to a string with static code page X2 and X1<>X2, the string data will generally first be converted to said code page X2 before assignment, and as a result the dynamic code page of the destination string will be X2. When assigning a string to a plain AnsiString (= AnsiString(CP_ACP)) or ShortString, the string data will however be converted to DefaultSystemCodePage. The dynamic code page of that AnsiString(CP_ACP) will then be the current value of DefaultSystemCodePage (e.g. 1250 for the Windows-1250 code page), even though its static code page is CP_ACP (which is a constant <> 1250). This is one example of how the static code page can differ from the dynamic code page. Subsequent sections will describe more such scenarios.
 
  
Note: as mentioned above, whether or not a potential code page conversion happens only depends on the ''static code pages'' of the involved strings. This means that if you assign one AnsiString(X) to another AnsiString(X) and the former's dynamic code was different from X, the string data will ''not'' be converted to code page X by the assignment.
+
Note: comme mentionné au-dessus, qu'une conversion potentielle de page de code survienne ou pas dépend seulement de la ''page de code declarée'' des chaînes impliquées. Cela signifie que si vous affectez une AnsiString(X) à une autre AnsiString(X) et que l'ancienne page de code dynamique était différente de X, la chaîne ne sera ''pas'' convertie vers la page de code X par l'affectation.
  
 
==== RawByteString ====
 
==== RawByteString ====
The RawByteString type is defined as
+
Le type RawByteString est défini comme
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
type
 
type
 
   RawByteString = type AnsiString(CP_NONE);
 
   RawByteString = type AnsiString(CP_NONE);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
As mentioned earlier, the results of conversions from/to the CP_NONE code page are undefined. As it does not make sense to define a type in the RTL whose behaviour is undefined, the behaviour of RawByteString is somewhat different than that of other AnsiString(X) types.
+
Comme mentionné avant, les résultats de conversions de/vers la page de code CP_NONE sont indéfinis. Comme cela n'a pas de sens de définir un type dans la RTL dont le comportement est indéfini, le comportement de RawByteString est quelque peu différent des autres types AnsiString(X).
  
As a first approximation, ''RawByteString'' can be thought of as an "untyped AnsiString": assigning an AnsiString(X) to a RawByteString has exactly the same behaviour as assigning that AnsiString(X) to another AnsiString(X) variable with the same value of X: no code page conversion or copying occurs, just the reference count is increased.
+
Comme première approximation, ''RawByteString'' paut être considéré comme un "AnsiString non typé": affecter une AnsiString(X) vers une RawByteString a exactement le même comportement que d'affecter cet AnsiString(X) vers une autre variable AnsiString(X) avec la même valeur de X: aucune conversion de page de code ou copie ne se passe, seul le compteur de référence est incrémenté.
  
Less intuitive is probably that when a RawByteString is assigned to an AnsiString(X), the same happens: no code page conversion or copying, just the reference count is increased. Note that this means that results from functions returning a RawByteString will never be converted to the destination's static code page. This is another way in which the dynamic code page of an AnsiString(X) can become different from its static code page.
+
Moins intuitif est probablement le fait que lorsqu'une RawByteString est affectée vers une AnsiString(X), la meêm chose se produit: pas de conversion de page de code ni de copie, seulment une incrémentation du compteur. Notez que cela signifie que les résultats de fonctions retourant une RawByteString ne seront jamais converties vers la page de code de destination. C'est une autre manière par laquelle la page de code dynamique d'une AnsiString(X) peut devenir différente de sa page de code declarée.
  
This type is mainly used to declare ''const'', ''constref'' and value parameters that accept any AnsiString(X) value without converting it to a predefined static code page. Note that if you do this, the routine accepting those parameters should be able to handle strings with any possible dynamic code page.
+
Ce type est principalement utilisé pour déclarer des ''const'', ''constref'' et des paramètres par valeur qui acceptent toute valeur AnsiString(X) sans la convertir vers une page de code prédéfinie. Notez que si vous faites cela, la routine acceptant ces paramètres devrait être capable de manipuler des chaînes avec n'importe quelle page de code dynamique.
  
''var'' and ''out'' parameters can also be declared as ''RawByteString'', but in this case the compiler will give an error if an AnsiString(X) whose static code page is different from CP_NONE is passed in. This is consistent with ''var'' and ''out'' parameters in general: they require an exactly matching type to be passed in. You can add an explicit RawByteString() typecast around an argument to remove this error, but then you must be prepared to deal with the fact that the returned string can have any dynamic code page.
+
Les paramètres ''var'' et ''out'' peuvent être aussi déclarés comme ''RawByteString'', mais dans ce cas, le compilateur donnera une erreur si une AnsiString(X) dont le page de code declarée est différente de CP_NONE est passé dedans. C'est consistant avec les paramètres ''var'' et ''out'' en général: ils nécessitent une exacte correspondance de type à passer dedans. Vous pouvez ajouter une conversion explicite de type vers RawByteString() pour supprimer l'erreur, mais vous devez être préparé à traiter le fait que la chaîne retournée peut avoir aucune page de code dynamique.
  
== String concatenations ==
+
== Concaténation de chaîne ==
Normally, in Pascal the result type of an expression is independent of how its result is used afterwards. E.g. multiplying two longints on a 32 bit platform and assigning the result to an int64 will still perform the multiplication using 32 bit arithmetic, and only afterwards the result is converted to 64 bit.
+
Normalement, en Pascal le type du résultat d'une expression est indépendant de comment son résultat est utilisé après. P.ex. multiplier 2 longints sur une plate-forme 32-bit et affecter le résultat vers un Int64 réalisera encore la multiplication en utilisant l'artithmétique 32-bit, et seulement après le résultat is converti en 64 bit.
  
Code page-aware strings are the only exception to this rule: concatenating two or more strings always occurs without data loss, although afterwards the resulting string will of course still be converted to the static code page of the destination (which may result in data loss).
+
Les chaînes sensibles à la page de code sont la seule exception à la règle: concaténer deux chaînes ou plus se produit toujours sans perte de données, bien qu'après la chaîne résultante sera bien sûr convertie vers la page de code declarée de la destination (une perte de donnée peut alors en résulter).
  
Assigning the result of a concatenation to a RawByteString is again special:
+
Affecter le résultat d'une concaténation vers une RawByteString est aussi particulier:
* if all concatenated strings have the same dynamic code page, the result will have this code page too
+
* si toutes les chaînes concaténées ont la même page de code dynamique, le résultat aura la même page de code aussi
* in other cases the result will be converted to CP_ACP (we may add an option in the future to change this RawByteString behaviour, as it is not very practical).
+
* dans les autres cas le résultat sera converti vers CP_ACP (nous pouvons ajouter une option dans le futur pour changer ce comportement de RawByteString, qui n'est pas très pratique).
  
 
== String constants ==
 
== String constants ==
String constants are parsed by FPC as follows:
+
Le compilateur doit connaître la page de code selon laquelle il devra interprété les constantes de chaîne car il peut avoir à les convertir au moment de la compilation. Normalement, une constante de chaîne est interprétée selon la [[#Page de code du fichier source|page de code du fichier source]]. Si la page de code du fichier source est ACP_CP, une valeur par défaut est utilisée à la place: dans ce cas, pendant les conversions, la constante de chaîne est supposée avoir la page de code 28591 (''ISO 8859-1 Latin 1; Western European'').
* if a file contains a ''{$codepage xxx}'' directive (e.g. <code>{$codepage UTF8}</code>), then string constants are interpreted according to that code page, otherwise
 
* if the file starts with an UTF-8 BOM, then string constants are interpreted as UTF-8 strings, otherwise
 
* string constants are copied without any translation into an internal buffer and are interpreted as characters using one of the following code pages:
 
** the ''DefaultSystemCodePage'' '''''of the computer on which the compiler itself is currently running''''' when ''{$modeswitch systemcodepage}'' is active (i.e., compiling the source code on a different system may cause string constants to be interpreted differently; this switch is available for Delphi compatibility and is enabled by default in ''{$mode delphiunicode}'')
 
** CP_ACP in case ''{$modeswitch systemcodepage}'' is not active (for backward compatibility with previous FPC versions)
 
  
In all but the last case, the actual code page of the source file is known. This knowledge is required when the compiler is forced to convert string constants to a different code page. Therefore, in the last case a default is used in such situations: strings are assumed to be encoded in code page 28591 (''ISO 8859-1 Latin 1; Western European''). This assumed or actual code page is referred to as the ''source file code page'' below.
+
Quand une constante de chaîne est affectée dans une AnsiString(X) soit par code ou comme partie d'une constante typée ou d'une initialisation de variable alors :
 +
* si X = CP_NONE (i.e., la cible est une RawByteString), le résultat est le même que si la constante String était affectée vers une AnsiString(CP_ACP)
 +
* si X = CP_ACP et que la page de code de la constante String est différente de CP_ACP, alors la constante est convertie, lors de la compilation, vers la page de code du fichier source. Si la page de code du fichier source est aussi CP_ACP, alors elle sera copiée sans changement avec la page de code CP_ACP et donc sa signification/interprétation dépendra de la valeur en cours de ''DefaultSystemCodePage'' à l'exécution. Ceci garantit la compatibilité avec les anciennes versions de FPC lors de l'affectation des constantes String sans employer une directive ''{$codepage xxx}'' un BOM UTF-8.
 +
* Pour les autres valeurs de X, la constante String est convertie, à la compilation, vers la page de code X.  
  
When a string constant is assigned to an AnsiString(X) either in code or as part of a typed constant or variable initialisation, then
+
Similairement, si une constante String est affectée dans une UnicodeString, la constante String est convertie, à la compilation, de la page de code du fichier source vers UTF-16.
* if X = CP_NONE (i.e., the target is a RawByteString), the result is the same as if the constant string were assigned to an AnsiString(CP_ACP)
 
* if X = CP_ACP and the code page of string constant is different from CP_ACP, then the string constant is converted, at compile time, to the source file code page. If the string constant's code page is also CP_ACP, it will be stored in the program unaltered with a code page of CP_ACP and hence its meaning/interpretation will depend on the actual value of ''DefaultSystemCodePage'' at run time. This ensures compatibility with older versions of FPC when assigning string constants to AnsiString variables without using a ''{$codepage xxx}'' directive or UTF-8 BOM.
 
* for other values of X, the string constant is converted, at compile time, to code page X
 
  
Similarly, if a string constant is assigned to a UnicodeString, the string constant is converted, at compile time, from the source file code page to UTF-16.
+
Pour les ShortString et PChar, la même règle que pour AnsiString(CP_ACP) est suivie.
  
For ShortString and PChar, the same rule as for AnsiString(CP_ACP) is followed.
+
Notez que les constantes String symboliques seront converties à la compilation vers le type String et la page de code appropriés chaque fois qu'ils sont utilisés. Cela signifie qu'il n'y a pas de charge sur la vitesse en utilisant une constante simple chaîne dans des contextes de pages de code et types de chaîne multiples, seulement quelque charge sur la taille de donnée.
  
Note that symbolic string constants will be converted at compile time to the appropriate string type and code page whenever they are used. This means that there is no speed overhead when using a single string constant in multiple code page and string type contexts, only some data size overhead.
+
Il s'ensuit de tout ceci que pour garantir une interprétation prédictible des constantes String dans votre code source, il est mieux soit inclure une directive explicite ''{$codepage xxx}'' (ou d'utiliser l'option en ligne de commande ''-Fc''), ou enregistrer le code source en UTF-8 avec un BOM.
 
 
From the above it follows that to ensure predictable interpretation of string constants in your source code, it is best to either include an explicit ''{$codepage xxx}'' directive (or use the equivalent ''-Fc'' command line option), or to save the source code in UTF-8 with a BOM.
 
  
 
== Indexation de chaîne ==
 
== Indexation de chaîne ==
 
Rien ne change dans l'indexation de chaînes. Chaque élément d'une chaîne UnicodeString/WideString est à 2 octets et chaque élément de tout autre type de chaîne est à 1 octet. Le mécanisme d'indexation de chaîne ignore totalement les pages de code et les points de code composites.
 
Rien ne change dans l'indexation de chaînes. Chaque élément d'une chaîne UnicodeString/WideString est à 2 octets et chaque élément de tout autre type de chaîne est à 1 octet. Le mécanisme d'indexation de chaîne ignore totalement les pages de code et les points de code composites.
  
= Sections anciennes ou obsolètes=
+
= Changements dans la RTL =
{{Warning|Ces sections sont conservées à titre historique - SVP, mettez à jour les sections du dessus avec cette information si elle est toujours applicable. Depuis FPC 2.7, (version en cours de développement), le support intensif d'Unicode a été implémenté.}}
+
En vue de garantir pleinement l'intégrité de donnée en présence de chaîne sensible à la page de code, toutes les routines dans la RTL et les paquets qui acceptent des paramètres ''AnsiString'' doivent être adaptées. La raison en est que si leurs paramètres restent des purs ''AnsiString'' alors toute chaîne avec un code de page statique sera convertie vers ''DefaultSystemCodePage'' quand elle sera passée dedans. Il en résultera une perte de donnée.
  
== Support de l'Unicode de Tiburon ==
+
Jusqu'à maintenant, les routines traitant de l'accès au système de fichier ont été mise à jour pour préserver toute la donnée caractère. Ci se trouve une liste exhaustive de toutes les routines qui préservent l'encodage des chaînes dans FPC 2.7.1 et postérieur. Sauf mention explicitement contraire, ces routines ont également toutes des surcharges qui acceptent des paramètres ''UnicodeString''.
 +
* '''System''': FExpand, LowerCase, UpperCase, GetDir, MKDir, ChDir, RMDir, Assign, Erase, Rename, standard I/O (Read/Write/Readln/Writeln/Readstr/Writestr), Insert, Copy, Delete, SetString
 +
* '''ObjPas''' (used automatically in Delphi and ObjFPC modes): AssignFile
 +
* '''SysUtils''': FileCreate, FileOpen, FileExists, DirectoryExists, FileSetDate, FileGetAttr, FileSetAttr, DeleteFile, RenameFile, FileSearch, ExeSearch, FindFirst, FindNext, FindClose, FileIsReadOnly, GetCurrentDir, SetCurrentDir, ChangeFileExt, ExtractFilePath, ExtractFileDrive, ExtractFileName, ExtractFileExt, ExtractFileDir, ExtractShortPathName, ExpandFileName, ExpandFileNameCase, ExpandUNCFileName, ExtractRelativepath, IncludeTrailingPathDelimiter, IncludeTrailingBackslash, ExcludeTrailingBackslash, ExcludeTrailingPathDelimiter, IncludeLeadingPathDelimiter, ExcludeLeadingPathDelimiter, IsPathDelimiter, DoDirSeparators, SetDirSeparators, GetDirs, ConcatPaths, GetEnvironmentVariable
 +
* '''Unix''': fp*() routines related to file system operations (no ''UnicodeString'' overloads), POpen
 +
* '''DynLibs''': all routines
  
Voici quelques informations au sujet du support de l'implémentation de l'Unicode de Tiburon's Unicode.
+
= A faire dans la RTL =
 +
Comme la liste ci-dessus est exhaustive, aucune autre routine RTL ne supporte encore des pages de code arbitraire. Cette section contient une liste des pièges que certaines personnes ont identifiés et, si possible, des solutions de contournement. Notez que les routines non mentionnés ici ni ci-dessus sont aussi peu sûres que celles qui sont explicitement mentionnées.
  
http://blogs.codegear.com/abauer/2008/01/09/38845
+
==TFormatSettings et DefaultFormatSettings==
 +
Le type de ThousandSeparator'' et  ''DecimalSeparator'' est AnsiChar. Cela veut dire que si  ''DefaultSystemCodePage'' vaut UTF-8 et que le séparateur de locale fait plus d'un caractère de longueur dans cet encodage, ces champs ne seront pas assez grands. Des exemples sont le blancs insécables français et russes utilisés pour représenter le séparateur des milliers.
  
http://blogs.codegear.com/abauer/2008/07/16/38864
+
= Sections anciennes/obsolètes=
 
+
{{Warning|Ces sections sont conservées à titre historique - SVP, mettez à jour les sections du dessus avec cette information si elle est toujours applicable. Depuis FPC 2.7, (version en cours de développement), le support intensif d'Unicode a été implémenté.}}
==Etat du support d'Unicode dans FPC jusqu'ici==
 
 
 
Actuellement, FPC 2.3.x a un nouveau type nommé UnicodeString. C'est similaire à un type WideString. La différence étant que UnicodeString bénéficie du comptage de référence sur toutes les plates-formes.
 
  
Tout le travail d'implémentation est actuellement fait dans une branche svn séparée: http://svn.freepascal.org/svn/fpc/branches/cpstrnew
+
==Changements visibles par l'utilisateur==
 +
(*** non traduit car obsolète ***)
  
==User visible changes==
 
(non traduit)
 
 
Full support of code page aware strings is not possible without breaking some existing code. The following list tries to summarize the most important user visible changes.
 
Full support of code page aware strings is not possible without breaking some existing code. The following list tries to summarize the most important user visible changes.
 
* The string header has two new fields: encoding and element size. On 32 Bit platforms this increases the header size by 4 and on 64 bit platforms by 8 bytes.
 
* The string header has two new fields: encoding and element size. On 32 Bit platforms this increases the header size by 4 and on 64 bit platforms by 8 bytes.
Line 180: Line 200:
 
* the type of the dest parameter of WideCharLenToString and UnicodeCharLenToString has been changed from Ansistring to Unicodestring
 
* the type of the dest parameter of WideCharLenToString and UnicodeCharLenToString has been changed from Ansistring to Unicodestring
 
* UTF8ToAnsi and AnsiToUTF8 take a RawByteString now
 
* UTF8ToAnsi and AnsiToUTF8 take a RawByteString now
 
==Feuille de route du support par la RTL d'Unicode avec UnicodeString==
 
 
{| class="wikitable"
 
! Sujet !! Etat !! Commentaire !! Affecté à
 
|-
 
| Variables Locale || {{Not Implemented}} || Les variables font toutes 1 octet en taille et ne peuvent tenir de valeur de la taille de UnicodeChar. Par exemple: Le séparateur des milliers russe est un espace non sécable $00A0 qui ne peut tenir dans la variable  ThousandSeparator (type Char standard). ||
 
|-
 
| TStrings || {{Not Implemented}} || Il n'y a pas de version UnicodeString de TStrings ||
 
|-
 
| TStringList || {{Not Implemented}} || Il n'y a pas de version UnicodeString de TStringList ||
 
|-
 
| Pos() || {{Working}} ||  ||
 
|}
 
 
==Feuille de route du support par la RTL d'Unicode avec UTF8String==
 
 
{| class="wikitable"
 
! Sujet !! Etat !! Commentaires !! Affecté à
 
|-
 
| UTF8String || {{Not Implemented}} || Nécessite une réelle implémentation. Est pour l'instant uniquement un alias pour ansistring.||
 
|-
 
| TStrings || {{Not Implemented}} || Il n'y a pas de version UTF8String pour TStrings||
 
|-
 
| TStringList || {{Not Implemented}} || Il n'y a pas de version UTF8String pour TStringList||
 
|}
 
  
 
= Voir aussi =
 
= Voir aussi =
Line 212: Line 206:
 
* [[unicode use cases/fr|Cas d'utilisation d'Unicode ]]
 
* [[unicode use cases/fr|Cas d'utilisation d'Unicode ]]
 
* [[LCL Unicode Support/fr|Support d'Unicode par la LCL]]
 
* [[LCL Unicode Support/fr|Support d'Unicode par la LCL]]
 +
* Suggestion: [[not Delphi compatible enhancement for Unicode Support]]
  
[[Category:Unicode]]
+
[[Category:Unicode/fr]]
[[Category:FPC]]
+
[[Category:FPC/fr]]

Latest revision as of 04:08, 16 February 2020

English (en) español (es) français (fr) русский (ru)

Introduction

Jusqu'à la version 2.6.x inclus, la RTL est basée sur ceux de Turbo Pascal et Delphi 7. Cela signifie qu'elle était au départ basé sur les types shortstring, ansistring et pchar. Aucun de ces types n'avait d'information d'encodage associé avec eux, mais ils étaient supposés être implicitement encodés dans l'"encodage système par défaut" et étaient passés aux API système sans aucune conversion.

Dans Delphi 2009, Embarcadero a basculé l'ensemble de la RTL vers le type UnicodeString, qui représente des chaînes utilisant UTF-16. En plus, ils sont rendu le type AnsiString "sensible (aware) à la page de code". Cela signifie que les AnsiStrings dès lors contiennent la page de code selon lequel les données doivent être interprétées.

Le support au niveau du langage de FPC est déjà disponible dans les versions en cours de développement du compilateur (FPC 2.7.1/trunk). Le support au niveau RTL n'est pas encore complet. Cette page donne une vue d'ensemble des comportements relatifs à la page de code pour ces types de chaînes, le niveau actuel du support par la RTL et des possibles voies d'amélioration futures pour ce support.

Compatibilité ascendante

Si vous avez du code existant qui marche d'une façon connue (*) avec une version antérieure de FPC et que vous ne faites aucun changement, il devrait continuer à fonctionner non modifié avec la nouvelle verison de FPC. Garantir tel est le but principal de la multitude de variables de page de code et leurs valeurs par défaut, comme décrit ci-dessous.

(*) cela veut dire this principalement : vous ne stockez pas de donnée dans une AnsiString qui a été encodée par autre chose que la page de code par défaut du système et par la suite passe cette chaîne tel quelle à une routine RTL de FPC. Par exemple, le code actuel de Lazarus est bien en général, comme vous êtes censés appeler UTF8ToAnsi() avant de passer ses chaînes aux routines RTL de FPC.

Code pages

Une page de code définit comment les octets individuels d'une chaînes sont interprétés i.e. quelle lettre, quel symbole ou autre caractère graphique correspond à chaque octet ou séquence d'octets.

Identificateurs de page de code

Un identificateur de page de code est toujours enregistré comme un TSystemCodePage, qui est un alias pour Word. La valeur représente la page de code correspondante telle que définie par Microsoft Windows. En plus, il y a 3 valeurs spéciales de code de page :

  • CP_ACP: cette valeur représente la "page de code par défaut" en cours. Voir #Réglage de la page de code pour plus d'information.
  • CP_OEM: cette valeur représente la page de code OEM. Sur les plates-formes Windows, ceci correspond à la page de code utilisée par la console (par exemple les fenêtres cmd.exe). Sur d'autres plates-formes, cette valeur est interprétée de la même façon que CP_ACP.
  • CP_NONE: cette valeur indique qu'aucune information de page de code n'a été associée avec la donnée chaîne. Le résultat de toute opération explicite ou implicite qui convertit cette donnée en une autre page de code est indéfinie

Note: les identificateurs de page de code sont différent des noms de page de code tels qu'ils sont utilisés dans la directive {$codepage xxx} (qui est déjà disponible dans la version stable de FPC). Les noms de page de code sont des noms d'unités individuelles de page de code exposés dans l'unité de jeu de caractères, qui ont des noms tels que cp866 et cp1251 et utf8.

Réglage de la page de code

L'unité system contient plusieurs variables globales qui indiquent la page de code par défaut utilisée par certaines opérations.

DefaultSystemCodePage

  • Usage: détermine comment CP_ACP est interprété
  • Valeur initiale:
    • Windows: C'est le résultat de l'appel système à GetACP, qui retourne la page de code ANSI de Windows.
    • iOS: UTF-8
    • Unix (sauf iOS): Basé sur le réglage actuel des variables d'environnement LANG ou LC_CTYPE. C'est en général UTF-8, mais il n'est pas garanti que cela soit le cas.
    • Autres plates-formes: CP_ACP (ces plates-formes ne supportent actuellement pas les pages de code multiples, et sont codés en dur pour utiliser la page de code spécifique au système dans tous les cas)
  • Modifications: vous pouvez modifier cette valeur en appelant SetMultiByteConversionCodePage(CodePage: TSystemCodePage)
  • Notes: Depuis que cette variable peut être modifiée, ce n'est plus une bonne idée d'utiliser cette valeur pour déterminer la "page de code par défaut" réelle du système (à moins de le faire au démarrage du programme et d'être certain qu'aucune autre unité ne l'a changé dans son code d'initialisation).

DefaultFileSystemCodePage

  • Usage: Définit la page de code vers laquelle les noms de chemin/fichier sont traduits avant d'être passé lors d'un appel à une API système, si la RTL utilise une API système à simple octet pour cette usage sur la plate-forme courante. Ce page de code est aussi utilisée pour les opérations intermédiaires sur les chemins d'accès dans la RTL avant de faire des appels aux API système. Cette variable n'existe pas dans Delphi et a été introduite dans FPC pour rendre possible le changement de valeur de DefaultSystemCodePage sans casser les interfaces RTL avec les appels du système de fichier du système d'exploitation.
  • Valeur initiale:
    • Windows: UTF-8, parce que la RTL utilise des appels aux API système UTF-16 (donc aucune donnée n'est perdue dans les opérations intermédiaires).
    • OS X and iOS: UTF-8 (comme défini par Apple)
    • Unix (mis à part OS X et iOS): DefaultSystemCodePage, parce que l'encodage des fichiers est indéfini sur les plates-formes Unix (c'est un tableau non typé d'octets qui peut être interprété comme on veut ; il n'est pas garanti d'être de l'UTF-8 valide)
    • Autres plates-formes: identique à DefaultSystemCodePage
  • Modifications: vous pouvez modifier cette valeur en appelant SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage)
  • Notes: Les réglages Unix/OS X/iOS s'appliquent seulement dans le cas où le gestionnaire de widestring cwstring est installé, sinon DefaultFileSystemCodePage aura la même valeur que DefaultSystemCodePage après le démarrage du programme.

DefaultRTLFileSystemCodePage

  • Usage: définit la page de code vers laquelle les noms de fichier/chemin sont traduits avant d'être retournées par les routines RTL pour les fichier/chemin RawByteString. Des exemples sont dans les noms de fichier/chemin retournés par les versions RawbyteString de SysUtils.FindFirst et System.GetDir. La principale raison de son existence est de rendre la RTL capable de fournir la compatibilité ascendante avec les versions antérieures de FPC, comme celles-ci retournaient toujours des chaînes encodées pour les API système en simple octet utilisées (qui étaient habituellement ce qui est connu maintenant comme DefaultSystemCodePage).
  • Valeur initiale
    • Windows: DefaultSystemCodePage, pour compatibilité ascendante.
    • OS X and iOS: UTF-8, pour compatibilité ascendante (c'était déjà toujours UTF-8 dans le passé, puisque c'est ce que les API de fichiers de l'OS retourne et nous ne convertissions pas cette donnée).
    • Unix (mis à part OS X et iOS): DefaultSystemCodePage, pour la même raison qu'avec DefaultFileSystemCodePage. Régler celle-ci à une autre valeur que DefaultFileSystemCodePage est une mauvaise idées sur ces plates-formes, puisque toute conversion peut corrompre ces chaînes car leur encodage initial est inconnu.
    • Autres plates-formes: comme pour DefaultSystemCodePage
  • Modifications: Vous pouvez modifier cette valeur en appelant SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage)
  • Notes: les mêmes que pour DefaultFileSystemCodePage.

Page de code du fichier source

La page de code du fichier sourcedétermine comment les constantes de chaîne sont interprétées et où le compilateur insèrera l'opération de conversion de la page de code à l'affectation d'un type de chaîne vers un autre.

La page de code du fichier source est déterminée de la façon suivante:

  • Si le fichier contient une directive {$codepage xxx} (p.ex. {$codepage UTF8}), alors le page de code du fichier source est cette page de code, sinon
  • Si le fichier commence par un UTF-8 BOM, alors la page de code du fichier source est UTF-8, sinon
  • Si {$modeswitch systemcodepage} est active, la page de code du fichier source est la DefaultSystemCodePage de l'ordinateur sur lequel le compilateur lui-même s'exécute (i.e., la compilation du code source peut créer un programme qui se comporte différemment sur un autre système; cette bascule est disponible pour la compatibilité avec Delphi et est activée par défaut avec {$mode delphiunicode}), sinon
  • la page de code du fichiers source est définie comme CP_ACP (pour compatibilité ascendante avec les versions antéreures de FPC)

Strings

String/character types

Shortstring

La page de code d'une shortstring est implicitement CP_ACP d'où elle sera toujours égale à la valeur courante de DefaultSystemCodePage.

PAnsiChar/AnsiChar

Ces types sont les mêmes que les anciens types PChar/Char. Dans tous les modes du compilateur sauf pour {$mode delphiunicode}, PChar/Char sont aussi encore des alias pour PAnsiChar/AnsiChar. Leur page de code est implicitement CP_ACP et donc toujours égale à la valeur courante de DefaultSystemCodePage.

PWideChar/PUnicodeChar et WideChar/UnicodeChar

Ces types demeurent inchangés. WideChar/UnicodeChar peuvent contenir une simple unité de code UTF-16, alors que PWideChar/PUnicodeChar pointe sur une simple unité de code ou un tableau d'unités de code en UTF-16.

En {$mode delphiunicode}, PChar devient un alias de PWideChar/PUnicodeChar et Char devient un alias de WideChar/UnicodeChar.

UnicodeString/WideString

Ces types se comporte comme dans les versions précédentes:

  • Widestring est le même qu'un "COM BSTR" dans Windows et un alias de UnicodeString sur toutes les autres plates-formes. Sa chaîne de données est encodée avec de l'UTF-16.
  • UnicodeString est une chaîne à comptage de référence avec une longueur maximale de high(SizeInt) en unités de code UTF-16.

Ansistring

Les AnsiStrings sont des chaînes à comptage de références avec une longueur maximal de high(SizeInt) octets. En plus, une information de code de page peut maintenant leur être associée.

La chose la plus importante à comprendre sur le nouveau type AnsiString est qu'il a à la fois une page de code déclarée/statique/préférée/par défaut (appelée page de code declarée à partir de maintenant), et une page de code dynamique. La page de code declarée dit au compilateur que lorsqu'on affecte quelque chose à cet AnsiString, il devrait d'abord convertir cette donnée vers cette page de code (sauf si c'est CP_NONE, voir RawByteString plus bas). La page de code dynamique est une propriété de l'AnsiString qui, tels la longueur et le compteur de référence, définit la page de code en cours des données actuellement tenues par cette AnsiString.

Page de code declarée

La page de code declarée d'une AnsiString peut seulement être définie en déclarant un nouveau type comme suit:

type
  CP866String = type AnsiString(866); // note the extra "type"

La page de code declarée d'une variable déclarée comme pure AnsiString est CP_ACP. En effet, le type AnsiString est maintenant sémantiquement défini dans l'unité System comme:

type
  AnsiString = type AnsiString(CP_ACP);

Un autre type AnsiString(X) prédéfini dans l'unité System est UTF8String:

type
  UTF8String = type AnsiString(CP_UTF8);

Une fois que vous avez défini tel type AnsiString(X), vous pouvez l'utiliser pour déclarer des variables, des paramètres, champs etc comme d'habitude.

Notez que CP_UTF16 et CP_UTF16BE ne sont pas valides comme page de code pour les AnsiStrings. Ce qui peut résulter d'une telle définition est indéfini.

Page de code dynamique

Si une chaîne d'une page de code declarée X1 est affectée par une chaîne d'une pafe de code X2, alors:

  • si (X1 = CP_NONE) ou (X2 = CP_NONE), voir RawByteString, sinon
  • si (la page de code du source <> CP_ACP), alors si (X2 = CP_ACP) et (X1 = page de code du fichier source) ou vice-versa, aucune conversion ne sera faite (même si à l'exécution, DefaultSystemCodePage a une valeur différente de la page de code du fichier source). La raison pour la condition (page de code du source <> CP_ACP) est la compatibilité ascendante avec les versions antérieures de FPC (alors qu'elles ne prennent pas en charge AnsiStrings avec des pages de codes arbitraires, elles réinterprètaient toujours AnsiStrings en fonction de la valeur actuelle de la page de code du système). Sinon
  • si (X1 <> X2), la donnée chaîne sera convertie de la page de code X1 vers la page de code X2 avant affectation, par laquelle CP_ACP sera interprétée comme la valeur actuelle de DefaultSystemCodePage. Sinon,
  • Si (X1 = X2), aucune coversion de page de code ne sera réalisée.

Ces règles signifient qu'il est parfaitement possible pour une variable AnsiString d'avoir une page de code dynamique qui diffère de sa page de code declarée. P.ex. dans le troisième cas, X1 pourrait être CP_ACP, alors qu'après affectation, il pourrait avoir un page de code dynamique égale à DefaultSystemCodePage.

Note: comme mentionné au-dessus, qu'une conversion potentielle de page de code survienne ou pas dépend seulement de la page de code declarée des chaînes impliquées. Cela signifie que si vous affectez une AnsiString(X) à une autre AnsiString(X) et que l'ancienne page de code dynamique était différente de X, la chaîne ne sera pas convertie vers la page de code X par l'affectation.

RawByteString

Le type RawByteString est défini comme

type
  RawByteString = type AnsiString(CP_NONE);

Comme mentionné avant, les résultats de conversions de/vers la page de code CP_NONE sont indéfinis. Comme cela n'a pas de sens de définir un type dans la RTL dont le comportement est indéfini, le comportement de RawByteString est quelque peu différent des autres types AnsiString(X).

Comme première approximation, RawByteString paut être considéré comme un "AnsiString non typé": affecter une AnsiString(X) vers une RawByteString a exactement le même comportement que d'affecter cet AnsiString(X) vers une autre variable AnsiString(X) avec la même valeur de X: aucune conversion de page de code ou copie ne se passe, seul le compteur de référence est incrémenté.

Moins intuitif est probablement le fait que lorsqu'une RawByteString est affectée vers une AnsiString(X), la meêm chose se produit: pas de conversion de page de code ni de copie, seulment une incrémentation du compteur. Notez que cela signifie que les résultats de fonctions retourant une RawByteString ne seront jamais converties vers la page de code de destination. C'est une autre manière par laquelle la page de code dynamique d'une AnsiString(X) peut devenir différente de sa page de code declarée.

Ce type est principalement utilisé pour déclarer des const, constref et des paramètres par valeur qui acceptent toute valeur AnsiString(X) sans la convertir vers une page de code prédéfinie. Notez que si vous faites cela, la routine acceptant ces paramètres devrait être capable de manipuler des chaînes avec n'importe quelle page de code dynamique.

Les paramètres var et out peuvent être aussi déclarés comme RawByteString, mais dans ce cas, le compilateur donnera une erreur si une AnsiString(X) dont le page de code declarée est différente de CP_NONE est passé dedans. C'est consistant avec les paramètres var et out en général: ils nécessitent une exacte correspondance de type à passer dedans. Vous pouvez ajouter une conversion explicite de type vers RawByteString() pour supprimer l'erreur, mais vous devez être préparé à traiter le fait que la chaîne retournée peut avoir aucune page de code dynamique.

Concaténation de chaîne

Normalement, en Pascal le type du résultat d'une expression est indépendant de comment son résultat est utilisé après. P.ex. multiplier 2 longints sur une plate-forme 32-bit et affecter le résultat vers un Int64 réalisera encore la multiplication en utilisant l'artithmétique 32-bit, et seulement après le résultat is converti en 64 bit.

Les chaînes sensibles à la page de code sont la seule exception à la règle: concaténer deux chaînes ou plus se produit toujours sans perte de données, bien qu'après la chaîne résultante sera bien sûr convertie vers la page de code declarée de la destination (une perte de donnée peut alors en résulter).

Affecter le résultat d'une concaténation vers une RawByteString est aussi particulier:

  • si toutes les chaînes concaténées ont la même page de code dynamique, le résultat aura la même page de code aussi
  • dans les autres cas le résultat sera converti vers CP_ACP (nous pouvons ajouter une option dans le futur pour changer ce comportement de RawByteString, qui n'est pas très pratique).

String constants

Le compilateur doit connaître la page de code selon laquelle il devra interprété les constantes de chaîne car il peut avoir à les convertir au moment de la compilation. Normalement, une constante de chaîne est interprétée selon la page de code du fichier source. Si la page de code du fichier source est ACP_CP, une valeur par défaut est utilisée à la place: dans ce cas, pendant les conversions, la constante de chaîne est supposée avoir la page de code 28591 (ISO 8859-1 Latin 1; Western European).

Quand une constante de chaîne est affectée dans une AnsiString(X) soit par code ou comme partie d'une constante typée ou d'une initialisation de variable alors :

  • si X = CP_NONE (i.e., la cible est une RawByteString), le résultat est le même que si la constante String était affectée vers une AnsiString(CP_ACP)
  • si X = CP_ACP et que la page de code de la constante String est différente de CP_ACP, alors la constante est convertie, lors de la compilation, vers la page de code du fichier source. Si la page de code du fichier source est aussi CP_ACP, alors elle sera copiée sans changement avec la page de code CP_ACP et donc sa signification/interprétation dépendra de la valeur en cours de DefaultSystemCodePage à l'exécution. Ceci garantit la compatibilité avec les anciennes versions de FPC lors de l'affectation des constantes String sans employer une directive {$codepage xxx} un BOM UTF-8.
  • Pour les autres valeurs de X, la constante String est convertie, à la compilation, vers la page de code X.

Similairement, si une constante String est affectée dans une UnicodeString, la constante String est convertie, à la compilation, de la page de code du fichier source vers UTF-16.

Pour les ShortString et PChar, la même règle que pour AnsiString(CP_ACP) est suivie.

Notez que les constantes String symboliques seront converties à la compilation vers le type String et la page de code appropriés chaque fois qu'ils sont utilisés. Cela signifie qu'il n'y a pas de charge sur la vitesse en utilisant une constante simple chaîne dans des contextes de pages de code et types de chaîne multiples, seulement quelque charge sur la taille de donnée.

Il s'ensuit de tout ceci que pour garantir une interprétation prédictible des constantes String dans votre code source, il est mieux soit inclure une directive explicite {$codepage xxx} (ou d'utiliser l'option en ligne de commande -Fc), ou enregistrer le code source en UTF-8 avec un BOM.

Indexation de chaîne

Rien ne change dans l'indexation de chaînes. Chaque élément d'une chaîne UnicodeString/WideString est à 2 octets et chaque élément de tout autre type de chaîne est à 1 octet. Le mécanisme d'indexation de chaîne ignore totalement les pages de code et les points de code composites.

Changements dans la RTL

En vue de garantir pleinement l'intégrité de donnée en présence de chaîne sensible à la page de code, toutes les routines dans la RTL et les paquets qui acceptent des paramètres AnsiString doivent être adaptées. La raison en est que si leurs paramètres restent des purs AnsiString alors toute chaîne avec un code de page statique sera convertie vers DefaultSystemCodePage quand elle sera passée dedans. Il en résultera une perte de donnée.

Jusqu'à maintenant, les routines traitant de l'accès au système de fichier ont été mise à jour pour préserver toute la donnée caractère. Ci se trouve une liste exhaustive de toutes les routines qui préservent l'encodage des chaînes dans FPC 2.7.1 et postérieur. Sauf mention explicitement contraire, ces routines ont également toutes des surcharges qui acceptent des paramètres UnicodeString.

  • System: FExpand, LowerCase, UpperCase, GetDir, MKDir, ChDir, RMDir, Assign, Erase, Rename, standard I/O (Read/Write/Readln/Writeln/Readstr/Writestr), Insert, Copy, Delete, SetString
  • ObjPas (used automatically in Delphi and ObjFPC modes): AssignFile
  • SysUtils: FileCreate, FileOpen, FileExists, DirectoryExists, FileSetDate, FileGetAttr, FileSetAttr, DeleteFile, RenameFile, FileSearch, ExeSearch, FindFirst, FindNext, FindClose, FileIsReadOnly, GetCurrentDir, SetCurrentDir, ChangeFileExt, ExtractFilePath, ExtractFileDrive, ExtractFileName, ExtractFileExt, ExtractFileDir, ExtractShortPathName, ExpandFileName, ExpandFileNameCase, ExpandUNCFileName, ExtractRelativepath, IncludeTrailingPathDelimiter, IncludeTrailingBackslash, ExcludeTrailingBackslash, ExcludeTrailingPathDelimiter, IncludeLeadingPathDelimiter, ExcludeLeadingPathDelimiter, IsPathDelimiter, DoDirSeparators, SetDirSeparators, GetDirs, ConcatPaths, GetEnvironmentVariable
  • Unix: fp*() routines related to file system operations (no UnicodeString overloads), POpen
  • DynLibs: all routines

A faire dans la RTL

Comme la liste ci-dessus est exhaustive, aucune autre routine RTL ne supporte encore des pages de code arbitraire. Cette section contient une liste des pièges que certaines personnes ont identifiés et, si possible, des solutions de contournement. Notez que les routines non mentionnés ici ni ci-dessus sont aussi peu sûres que celles qui sont explicitement mentionnées.

TFormatSettings et DefaultFormatSettings

Le type de ThousandSeparator et DecimalSeparator est AnsiChar. Cela veut dire que si DefaultSystemCodePage vaut UTF-8 et que le séparateur de locale fait plus d'un caractère de longueur dans cet encodage, ces champs ne seront pas assez grands. Des exemples sont le blancs insécables français et russes utilisés pour représenter le séparateur des milliers.

Sections anciennes/obsolètes

Warning-icon.png

Avertissement: Ces sections sont conservées à titre historique - SVP, mettez à jour les sections du dessus avec cette information si elle est toujours applicable. Depuis FPC 2.7, (version en cours de développement), le support intensif d'Unicode a été implémenté.

Changements visibles par l'utilisateur

(*** non traduit car obsolète ***)

Full support of code page aware strings is not possible without breaking some existing code. The following list tries to summarize the most important user visible changes.

  • The string header has two new fields: encoding and element size. On 32 Bit platforms this increases the header size by 4 and on 64 bit platforms by 8 bytes.
  • WideCharLenToString, UnicodeCharLenToString, WideCharToString, UnicodeCharToString and OleStrToString return an UnicodeString instead of an Ansistring before.
  • the type of the dest parameter of WideCharLenToString and UnicodeCharLenToString has been changed from Ansistring to Unicodestring
  • UTF8ToAnsi and AnsiToUTF8 take a RawByteString now

Voir aussi