package eg.ufe.codecorrecteur; import java.util.Arrays; /** * Bloc de données transmis. Composé de 3 octets censés représenter le même * octet. Cet octet est copié 2 fois au départ, ce qui permet à l'arrivée de * repérer et de corriger des erreurs de transmission. * * Cette version permet d'obtenir un rapport sur les erreurs de transmission. */ public class BlocAvecRapportErreurs { private byte[] data = new byte[3]; public enum TypeErreur { CORRECT, CORRECTION, ERREUR }; /** * Indique si une erreur a été repérée lors du dernier décodage (voir les * constantes ci-dessus). */ private TypeErreur typeErreur = null; /** * Indique si le décodage doit rapporter les corrections et erreurs. */ private boolean avecRapport = false; /** * Construit un bloc en dupliquant 2 fois un octet. Il s'agit du codage de la * donnée passée en paramètre. * * @param donnee * donnée codée par le bloc. * @param avecRapport */ public BlocAvecRapportErreurs(byte donnee) { data[0] = donnee; data[1] = donnee; data[2] = donnee; } public TypeErreur getTypeErreur() { return typeErreur; } // public byte get(int i) { // return data[i]; // } /** * Retourne la valeur supposée être représentée par le bloc. Version * "détaillée", plus simple à trouver que getValeur(). * * @return la valeur supposée être représentée par le bloc. */ public byte getValeurDecodeeAvecRapport() { if (data[0] == data[1] && data[0] == data[2]) { // Les 3 sont égaux // Dans le cas où il y a peu d'erreurs de transmission, on commence par ce // cas. typeErreur = TypeErreur.CORRECT; return data[0]; } if (data[0] == data[1] || data[0] == data[2]) { // Le premier est égal à un des 2 autres donc c'est la bonne valeur dans // data[0] typeErreur = TypeErreur.CORRECTION; return data[0]; } else { if (data[1] == data[2]) { // Le 2ème est égal au 3ème mais pas au 1er typeErreur = TypeErreur.CORRECTION; return data[1]; } else { // 3 valeurs différentes ! On ne peut rien faire pour réparer // Pour ce 1er programme, on retourne la valeur de data[0] typeErreur = TypeErreur.ERREUR; return data[0]; } } } /** * Retourne la valeur supposée être représentée par le bloc. Pas de rapport de * ce qui s'est passé pendant le décodage du bloc. * * @return la valeur du bloc décodé. */ public byte getValeurDecodee() { if (data[1] == data[2]) { // Le seul cas où on ne retourne pas data[0] return data[1]; } else { return data[0]; } } /** * Méthode utilitaire pour coder un tableau d'octets en tableau de Bloc. * * @param valeurs * @return */ public static BlocAvecRapportErreurs[] coder(byte[] valeurs) { BlocAvecRapportErreurs[] resultat = new BlocAvecRapportErreurs[valeurs.length]; for (int i = 0; i < valeurs.length; i++) { resultat[i] = new BlocAvecRapportErreurs(valeurs[i]); } return resultat; } /** * Méthode utilitaire pour décoder un tableau de blocs en tableau d'octet. * Pour chaque bloc on enregistre ou non (selon le paramètre avecRapport) * s'il y a eu un problème de décodage (erreur de transmission). * * @param valeursTransmises * les blocs à décoder * @return les octets obtenus à partir des blocs */ public static byte[] decoder(BlocAvecRapportErreurs[] blocsTransmis, boolean avecRapport) { byte[] resultat = new byte[blocsTransmis.length]; if (avecRapport) { for (int i = 0; i < blocsTransmis.length; i++) { resultat[i] = blocsTransmis[i].getValeurDecodeeAvecRapport(); } } else { for (int i = 0; i < blocsTransmis.length; i++) { resultat[i] = blocsTransmis[i].getValeurDecodee(); } } return resultat; } /** * Méthode utilitaire pour décoder un tableau de blocs en tableau d'octet * en enregistrant s'il y a eu un problème de décodage (erreur de transmission). * @param blocsTransmis * @return */ public static byte[] decoder(BlocAvecRapportErreurs[] blocsTransmis) { return decoder(blocsTransmis, true); } /** * Simule une erreur de transmission du bloc. * * @param i * numéro de l'exemplaire de l'octet modifié. * @param valeur * valeur modifiée */ public void simulationErreurTransmission(int i, byte valeur) { data[i] = valeur; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return "Bloc {data=" + Arrays.toString(data) + "}"; } }