Question

Étant donné une chaîne binaire codée sur 1 octet, est-il possible de cartographier plusieurs des morceaux de cet octet en une valeur ENUM?
par exemple. : Je suppose que veux couper mon champ dans ceci:

  • et Bit1 Bit2 = field1
  • Bit3 = field2
  • Bit4 = field3
  • Bit5 = field4
  • autres bits sont inutilisés

Comment pourrais-je la carte que, disons:

public enum MyEnum {
    FIELD1, FIELD2, FIELD3, FIELD4;

    private static final EnumSet<MyEnum> ALLFIELDS = EnumSet.allOf(MyEnum.class);

}

Ce que je suis en train de faire est de filtrer ces valeurs enum en utilisant un masque. Pour cela, je l'ai fait la méthode suivante:

public static <E extends Enum<E>> EnumSet<E> filterWithBitMask(EnumSet<E> set, int bitmask) {
    List<E> kept = new ArrayList<E>();
    for (E property : set) {
        if ((bitmask & (1 << ((Enum<E>) property).ordinal())) != 0) {
            kept.add(property);
        }
    }
    EnumSet<E> selectedProperties = set.clone();
    selectedProperties.retainAll(kept);
    return selectedProperties;
}

Cela fonctionne bien aussi longtemps que mes champs ENUM représentent un peu, mais je ne peux pas comprendre comment les combiner en un seul champ. Désolé si cela semble évident, mais cela est la première fois que je manipuler des données au niveau du bit ...

EDIT COMMENTAIRES: J'ai modifié la structure de terrain pour représenter ce que j'ai vraiment. Donc, le seul champ qui couvre plus de 1 bit est field1. Sur la base de la présence de Bit1 et Bit2, j'attribue une variable de poids à field1.

public enum MyByte {    
    BIT_1, BIT_2, BIT_3, BIT_4, BIT_5;

    private static final EnumSet<MyByte> ALLPROPERTIES = EnumSet.allOf(MyByte.class);

    public static EnumSet<Fields> getValues(int bitmask) {
        EnumSet<MyByte> selectedBits = filterWithBitMask(ALLPROPERTIES, bitmask);
        int weight = 0;
        EnumSet<Fields> fields = null;
        if (selectedBits.contains(BIT_1)) 
            weight += 1;
        if (selectedBits.contains(BIT_2))
            weight += 2;
        if (selectedBits.contains(BIT_1) || selectedBits.contains(BIT_2)) 
            fields = EnumSet.of(Fields.FIELD1.setValue(weight));
        if (selectedBits.contains(BIT_3)) {
            if (fields != null)
                fields.add(Fields.FIELD2);
            else fields = EnumSet.of(Fields.FIELD2);
        }
        if (selectedBits.contains(BIT_4)) {
            if (fields != null)
                fields.add(Fields.FIELD3);
            else fields = EnumSet.of(Fields.FIELD3);
        }

        if (selectedBits.contains(BIT_5)) {
            if (fields != null)
                fields.add(Fields.FIELD4);
            else fields = EnumSet.of(Fields.FIELD4);
        }

        return fields;
    }

    public enum Fields {

        // BIT_1 and BIT_2
        FIELD1,
        // BIT_3
        FIELD2,
        // BIT_4
        FIELD3,
        // BIT_5
        FIELD4;

        private int value;

        public Fields setValue(int i) {
            this.value = i;
            return this;
        }

    }


}

Voici la solution sale je suis venu avec pour l'instant, mais je ne l'aime vraiment pas tous les cas énoncés. Si quelqu'un a une meilleure solution, je serais heureux de changer cela; -)

Merci!

Était-ce utile?

La solution

pas tout à fait sûr de ce que vous voulez. cela pourrait être d'intérêt:

import java.util.*;
enum Field {
    field1((byte) 0xc0) {
        int filter_(byte mask) { // you may want this one to be different
            return mask & this.mask;
        }
    },
    field2((byte) 0x20), field3((byte) 0x10), field4((byte) 0x08);
    Field(byte mask) {
        this.mask = mask;
    }
    int filter_(byte mask) {
        return mask & this.mask;
    }
    static EnumSet<Field> filter(byte mask) {
        final EnumSet<Field> fields = EnumSet.noneOf(Field.class);
        for (Field field : values())
            if (field.filter_(mask) != 0) fields.add(field);
        return fields;
    }
    final byte mask;
}
public class Main {
    public static void main(String[] args) {
        for(Field field:Field.values()) {
            System.out.println(Field.filter(field.mask));
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top