PureBasic

Forums PureBasic
Nous sommes le Mer 18/Sep/2019 14:52

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 7 messages ] 
Auteur Message
 Sujet du message: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Sam 05/Aoû/2017 15:41 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1655
Localisation: Belgique
Bonjour à tous,

Dans certain cas il est nécessaire de pouvoir lire dans un fichier un certain nombre d'octets de gauche à droite.

Exemple avec un fichier MIDI.

L'entête du fichier est la suivante "4D546864" ou "MThd" en caractères, si par exemple vous utilisé
Code:
Hex(ReadLong(0)) ; donne 6468544D


Vous constaterez que le résultat est inversé.

Voici une exemple avec une procédure qui vous donnera le résultat attendu.

Code:
; Create file for testing
CreateFile(0,"Test.txt")
; write some values for testing
WriteByte(0,$4D)
WriteByte(0,$54)
WriteByte(0,$68)
WriteByte(0,$64)
CloseFile(0)
OpenFile(0,"Test.txt")
; I read a long (4 octeds), look the result
; The result is wrong it is inverted.
Debug "The result is wrong it is inverted."
Debug Hex(ReadLong(0))
CloseFile(0)
Procedure ReadOcteds(IdFile,NumberOcteds,*Variable)
  Protected v.l,i,p=NumberOcteds
  For i=1 To NumberOcteds
    p-1
    v=ReadByte(IdFile)
    MoveMemory(@v,*Variable+p,1)
  Next
EndProcedure

Define test.l
OpenFile(0,"Test.txt")
ReadOcteds(0,4,@test)
CloseFile(0)
Debug "The result is correct."
Debug Hex(test)


_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Dernière édition par microdevweb le Dim 06/Aoû/2017 9:08, édité 2 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Sam 05/Aoû/2017 16:48 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8750
Sympa ça.
N'oubliez pas de rajouter un dernier CloseFile(0) en fin de code.

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Sam 05/Aoû/2017 16:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 13/Déc/2015 11:05
Messages: 649
Localisation: Allez, cherche...
Effectivement on a parfois ce problème, qui vient de l'ordre d'écriture des octets, ce qu'on apelle l' endianness. Typiquement, on utilise sur les architectures Intel-PC la méthode dite "little-endian", ou octet de poids faible en tête, et sur d'autres archi moins répandues (ARM, Sparc,...), la méthode du "big-endian", octet de poids fort en tête.
En big-endian, le premier bit est le plus élevé (celui qui code la partie la plus grande), et le dernier le plus faible, et inversement en little-endian, le premier est le plus faible...

Ainsi si l'on écrit le nombre 01A4 (420) en little-endian (comme c'est le cas sur la plupart de nos PC), puis que l'on lit l'un aprés l'autre ses deux octets, on a A401. En mémoire, les octets sont dans le sens inverse de celui dans lequel on les écrirait naturellement.

Je viens justement d'avoir ce probléme avec des cartes altimétriques de la Nasa qui sont en big-endian :)

Merci de ta procédure :) Elle va me servir

_________________
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Dim 06/Aoû/2017 9:07 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1655
Localisation: Belgique
Bien vu Ar-S,

J'ai corrigé.

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Dim 06/Aoû/2017 21:09 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 2065
ces procedures font la meme chose :)

Code:

Procedure.w xchEndianW(e.w)
      ;by wilbert
      ProcedureReturn (e & $FF) << 8 + (e >> 8) & $FF
EndProcedure

Procedure xchEndianL(e.l)
      ; by wilbert
      ProcedureReturn (e & $FF) << 24 + (e & $FF00) << 8 + (e >> 8) & $FF00 + (e >> 24) & $FF
EndProcedure

_________________
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Dim 06/Aoû/2017 21:27 
Hors ligne

Inscription: Dim 10/Jan/2010 5:29
Messages: 3426
Zorro a écrit:
ces procedures font la meme chose :)


Code:
Procedure.w xchEndianW(e.w)
      ;by wilbert
      ProcedureReturn (e & $FF) << 8 + (e >> 8) & $FF
EndProcedure

Procedure xchEndianL(e.l)
      ; by wilbert
      ProcedureReturn (e & $FF) << 24 + (e & $FF00) << 8 + (e >> 8) & $FF00 + (e >> 24)    & $FF
EndProcedure

Debug htonl_(65)
Debug xchEndianL(65)
   
Debug htons_(65)
Debug xchEndianW(65)




Les API aussi le font très bien , portable en plus :

https://linux.die.net/man/3/htonl
https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms738556(v=vs.85).aspx


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Récupérer les octets d'un fichier de gauche à droite
MessagePosté: Lun 07/Aoû/2017 8:35 
Hors ligne

Inscription: Sam 23/Fév/2008 17:58
Messages: 556
Bonjour à tous

Little-endian a encore frappé.

En effet seules, les architectures Motorola 68000, les SPARC (Sun Microsystems) ou encore les System/370 (IBM). Ou le protocole TCP/IP, sont en big-endian ou gros-boutistes ou mot de poids fort en tête.

Mais Intel a préféré le Little-endian ou les poids les plus faibles sont en tête c'est-à-dire dans l’adressage le plus faible.

Attention l’unité adressage est l’octet.
Donc si vous visualisez un octet en hexa ou en binaire il n’y a aucune inversion des bits ou du demi octet dans cette unité c'est à dire dans l'octet.
En little-endian les nombres ont des octets qui sont placés en ordre de poids, du poids le plus faible à la plus faible adresse jusqu’au poids le plus fort dans l’adresse la plus forte.

Enfin pour retrouver les nombres dans l’ordre dans lesquels on les lit en occident il suffit d’utiliser par exemple :
Soit Bin(..)
Soit Hex(..)

Resultat$ = Hex(Valeur.q [, Type])
Description
Convertit un entier en une valeur hexadécimale.
Arguments
Valeur.q Un entier de type 'quad'.
Type (optionnel) #PB_Quad : valeur sera traitée en quad (0 à 18446744073709551615)
#PB_Byte : La valeur est un octet (8-bit) allant de 0 à 255
#PB_Ascii : La valeur est un octet (8-bit) allant de 0 à 255
#PB_Word : La valeur est un word (16-bit) allant de 0 à 65535
#PB_Unicode: La valeur est un word (16-bit) allant de 0 à 65535
#PB_Long : La valeur est un long (32-bit) allant de 0 à 4294967295

Exemples sous PB560 en unicode

On peut remarquer dans le dump de la variable numer l’ordre des octets en parfait concordance avec la définition de litte-endian.

Code:
structure NUM
  VB.B
  VW.w
  VL.l
  Vq.q
  VF.F
  VD.D
  VS.s{18}
EndStructure

macro _HEX (__ad,lng,flag)
;  CompilerIf #PB_Compiler_Unicode =0
;     ; en ascii  le nombre d'octets est le même que la longueur en caractères lng=lng
;   CompilerElse
;     ; en unicode le nombre d'octets  est double de la longueur en caractères
;     lng=lng*2
;   CompilerEndIf
  sort.s=""
  hexs.s=""
  cart$=""
  If flag=0
; ;     teth.s=" Unité     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1"+#LF$
      teth.s="Adresse___00_01_02_03_04_05_06_07_08_09_0A_0B_0C_0D_0E_0F_10_11_12_13_14_15_16_17_18_19_1A_1B_1C_1D_1E_1F_20_21_22_23_24_25_26_27_28_29_2A_2B_2C_2D_2E_2F_30_31_32_33_34_35_36_37_38_39_3A_3B_3C_3D_3E_3F_40_41"
      sort.s=Left(teth,(lng-1)*3+12)+"        ASCII"+#LF$
    flag=1
  EndIf
  For i=0 To lng-1
    num.c=PeekA(__ad+i)
    If Chr(num)<" " or num>128
      cart$=cart$+"."
    Else
      cart$=cart$+Chr(num)
    EndIf
    hexs.s=hexs.s+RSet(Hex(num),2,"0")+"_"
  Next
    sort.s+RSet(Hex(__ad),8,"0")+"  "+hexs+"    "+cart$+#LF$
    debug sort
endmacro

lng=16
define numer.num
numer\VB=$EF
numer\VW=$1234
numer\VL=$56789ABC
numer\Vq=$0123456789ABCDEF
numer\VS="Jean-Claude Durand"
flg=0
__ad=numer
_hex(__ad,lng,flg)
    debug "VB="+hex(numer\VB,#PB_Byte  )
    debug "VW="+hex(numer\VW,#PB_Word  )
    debug "VL="+hex(numer\Vl,#PB_Long  )
    debug "VQ="+hex(numer\Vq,#PB_Quad  )
    __ad=@numer\VS
    lng=36  ; doubler le nombre d'octets en unicode donner le nombre de caractère en ascii
    flg=0
_Hex(__ad,lng,flg)   



A+

_________________
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 7 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 3 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye