binary

 

binary - Insère et extrait des champs à partir de chaînes binaires

SYNTAXE

 binary format formatString ?arg arg ...?
 binary scan string formatString ?varName varName ...?

DESCRIPTION

Cette commande fournit des facilités pour la manipulation de données binaires. La première forme, binary format, crée une chaîne binaire à partir de valeurs Tcl standards. Par exemple, en partant des valeurs 16 et 22, elle produira une chaîne binaire de 8 octets constituée de deux entiers de 4 octets, un pour chacun des nombres. La seconde forme de la commande, binary scan, fait le contraire: elle extrait les données à partir d'une chaîne binaire et les renvoie comme des valeur chaînes Tcl ordinaire.

BINARY FORMAT

La commande binary format génère une chaîne binaire dont le format est spécifié par le formatString et dont le contenu provient des arguments supplémentaires. La valeur binaire résultante est renvoyée.

Le formatString est constitué d'une séquence de zéro ou plus de spécificateurs de champs séparés par zéro ou plusieurs espaces. Chaque spécificateur de champ est un simple caractère suivi par un nombre optionnel compte. La plupart des spécificateurs de champs attendent un argument pour formater la valeur. Le caractère spécifie comment la valeur est formatée. Le nombre compte indique combien d'items du type spécifié sont présents dans la valeur. Si présent, compte est un entier décimal non-négatif ou [24], qui indique normalement que tous les éléments de la valeur doivent être utilisés. Si le nombre d'arguments ne correspond pas au nombre de champs dans le format chaîne qui attend les arguments, alors une erreur est générée.

Chaque paire type-compte déplace un curseur imaginaire au travers des données binaires, en stockant les octets à la position courante et avançant le curseur juste après le dernier octet stocké. Le curseur est initialement à la position 0 au début des données. Le type peut être l'un des caractères suivants:

a Stocke une chaîne de caractères de longueur compte dans la chaîne de sortie. Si arg a moins d'octets que compte, alors des octets supplémentaire nuls sont utilisés pour remplir le champ. Si arg est plus long que la longueur spécifiée, les caractères supplémentaires sont ignorés. Si compte est *, alors tous les octets de arg sont formatés. Si compte est omis, alors un caractère est formaté. Par exemple, binary format a7a* alpha bravo charlie renverra une chaîne équivalente à alpha\000\000bravoc.

A Cette forme est la même que a excepté que des espaces sont utilisés pour le remplissage au lieu de nuls. Par exemple, binary format A6A*A alpha bravo charlie renverra alpha bravoc.

b Stocke une chaîne de compte chiffres binaires en ordre croissant dans chaque octet de la chaîne de sortie. Arg doit contenir une séquence de 1 et de 0. Les octets résultants sont emis du premier au dernier avec les bits formatés de bas en haut dans chaque octet. Si arg a moins de chiffres que compte, alors des zéros seront utilisés pour les bits restant. Si arg a plus de chiffres que le nombre spécifiés, les chiffres supplémentaires sont ignorés. Si compte est *, alors tous les chiffres de arg sont formatés. Si compte est omis, alors un digit est formaté. Si le nombre de bits formatés ne finit pas à un une limite d'octet, les bits restants du dernier octet seront des zéros. Par exemple, binary format b5b* 11100 111000011010 renverra une chaîne équivalente à \x07\x87\x05.

B Cette forme est la même que b excepté que le bits sont stockés dans l'ordre descendant dans chaque octet. Par exemple, binary format B5B* 11100 111000011010 renverra une chaîne équivalentee à \xe0\xe1\xa0.

h Stocke une chaîne de compte chiffres hexadécimaux de bas en haut dans chaque octet de la chaîne de sortie. Arg doit contenir une séquence de caractères comprise dans ``0123456789abcdefABCDEF. Les octets résultants sont émis du premier au dernier avec les chiffres hexa formatés de bas en haut dans chaque octet. Si arg a moins de chiffres que compte, alors des zéros sont utilisés pour les chiffres restants. Si arg a plus de chiffres que le nombre spécifiés, les chiffres supplémentaires seront ignorés. Si compte est *, alors tous les chiffres de arg seront formatés. Si compte'' est omis, alors un digit est formaté. Si le nombre de chiffres formatée ne finit pas à une limite d'octet, les bits restants du dernier octet seront des zéros. Par exemple, binary format h3h* AB def renverra une chaîne équivalente à \xba\x00\xed\x0f.

H Cette forme est la même que h excepté que le chiffres sont stockés de haut en bas dans chaque octet. Par exemple, binary format H3H* ab DEF renverra une chaîne équivalente à \xab\x00\xde\xf0.

c Stocke une ou plusieurs valeur entières 8-bit dans la chaîne de sortie. Si aucun compte n'est spécifié, alors arg doit être une valeur entière; autrement arg doit être une liste contenant au moins compte éléments entiers. Les 8 bits de poids faible de chaque entier sont stockés comme une valeur d'un octet à la position du curseur. Si compte est *, alors tous les entiers de la liste sont formatés. Si le nombre d'éléments dans la liste est inférieur à compte, alors une erreur est générée. Si le nombre d'éléments dans la liste est supérieur à compte, alors les éléments supplémentaires sont ignorés. Par exemple, binary format c3cc* {3 -3 128 1} 260 {2 5} renverra une chaîne équivalente à \x03\xfd\x80\x04\x02\x05, alors que binary format c {2 5} générera une erreur.

s Cette forme est la même que c excepté qu'elle stocke un ou plusieurs entiers 16-bit en ordre little-endian dans la chaîne de sortie. Les 16 bits de poids faible de chaque entier sont stockés comme une valeur de deux-octet à la position du curseur avec l'octet de poids faible stocké en premier. Par exemple, binary format s3 {3 -3 258 1} renverra une chaîne équivalente à \x03\x00\xfd\xff\x02\x01.

S Cette forme est la même que s excepté qu'elle stocke un ou plusieurs entiers 16-bit en ordre big-endianx dans la chaîne de sortie. Par exemple, binary format S3 {3 -3 258 1} renverra une chaîne équivalente à \x00\x03\xff\xfd\x01\x02.

i Cette forme est la même que c excepté qu'elle stocke un ou plusieurs entiers 32-bit en ordre little-endian dans la chaîne de sortie. Les 32 bits de poids faible de chaque entier sont stockés comme une valeur de quatre-octet à la position du curseur avec l'octet de poids faible stocké en premier.Par exemple, binary format i3 {3 -3 65536 1} renverra une chaîne équivalente à \x03\x00\x00\x00\xfd\xff\xff\xff\x00\x00\x01\x00

I Cette forme est la même que i excepté qu'elle stocke un ou plusieurs 32-bit entiers en ordre big-endian dans la chaîne de sortie. Par exemple, binary format I3 {3 -3 65536 1} renverra une chaîne équivalente à \x00\x00\x00\x03\xff\xff\xff\xfd\x00\x01\x00\x00

f Cette forme est la même que c excepté qu'elle stocke un ou plusieurs flottants simple précision dans la représentation native de la machine dans la chaîne de sortie. Cette représentation n'est pas portable, donc elle ne doit pas être utilisée pour communiquer des nombres flottants sur le réseau. La taille d'un nombre flottant peut varier selon les architectures, donc le nombre d'octets générés peut varier.Si la valeur déborde de la représentation native de la machine, alors la valeur de FLT_MAX définie par le système sera utilisée.Parce que Tcl utilise des nombres flottants double-précision en interne, il peut y avoir une certaine perte de précision dans la conversion en simple-précision. Par exemple, sur un système Windows s'exécutant sur un processeur Pentium Intel, binary format f2 {1.6 3.4} renverra une chaîne équivalente à\xcd\xcc\xcc\x3f\x9a\x99\x59\x40.

d Cette forme est la même que f excepté qu'elle stocke un ou plusieurs flottants double-précision dans la représentation native de la machine dans la chaîne de sortie. Par exemple, sur un système Windows s'exécutant sur un processeur Pentium Intel, binary format d1 {1.6} renverra une chaîne équivalente à \x9a\x99\x99\x99\x99\x99\xf9\x3f.

x Stocke compte octet nuls dans la chaîne de sortie. Si compte n'est pas spécifié, elle stocke un octet null. Si compte est *, elle génère une erreur. Ce type n'attend pas d'argument.Par exemple, binary format a3xa3x2a3 abc def ghi renverra une chaîne équivalente à abc\000def\000\000ghi.

X Déplace le curseur en arrière de compte octets dans la chaîne de sortie. Si compte est *ou est supérieur à la position courante du curseur, alors le curseur est positionné à l'emplacement 0 ainsi l'octet suivant stocké sera le premier octet dans la chaîne résultat. Si compte est omis alors le curseur est déplacé d'un octet vers l'arrière. Ce type n'attend pas d'argument.Par exemple, binary format a3X*a3X2a3 abc def ghi renverra dghi.

@ Déplace le curseur à l'emplacement absolu spécifié par compte dans la chaîne de sortie. La position 0 correspond au premier octet dans la chaîne de sortie. Si compte correspond à une position au-delà du dernier octet stocké, alors des octet nuls seront placés aux emplacements non initialisés et le curseur sera placé à l'emplacement spécifié. Si compte est *, alors le curseur est déplacé à la fin de la chaîne de sortie actuelle. Si compte est omis, alors une erreur est générée. Ce type n'attend pas d'argument. Par exemple, binary format a5@2a1@*a3@10a1 abcde f ghi j renverra abfdeghi\000\000j.

BINARY SCAN

La commande binary scan analyse les champs d'une chaîne binaire, retournant le nombre de conversions effectuées. String donne l'entrée à analyser et formatString indique comment l'analyser. Chaque varName donne le nom d'une variable; quand un champ de string est analysé le résultat est assigné à la variable correspondante.

Comme avec binary format, le formatString est constitué d'une séquence de zéro ou plusieurs spécificateurs de champs séparées par zéro ou plusieurs espaces. Chaque spécificateur de champ est un simple caractère suivi par un nombre optionnel compte. La plupart des spécificateurs de champs utilisent un argument pour obtenir la variable dans laquelle les valeurs seront placées. Le caractère spécifie comment les données binaires sont interprétées. Le compte indique typiquement combien d’exemplaires du type spécifié sont extraits des données. Si présent, compte est un entier décimal non-négatif ou *, qui indique normalement que tous les items restant dans les données doivent être utilisés. S'il n'y a pas assez d'octets après la position courante du curseur pour satisfaire le spécificateur de champ courant, alors la variable correspondante est inchangée et binary scan retourne immédiatement avec le nombre de variables qui ont été définies. S'il n'y a pas assez d'arguments pour tous les champs de la chaîne format nécessitant des arguments, alors une erreur est générée.

Il est important de noter que les c, s, et S (et i et I sur les systèmes 64bit) extraient les données dans des entiers de type long. Ce faisant, les entiers qui ont leurs bit haut positionné (0x80 pour chars, 0x8000 pour shorts, 0x80000000 pour ints), seront signées.Ainsi :

 set signShort [[binary format s1 0x8000]]
 binary scan $signShort s1 val;'''''# val == 0xFFFF8000

Si vous voulez produire une valeur non signée, vous pouvez masquer la valeur de retour à la taille désirée. Par exemple, pour produire un entier court non signée:

 set val [[expr {$val & 0xFFFF}]];'''''# val == 0x8000

Chaque paire type-compte déplace un curseur imaginaire le long des données binaires, en lisant les octets à la position courante. Initialement le curseur est à la position 0 au début des données. Le type peut être l'un des caractères suivants:

a Les données sont une chaîne de caractères de longueur compte. Si compte est *, alors tous les octets restants dans string seront scannés dans la variable. Si compte est omis, alors un caractère sera scanné. Par exemple, binary scan abcde\000fghi a6a10 var1 var2 retournera 1 avec la chaîne équivalente à abcde\000 stockée dans var1 et var2 inchangée.

A Cette forme est la même que a, excepté que les espaces et les nulls sont enlevés de la valeur scannée avant d'être stocké dans la variable. Par exemple, binary scan "abc efghi \000" A* var1 renverra 1 avec abc efghi stocké dans var1.

b Les données sont transformées en une chaîne de compte chiffres binaires de bas en haut représentés comme une séquence de caractères "1" et "0". Les octets de données sont scannées du premier au dernier avec les bits rangés de bas en haut pour chaque octet. Les bits supplémentaires dans le dernier octet sont ignorés. Si compte est *, alors tous les bits restant dans string seront scannés. Si compte est omis, alors un bit sera scanné.Par exemple, binary scan\x07\x87\x05 b5b* var1 var2 renverra 2 avec 11100 stocké dans var1 et 1110000110100000 stocké dans var2.

B Cette forme est la même que b, excepté que les bits sont stockés dans l'ordre descendant dans chaque octet. Par exemple, binary scan\x70\x87\x05 B5B* var1 var2 renverra 2 avec 01110 stocké dans var1 et 1000011100000101 stocké dans var2.

h Les données sont transformées en une chaîne de compte chiffres hexadécimaux dans l'ordre de bas en haut représentés par une séquence de caractères de "0123456789abcdef". Les octets de données sont scannés du premier au dernier avec les chiffres hexa extraits de bas en haut dans chaque octet. Les bits supplémentaires dans le dernier octet sont ignorés. Si compte est *, alors tous les chiffres hexa restant dans string sont scannés. Si compte est omis, alors un digit hexa sera scanné. Par exemple, binary scan\x07\x86\x05 h3h* var1 var2 renverra 2 avec 706 stocké dans var1 et 50 stocké dans var2.

H Cette forme est la même que h, excepté que les chiffres sont extraits de haut en bas dans chaque octet. Par exemple, binary scan\x07\x86\x05 H3H* var1 var2 renverra 2 avec 078 stocké dans var1 et 05 stocké dans var2.

c Les données sont transformées en compte entiers signés 8-bit et stockées dans la variable correspondante sous forme de liste. Si compte est *, alors tous les octets restant de string seront scannés. Si compte est omis, alors un entier 8-bit sera scanné. Par exemple, binary scan\x07\x86\x05 c2c* var1 var2 renverra 2 avec 7 -122 stocké dans var1 et 5 stocké dans var2. Notez que les entiers renvoyés sont signés, mais ils peuvent être convertis en entiers 8-bit non signées en utilisant une expression telle que: expr ( $num + 0x100 ) % 0x100

s Les données sont interprétées comme compte entiers signés 16-bit représenté en little-endian. Les entiers sont stockés dans la variable correspondante sous forme de liste. Si compte est *, alors tous les octets restants de string seront scannés. Si compte est omis, alors un entier 16-bit sera scanné. Par exemple, binary scan\x05\x00\x07\x00\xf0\xff s2s* var1 var2 renverra 2 avec 5 7 stocké dans var1 et -16 stocké dans var2. Notez que les entiers renvoyés sont signés, mais ils peuvent être convertis en entiers 16-bit non signées en utilisant une expression telle que: expr ( $num + 0x10000 ) % 0x10000

S Cette forme est la même que s excepté que les données sont interprétées comme compte entiers 16-bit signés représenté en big-endian. Par exemple, binary scan\x00\x05\x00\x07\xff\xf0 S2S* var1 var2 renverra 2 avec 5 7 stocké dans var1 et -16 stocké dans var2.

i Les données sont interprétées comme compte entiers 32-bit signés représentés en little-endian. Les entiers sont stockés dans la variable correspondante sous forme de liste. Si compte est *, alors tous octets restants de string seront scannés. Si compte est omis, alors un entier 32-bit sera scanné. Par exemple, binary scan\x05\x00\x00\x00\x07\x00\x00\x00\xf0\xff\xff\xff i2i* var1 var2 renverra 2 avec 5 7 stocké dans var1 et -16 stocké dans var2. Notez que les entiers renvoyés sont signés et ne peuvent pas être représentés par Tcl comme valeurs non signées.

I Cette forme est la même que i excepté que les données sont interprétées comme compte entiers 32-bit signés représenté en big-endian. Par exemple, binary\x00\x00\x00\x05\x00\x00\x00\x07\xff\xff\xff\xf0 I2I* var1 var2 renverra 2 avec 5 7 stocké dans var1 et -16 stocké dans var2.

f Les données sont interprétées comme compte nombre flottants simple-précision dans la représentation native de la machine. Les nombres flottants sont stockés dans la variable correspondante sous forme de liste. Si compte est *, alors tous les octets restants de string seront scannés. Si compte est omis, alors un nombre flottant simple-précision sera scanné. La taille d'un nombre flottant peut varier selon les architectures, donc le nombre d'octets scannés peut varier. Si les données ne représentent pas un nombre flottant valide, la valeur résultante est indéfinie et dépend du compilateur. Par exemple, sur un système Windows s'exécutant sur un processeur Pentium Intel, binary scan\x3f\xcc\xcc\xcd f var1 >renverra 1 avec 1.6000000238418579 stocké dans var1.

d Cette forme est la même que f excepté que les données sont interprétées comme compte nombre flottants double-précision dans la représentation native de la machine. Par exemple, , sur un système Windows s'exécutant sur un processeur Pentium Intel, binary scan\x9a\x99\x99\x99\x99\x99\xf9\x3f d var1 renverra 1 avec 1.6000000000000001 stocké dans var1.

x Déplace le curseur en avant de compte octets dans string. Si compte est * ou est supérieur au nombre d'octets après la position courante du curseur, alors le curseur est positionné après le dernier octet de string. Si compte est omis, alors le curseur est déplacé en avant d'un octet. Notez que ce type n'attend pas d'argument. Par exemple, binary scan\x01\x02\x03\x04 x2H* var1 renverra 1 avec 0304 stocké dans var1.

X Déplace le curseur en arrière de compte octets dans string. Si compte est * ou est supérieur à la position courante du curseur, alors le curseur est positionné à la position 0 de telle sorte que le prochain octet scanné sera le premier octet de string. Si compte est omis alors le curseur est déplacé en arrière d'un octet. Notez que ce type n'attend pas d'argument. Par exemple, binary scan\x01\x02\x03\x04 c2XH* var1 var2 renverra 2 avec 1 2 stocké dans var1 et 020304 stocké dans var2.

@ Déplace le curseur à la position absolu de la chaîne spécifiée par compte. Notez que la position 0 correspondante au premier octet de string. Si compte correspond à une position au-delà de la fin de string, alors le curseur est positionné après le dernier octet. Si compte est omis, alors une erreur est générée. Par exemple, binary scan\x01\x02\x03\x04 c2@1H* var1 var2 renverra 2 avec 1 2 stocké dans var1 et 020304 stocké dans var2.

PLATFORM ISSUES

Il est parfois souhaitable de formater ou scanner des valeur entières dans l'ordre natif des octets de la machine. Référez vous à l'élément byteOrder du tableau tcl_platform pour connaître le caractère à utiliser pour formater ou scanner des entiers.

VOIR ÉGALEMENT

format, scan, tclvars


Traduit par Michel Salvagniac 2002-2003

Copyright © 2003 - Le Wiki Tcl/Tk Francophone.


Catégorie Manuel Tcl/Tk