2016-07-22 2 views
4

est-il possible de passer un certain champ lors de l'analyse d'un journal tronqué dans Kaitai Struct? Parce que s'il lit un champ (type spécifier à une énumération) mais valeur pas là, il lèvera un NullPointer Exception.
Je veux demander si un moyen d'atteindre cet comme default: pass attribut dans la bibliothèque python ConstructKaitai Struct: passer un certain champ pour atteindre la tolérance de panne

Voici mon fichier ksy:

meta: 
    id: btsnoop 
    endian: be 
seq: 
    - id: header 
    type: header 
    - id: packets 
    type: packet 
    repeat: eos 
types: 
    header: 
    seq: 
     - id: iden 
     size: 8 
     - id: version 
     type: u4 
     - id: datalink_type 
     type: u4 
     enum: linktype 
    packet: 
    seq: 
     - id: ori_len 
     type: u4 
     - id: include_len 
     type: u4 
     - id: pkt_flags 
     type: u4 
     - id: cumu_drop 
     type: u4 
     - id: timestamp 
     type: s8 
     - id: data 
     size: include_len 
     type: frame 
    frame: 
    seq: 
     - id: pkt_type 
     type: u1 
     enum: pkttype 
     - id: cmd 
     type: cmd 
     if: pkt_type == pkttype::cmd_pkt 
     - id: acl 
     type: acl 
     if: pkt_type == pkttype::acl_pkt 
     - id: evt 
     type: evt 
     if: pkt_type == pkttype::evt_pkt 
    cmd: 
    seq: 
     - id: opcode 
     type: u2le 
     - id: params_len 
     type: u1 
     - id: params 
     size: params_len 
    acl: 
    seq: 
     - id: handle 
     type: u2le 
    evt: 
    seq: 
     - id: status 
     type: u1 
     enum: status 
     - id: total_length 
     type: u1 
     - id: params 
     size-eos: true 
enums: <-- I need to list all possible option in every enum? 
    linktype: 
    0x03E9: unencapsulated_hci 
    0x03EA: hci_uart 
    0x03EB: hci_bscp 
    0x03EC: hci_serial 
    pkttype: 
    1: cmd_pkt 
    2: acl_pkt 
    4: evt_pkt 
    status: 
    0x0D: complete_D 
    0x0E: complete_E 
    0xFF: vendor_specific 

Merci pour la réponse :)

Répondre

3

Il y a encore deux les questions auxquelles vous faites face ici :)

Analyser les données partielles/tronquées/endommagées

Le problème principal ici est que normalement Kaitai Struct compile .ksy dans un code qui fait l'analyse réelle dans le constructeur de la classe. Cela signifie que si un problème survient, boom, vous n'avez aucun objet du tout. Dans la plupart des cas d'utilisation, il s'agit du comportement souhaité, car cela vous permet en fait de vous assurer que l'objet est entièrement initialisé. Le problème est généralement un EOFException, lorsque le format veut lire la primitive suivante, mais il n'y a pas de données dans le flux à gauche, ou, dans certains cas plus compliqués, quelque chose d'autre. Cependant, il y a des cas d'utilisation comme vous l'avez mentionné, où l'analyse syntaxique du «meilleur effort» serait utile - c'est-à-dire que vous êtes autorisé à avoir un objet à moitié plein. Un autre cas d'utilisation populaire est le visualiseur: il est utile de montrer le "meilleur effort" là aussi, car il est préférable de visualiser le résultat de l'utilisateur à moitié analysé (pour aider à localiser à l'erreur) plutôt que de utilisateur avec les devinettes).

Il existe une solution simple pour cela dans Kaitai Struct - vous pouvez compiler votre classe avec l'option --debug. De cette façon vous obtiendrez une classe qui a la création d'objet et l'analyse séparée, l'analyse serait juste une autre méthode d'un objet (void _read()). Cependant, cela signifie que vous devrez appeler la méthode d'analyse manuellement. Par exemple, si votre code d'origine était:

Btssnoop b = Btssnoop.fromFile("/path/to/file.bin"); 
System.out.println(b.packets.size()); 

après avoir compilé avec --debug, vous aurez à faire étape supplémentaire:

Btssnoop b = Btssnoop.fromFile("/path/to/file.bin"); 
b._read(); 
System.out.println(b.packets.size()); 

et vous pouvez l'envelopper dans un bloc try/catch et fait poursuivre le traitement même après avoir IOException:

Btssnoop b = Btssnoop.fromFile("/path/to/file.bin"); 
try { 
    b._read(); 
} catch (IOException e) { 
    System.out.println("warning: truncated packets"); 
} 
System.out.println(b.packets.size()); 

Il y a quelques prises, cependant:

  • --debug n'était pas encore disponible pour la cible Java, à partir de la version v0.3; En fait, ce n'est même pas dans le dépôt public git en ce moment, j'espère que je vais le pousser bientôt.
  • --debug fait également quelques choses supplémentaires, comme écrire des positions de chaque attribut, ce qui impose une pénalité de performance/mémoire assez sévère. Dites-moi si vous aurez besoin d'un commutateur pour compiler la fonctionnalité "constructeur/analyse séparé" sans le reste de la fonctionnalité --debug - Je peux penser à un autre commutateur pour activer cela.
  • Si vous avez besoin d'analyser continuellement les paquets entrants dès leur arrivée, il est probablement mauvais de les stocker tous en mémoire et de les ré-analyser tous à chaque mise à jour. Nous envisageons un modèle d'analyse basé sur les événements pour celui-là, s'il vous plaît dites-moi si vous seriez intéressé par celui-là.

les valeurs manquantes ENUM et NPE

implémentation actuelle Java se traduit énumérations la lecture en quelque chose comme

this.pet1 = Animal.byId(_io.readU4le()); 

où Animal.byId se traduit par:

private static final Map<Long, Animal> byId = new HashMap<Long, Animal>(3); 
static { 
    for (Animal e : Animal.values()) 
     byId.put(e.id(), e); 
} 
public static Animal byId(long id) { return byId.get(id); } 

retours de Java Carte get null par contrat, lorsqu'aucune valeur n'a été trouvée sur la carte. Vous devriez être capable de comparer cette nullité avec quelque chose (c'est-à-dire une autre valeur enum) et obtenir vrai vrai ou faux. Pouvez-vous me montrer exactement où vous avez un problème de NPE, c'est-à-dire votre code, votre code généré et votre trace de pile?