J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php, html ou
autre fichier texte), les fonctions API WideCharToMultiByte() et
MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.
Connaissez-vous d'autres axes de récherche en VB6 ?
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5), ce devrait être extrèmement efficace !
Oui, mais contrairement à ce qui est proposé dans ton article (et pour ce cas j'entends), je resterais en interprétation binaire. Soit à déclarer le buffer en tableau d'octets et non en chaîne. Ce qui devrait d'ailleurs diviser par deux l'espace mémoire utilisé. Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet octet And 11100000 = 11000000 => premier octet d'un caractère sur deux octets octet And 11110000 = 11100000 => premier octet d'un caractère sur trois octets octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre octets octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Pour être complet, il y a des séquences non valides en UTF-8 qu'il faudrait traiter mais je crois que l'article sur wikipedia y fait référence. Sinon, voir par exemple ici : http://www.ietf.org/rfc/rfc3629.txt
Merci à vous deux. Je prévois de tester les 2 méthodes dès que j'en aurai terminé avec ma maçonnerie. -- Cordialement
Aski MVP Windows Desktop Experience
Hello Fred et Jean-Marc,
"Fred" <foleide@free.fr.invalid> a écrit
Jean-marc écrivait :
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux
(http://faq.vb.free.fr/index.php?question5), ce devrait être
extrèmement efficace !
Oui, mais contrairement à ce qui est proposé dans ton article (et pour ce
cas j'entends), je resterais en interprétation binaire. Soit à déclarer le
buffer en tableau d'octets et non en chaîne. Ce qui devrait d'ailleurs
diviser par deux l'espace mémoire utilisé. Et ensuite faciliter le
traitement des octets en effectuant des masquages binaires.
octet And 10000000 = 00000000 => caractère mono-octet
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux
octets
octet And 11110000 = 11100000 => premier octet d'un caractère sur trois
octets
octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre
octets
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets
Pour être complet, il y a des séquences non valides en UTF-8 qu'il
faudrait traiter mais je crois que l'article sur wikipedia y fait
référence. Sinon, voir par exemple ici :
http://www.ietf.org/rfc/rfc3629.txt
Merci à vous deux. Je prévois de tester les 2 méthodes dès que j'en aurai
terminé avec ma maçonnerie.
--
Cordialement
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5), ce devrait être extrèmement efficace !
Oui, mais contrairement à ce qui est proposé dans ton article (et pour ce cas j'entends), je resterais en interprétation binaire. Soit à déclarer le buffer en tableau d'octets et non en chaîne. Ce qui devrait d'ailleurs diviser par deux l'espace mémoire utilisé. Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet octet And 11100000 = 11000000 => premier octet d'un caractère sur deux octets octet And 11110000 = 11100000 => premier octet d'un caractère sur trois octets octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre octets octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Pour être complet, il y a des séquences non valides en UTF-8 qu'il faudrait traiter mais je crois que l'article sur wikipedia y fait référence. Sinon, voir par exemple ici : http://www.ietf.org/rfc/rfc3629.txt
Merci à vous deux. Je prévois de tester les 2 méthodes dès que j'en aurai terminé avec ma maçonnerie. -- Cordialement
Aski MVP Windows Desktop Experience
aski
Hello Jean-Marc,
"Jean-marc" a écrit dans le message de groupe de discussion : 48adcf7f$0$2856$
aski wrote:
Re,
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit automate d'état fini dont Jean-Marc a le secret, devrait être extrêmement rapide !
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5), ce devrait être extrèmement efficace !
Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette. :-(
C'est trop d'honneur :-)
Rien de bien compliqué en soi dans les automates. Je pense que l'exemple que j'ai indiqué dans la FAQ doit permettre de comprendre le principe: http://faq.vb.free.fr/index.php?question3
Effectivement, il m'est arrivé de faire des automates sans le savoir .... :o)
Une petite question : pourquoi utiliser (InStr(validStates, Trim$(Str$(etat)) & ",") > 0) et non (etat =1 or etat =4) par exemple ? Est-ce pour gagner de la vitesse ? -- Cordialement
Aski MVP Windows Desktop Experience
Hello Jean-Marc,
"Jean-marc" <jm@nowhere.invalid> a écrit dans le message de groupe de
discussion : 48adcf7f$0$2856$ba620e4c@news.skynet.be...
aski wrote:
Re,
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être
extrêmement rapide !
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5),
ce devrait être extrèmement efficace !
Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette.
:-(
C'est trop d'honneur :-)
Rien de bien compliqué en soi dans les automates. Je pense que l'exemple
que j'ai indiqué dans la FAQ doit permettre de comprendre le principe:
http://faq.vb.free.fr/index.php?question3
Effectivement, il m'est arrivé de faire des automates sans le savoir ....
:o)
Une petite question : pourquoi utiliser
(InStr(validStates, Trim$(Str$(etat)) & ",") > 0)
et non
(etat =1 or etat =4) par exemple ?
Est-ce pour gagner de la vitesse ?
--
Cordialement
"Jean-marc" a écrit dans le message de groupe de discussion : 48adcf7f$0$2856$
aski wrote:
Re,
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit automate d'état fini dont Jean-Marc a le secret, devrait être extrêmement rapide !
Je confirme :o) Couplé avec une lecture binaire rapide si le fichier n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5), ce devrait être extrèmement efficace !
Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette. :-(
C'est trop d'honneur :-)
Rien de bien compliqué en soi dans les automates. Je pense que l'exemple que j'ai indiqué dans la FAQ doit permettre de comprendre le principe: http://faq.vb.free.fr/index.php?question3
Effectivement, il m'est arrivé de faire des automates sans le savoir .... :o)
Une petite question : pourquoi utiliser (InStr(validStates, Trim$(Str$(etat)) & ",") > 0) et non (etat =1 or etat =4) par exemple ? Est-ce pour gagner de la vitesse ? -- Cordialement
Aski MVP Windows Desktop Experience
jean-marc
"aski" wrote in message news:
Hello Jean-Marc,
Hello Aski,
Une petite question : pourquoi utiliser (InStr(validStates, Trim$(Str$(etat)) & ",") > 0) et non (etat =1 or etat =4) par exemple ?
C'est pour centraliser au début de la fonction la description des états valides, dans une seule variable.
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Est-ce pour gagner de la vitesse ?
Non :-)
Le (Instr + Trim + Str) est environ 700 fois plus lent qu'un simple test avec un IF et des OR...
Mais au bout du compte, la différence est petite car ce traitement final est petit comparé au reste...
Avec des If au lieu du Instr, on gagne plus ou mois 1 microseconde par appel.
Il faut donc faire 1 million d'appels à la fonction pour gagner une seconde.
Donc, à moins d'avoir des contraintes de performances extrèmement sévères, dans un programme dont le seul but est d'appeller cette fonction, plusieurs dizaines ou centaines de millions de fois, ça ne fait pas différence.
Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
"aski" <aski@asc.asc> wrote in message
news:uRPy6grBJHA.2056@TK2MSFTNGP05.phx.gbl...
Hello Jean-Marc,
Hello Aski,
Une petite question : pourquoi utiliser
(InStr(validStates, Trim$(Str$(etat)) & ",") > 0)
et non
(etat =1 or etat =4) par exemple ?
C'est pour centraliser au début de la fonction la
description des états valides, dans une seule variable.
Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.
On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Est-ce pour gagner de la vitesse ?
Non :-)
Le (Instr + Trim + Str) est environ 700 fois plus lent
qu'un simple test avec un IF et des OR...
Mais au bout du compte, la différence est petite car ce
traitement final est petit comparé au reste...
Avec des If au lieu du Instr, on gagne plus ou
mois 1 microseconde par appel.
Il faut donc faire 1 million d'appels à la fonction
pour gagner une seconde.
Donc, à moins d'avoir des contraintes de performances
extrèmement sévères, dans un programme dont le seul
but est d'appeller cette fonction, plusieurs dizaines ou
centaines de millions de fois, ça ne fait pas différence.
Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).
Une petite question : pourquoi utiliser (InStr(validStates, Trim$(Str$(etat)) & ",") > 0) et non (etat =1 or etat =4) par exemple ?
C'est pour centraliser au début de la fonction la description des états valides, dans une seule variable.
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Est-ce pour gagner de la vitesse ?
Non :-)
Le (Instr + Trim + Str) est environ 700 fois plus lent qu'un simple test avec un IF et des OR...
Mais au bout du compte, la différence est petite car ce traitement final est petit comparé au reste...
Avec des If au lieu du Instr, on gagne plus ou mois 1 microseconde par appel.
Il faut donc faire 1 million d'appels à la fonction pour gagner une seconde.
Donc, à moins d'avoir des contraintes de performances extrèmement sévères, dans un programme dont le seul but est d'appeller cette fonction, plusieurs dizaines ou centaines de millions de fois, ça ne fait pas différence.
Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
"jean-marc" a écrit dans le message de groupe de discussion : 48b2c564$0$2848$
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
... et également les Select Case, non ?
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Donc, à moins d'avoir des contraintes de performances Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce. -- Cordialement
Aski MVP Windows Desktop Experience
Re,
"jean-marc" <jean_marc_n2@yahoo.fr.invalid> a écrit dans le message de
groupe de discussion : 48b2c564$0$2848$ba620e4c@news.skynet.be...
Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.
... et également les Select Case, non ?
On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Donc, à moins d'avoir des contraintes de performances
Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.
--
Cordialement
"jean-marc" a écrit dans le message de groupe de discussion : 48b2c564$0$2848$
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
... et également les Select Case, non ?
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Donc, à moins d'avoir des contraintes de performances Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce. -- Cordialement
Aski MVP Windows Desktop Experience
Jean-marc
aski wrote:
Re,
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
... et également les Select Case, non ?
Oui, en effet :-)
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR". Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Je trouve aussi.
Donc, à moins d'avoir des contraintes de performances Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.
C'est vrai qu'un commentaire n'aurait pas été supeflu !
Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.
... et également les Select Case, non ?
Oui, en effet :-)
On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Je trouve aussi.
Donc, à moins d'avoir des contraintes de performances
Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.
C'est vrai qu'un commentaire n'aurait pas été supeflu !
Ainsi, si on modifie l'automate et qu'on modifie les états valides (ajout, suppression, modification, etc.) il suffit de modifier la variable validStates.
... et également les Select Case, non ?
Oui, en effet :-)
On peut aussi avoir un automate plus grand avec plein d'états finaux et alors ça évite une longue séquence de "OR". Bref, c'est une question de lisibilité du code.
Effectivement, dans ce cas, c'est plus "propre".
Je trouve aussi.
Donc, à moins d'avoir des contraintes de performances Et on gagne à mon sens en lisibilité en utilisant la forme avec Instr (ou avec toute forme d'écriture similaire).
C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.
C'est vrai qu'un commentaire n'aurait pas été supeflu !
Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux octets octet And 11110000 = 11100000 => premier octet d'un caractère sur trois octets octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre octets octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet puisqu'on lit au préalable le nombre d'octets du caractère codé.
Pour être complet, il y a des séquences non valides en UTF-8 qu'il faudrait traiter mais je crois que l'article sur wikipedia y fait référence. Sinon, voir par exemple ici : http://www.ietf.org/rfc/rfc3629.txt
J'ai également trouvé ce pdf dont le tableau 3-1B précise clairement les codes valides http://hapax.qc.ca/pdf/Chapitre-3.pdf -- Cordialement
Aski MVP Windows Desktop Experience
Salut Fred,
Et ensuite faciliter le traitement des octets en effectuant des masquages
binaires.
octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux
octets
octet And 11110000 = 11100000 => premier octet d'un caractère sur trois
octets
octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre
octets
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet
puisqu'on lit au préalable le nombre d'octets du caractère codé.
Pour être complet, il y a des séquences non valides en UTF-8 qu'il
faudrait traiter mais je crois que l'article sur wikipedia y fait
référence. Sinon, voir par exemple ici :
http://www.ietf.org/rfc/rfc3629.txt
J'ai également trouvé ce pdf dont le tableau 3-1B précise clairement les
codes valides
http://hapax.qc.ca/pdf/Chapitre-3.pdf
--
Cordialement
Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux octets octet And 11110000 = 11100000 => premier octet d'un caractère sur trois octets octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre octets octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet puisqu'on lit au préalable le nombre d'octets du caractère codé.
Pour être complet, il y a des séquences non valides en UTF-8 qu'il faudrait traiter mais je crois que l'article sur wikipedia y fait référence. Sinon, voir par exemple ici : http://www.ietf.org/rfc/rfc3629.txt
J'ai également trouvé ce pdf dont le tableau 3-1B précise clairement les codes valides http://hapax.qc.ca/pdf/Chapitre-3.pdf -- Cordialement
Aski MVP Windows Desktop Experience
Fred
"aski" a écrit dans le message de news:
Salut Fred,
Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
C'est le caractère correspondant à la valeur de l'octet dans le jeu ASCII (octets de 0 à 127)
octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet puisqu'on lit au préalable le nombre d'octets du caractère codé.
On cherche à savoir si le fichier est un fichier UTF-8, alors il faut au moins vérifier que les deux bits de poids forts sont 1 et 0.
Cela constitue d'ailleurs un des avantages de l'UTF-8 : il est très facile de se repositionner sur un début de séquence en cas de suite non valide ou d'erreurs de lecture.
-- Fred
"aski" <aski@asc.asc> a écrit dans le message de
news:OVBfaHqCJHA.4744@TK2MSFTNGP05.phx.gbl...
Salut Fred,
Et ensuite faciliter le traitement des octets en effectuant des
masquages
binaires.
octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
C'est le caractère correspondant à la valeur de l'octet dans le jeu
ASCII (octets de 0 à 127)
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet
puisqu'on lit au préalable le nombre d'octets du caractère codé.
On cherche à savoir si le fichier est un fichier UTF-8, alors il faut au
moins vérifier que les deux bits de poids forts sont 1 et 0.
Cela constitue d'ailleurs un des avantages de l'UTF-8 : il est très
facile de se repositionner sur un début de séquence en cas de suite non
valide ou d'erreurs de lecture.
Et ensuite faciliter le traitement des octets en effectuant des masquages binaires. octet And 10000000 = 00000000 => caractère mono-octet
OK, dans ce cas le type de codage est indéterminé.
C'est le caractère correspondant à la valeur de l'octet dans le jeu ASCII (octets de 0 à 127)
octet And 11000000 = 10000000 => octet de suite d'un caractère multi-octets
Il me semble qu'il ne devrait pas être nécessaire de lire cet octet puisqu'on lit au préalable le nombre d'octets du caractère codé.
On cherche à savoir si le fichier est un fichier UTF-8, alors il faut au moins vérifier que les deux bits de poids forts sont 1 et 0.
Cela constitue d'ailleurs un des avantages de l'UTF-8 : il est très facile de se repositionner sur un début de séquence en cas de suite non valide ou d'erreurs de lecture.