Strukturen-Werkzeug

Allgemein

Das Strukturen-Werkzeug erlaubt die Untersuchung und Bearbeitung von Byte-Feldern auf der Basis von benutzerdefinierten Strukturdefinitionen, die aus Feldern, Verbunden, einfachen Typen und Aufzählungswerten erstellt werden können.

Dieses Werkzeug hat einen eigenen Einrichtungsdialog, der durch den Knopf Einstellungen geöffnet wird. In dem Dialog kann unter anderem der Anzeigestil (Dezimal, Hexadezimal, Binär) der Werte festgelegt werden. Außerdem kann ausgewählt werden, welche Strukturdefinition geladen und welche Strukturen in der Ansicht dargestellt werden.

Strukturen werden in Okteta in Strukturdefinitions-Dateien auf der Basis von XML-Dateien mit der Erweiterung .osd definiert. Zusätzlich gibt es eine .desktop-Datei mit Metadaten über die Strukturdefinitions-Datei wie zum Beispiel Autor, Webseite oder Lizenz.

Zurzeit ist es nicht möglich, Strukturdefinitionen in Okteta zu erstellen oder zu bearbeiten. Diese Definitionen müssen daher wie im nächsten Abschnitt beschrieben manuell erstellt werden.

Strukturdefinitionen installieren

Installation von Strukturen mit der Funktion „Neue Erweiterungen“ herunterladen

Am einfachsten lassen sich neue Strukturen mit der Funktion „Neue Erweiterungen“ herunterladen in Okteta installieren. Dazu öffnen Sie den Einrichtungsdialog des Strukturwerkzeugs. Gehen Sie zur Seite Strukturen-Verwaltung und drücken den Knopf Neue Strukturen holen. Im Dialog, der dann geöffnet wird, können Strukturen installiert und deinstalliert werden.

Strukturdefinitionen manuell installieren

Das Werkzeug Strukturen sucht die Definitionen der Strukturen im Unterordner okteta/structures/ im Datenordner für Programme im Persönlichen Ordner des Benutzers. Diesen Ordner finden Sie mit der Eingabe von qtpaths --paths GenericDataLocation auf der Konsole. Wenn noch keine Strukturdefinitionen installiert wurden, muss dieser Ordner angelegt werden.

Für jede Strukturdefinition gibt es zwei Dateien: Eine Datei mit der tatsächlichen Definition und eine .desktop-Datei mit den Metadaten (Autor, Version usw.).

In diesem Ordner gibt es für jede Strukturdefinition einen eigenen Unterordner, der sowohl die .desktop-Datei und auch die .osd-Datei oder die main.js-Datei mit der Strukturdefinition.

Ist zum Beispiel der Datenordner der Programme qtpaths --paths GenericDataLocation, dann finden Sie eine Strukturdefinition namens BeispielStruktur im Unterordner okteta/structures/BeispielStruktur, darin dann die Dateien BeispielStruktur.desktop und BeispielStruktur.osd.

Neu installierte Strukturen benutzen

Wenn Sie eine neue Strukturdefinition installiert haben, müssen Sie Okteta neu starten, um sie benutzen zu können. Nach den Neustart von Okteta den Einrichtungsdialog der Strukturen öffnen. Wählen Sie dort die Seite Strukturen-Verwaltung und überprüfen Sie, ob die neue Strukturdefinition ausgewählt ist. Wechseln Sie dann zur Seite Strukturen und überprüfen Sie, ob das gewünschte Element in der rechten Liste enthalten ist.

Strukturdefinitionen gemeinsam nutzen

Allgemein gebräuchlich Strukturen müssen Sie wahrscheinlich nicht selbst definieren, sondern können zum Beispiel vorhandene Definitionen von der Seite store.kde.org benutzen.

Möchten Sie eine Strukturdefinition im Internet zur Verfügung stellen, packen Sie den Unterordner mit der .desktop-Datei und der Strukturdefinitions-Datei in ein Archiv, zum Beispiel ein gezipptes Tar-Archiv (.tar.gz). Bei dem Beispiel im vorigen Abschnitt ist das der Unterordner BeispielStruktur mit allen Dateien darin. Verwenden Sie diese Format, dann können Strukturdefinitionen in Okteta installiert werden. Eine manuelle Installation ist dann nicht erforderlich.

Strukturdefinitionen erstellen

Anmerkung

Eine aktuellere aber unvollständige Anleitung zum Schreiben von Strukturdefinitionen finden Sie im KDE UserBase Wiki.

Es gibt zwei Möglichkeiten, um eine Strukturdefinition zu erstellen, entweder im XML-Format oder als JavaScript. Mit JavaScript können Sie komplexere Strukturen mit Funktionen wie zum Beispiel der Überprüfung der Gültigkeit der Struktur schreiben. Mit XML haben Sie weniger Funktionen, wenn Ihnen aber eine statische Struktur reicht, ist das der einfachste Ansatz. Brauchen Sie dynamische Strukturen, bei denen zum Beispiel eine Feldlänge oder das Strukturlayout von anderen Werten in der Struktur abhängt, dann müssen Sie die Strukturdefinition in JavaScript schreiben. Es gibt eine Ausnahme für diese Regel: Haben Sie ein Feld, dessen Länge genau wie ein anderer Wert in der Struktur angenommen wird, dann können Sie auch XML verwenden. Ist dieser Wert aber so ähnlich wie Länge -1, dann müssen Sie JavaScript benutzen.

XML-Dateiformat einer Strukturdefinition

Anmerkung

Eine aktuellere aber unvollständige Anleitung zum Schreiben von Strukturdefinitionen finden Sie im KDE UserBase Wiki.

Die .osd-XML-Datei hat ein oberstes Element: <data> ohne Attribute. Innerhalb dieses Elements muss eines der folgenden Elemente enthalten sein:

<primitive>

Erstellt einen einfachen Typ wie z. B. int und float. Dieses Element kann keine untergeordneten Elemente enthalten und darf nur folgende Attribute haben:

type

Der Typ dieses einfachen Typs. Folgende Typen sind erlaubt:

  • char für ein 8 Bit ASCII-Zeichen

  • int8, int16, int32, int64 für Ganzzahlwerte dieser Größen mit Vorzeichen

  • uint8, uint16, uint32, uint64 für Ganzzahlwerte dieser Größen ohne Vorzeichen

  • bool8, bool16, bool32, bool64 für einen vorzeichenlosen Boole'schen Wert (0 = falsch, jeder andere Wert = wahr) dieser Größe

  • float für eine 32 Bit Fließkommazahl nach IEEE754

  • double für eine 64 Bit Fließkommazahl nach IEEE754

<bitfield>

Zur Definition eines Bitfelds. Dieses Element kann keine untergeordneten Elemente enthalten und darf nur folgende Attribute haben:

width

Die Anzahl der von diesem Bitfeld benutzten Bits. Der Wert muss zwischen 1 und 64 liegen.

type

Der Typ dieses Bitfelds. Folgende Werte sind erlaubt:

  • unsigned für ein Bitfeld, dessen Wert als vorzeichenlos interpretiert wird (Wertebereich von 0 bis 2width - 1)

  • signed für ein Bitfeld, dessen Wert als Wert mit Vorzeichen interpretiert wird (Wertebereich von -2width - 1 bis 2width - 1 - 1)

  • bool für ein Bitfeld, dessen Wert als Boolescher Wert interpretiert wird

Anmerkung

Denken Sie daran für „padding“ nach einem <bitfield> einen Wert anzugeben, sonst beginnt das nächste Element (ausgenommen Zeichenfolgen (strings) und Felder (arrays), die „padding“ automatisch einfügen) mitten in einem Byte. Ist dieses Verhalten gewünscht, brauchen Sie offensichtlich kein „padding“ anzugeben.

<enum>

Zur Definition eines einfachen Typs bei dem alle Werte als Elemente einer Aufzählung dargestellt werden. Diese Element kann keine untergeordneten Elemente enthalten, Sie brauchen jedoch ein Tag <enumDef> in der Datei zur Referenzierung. Folgende Attribute sind erlaubt:

enum

Die zurückliegende Aufzählung für diesen Wert. Muss zu dem Attribut name in einer der Tags <enumDef> in dieser Datei passen.

type

Der Typ dieser Aufzählung, mögliche Typen wie beim Element <primitive>. Nur die Typen Double und Float sind hier nicht sinnvoll.

<flags>

Dies ähnelt dem Element <enum>, mit dem einen Unterschied, dass die Werte als bitweises Oder aller Werte der Aufzählung dargestellt werden.

<struct>

Zur Definition einer Struktur. Alle anderen Element einschließlich <struct> können als untergeordnetes Element eingefügt werden und sind dann Bestandteil der gesamten Struktur.

<union>

Zur Definition eines Verbund-Datentyps. Ein Verbund ähnelt einem Datentyp <struct>, aber alle untergeordneten Elemente beginnen am gleichen Versatz. Nützlich für die Darstellung der gleichen Bytefolge auf verschiedene Arten.

<array>

Zur Definition eines Felds. Diese Element kann nur ein untergeordnete Element - den Typ des Felds - enthalten. Dieser Typ keine ein beliebiges Element sein, sogar ein <array> selbst. Es hat folgende Attribute:

length

Die Anzahl der Elemente in diesem Feld als Dezimalzahl. Alternativ kann hier auch eine Zeichenfolge für das Attribut „Name“ eines bereits definierten Elements <primitive>, <enum> or <flags> angeben werden, Der Wert dieses Elements gibt dann die Länge an. Dieser Wert ist zurzeit auf 10000 begrenzt, da größere Felder zu viel Speicher belegen und dieses Werkzeug verlangsamen.

<string>

Zur Definition einer Zeichenfolge in verschiedenen Kodierungen. Standard ist eine durch NULL begrenzte C-Zeichenfolge. Andere Arten von Zeichenfolgen können mit folgenden Attributen erzeugt werden:

terminatedBy

Dieses Attribut legt fest, welcher Unicode-Codepunkt die Zeichenfolge begrenzt. Der Wert muss eine hexadezimale Zahl sein, wahlweise mit führendem 0x. Ist die Zeichenfolge in ASCII kodiert, sind nur Werte bis 0x7f von Bedeutung. Ist weder eine Kodierung, noch die Attribute maxCharCount oder maxByteCount angegeben, wird für diesen Wert 0 wie bei einer C-Zeichenfolge angenommen.

maxCharCount

Die maximale Anzahl der Zeichen in dieser Zeichenfolge. Ist zusätzlich auch terminatedBy angegeben, begrenzt der kleiner der beiden Werte die Zeichenfolge. Die Attribute maxByteCount und maxCharCount schließen sich gegenseitig aus.

maxByteCount

Die maximale Länge der Zeichenfolge in Byte. Ist zusätzlich auch terminatedBy angegeben, begrenzt der kleiner der beiden Werte die Zeichenfolge. Die Attribute maxByteCount und maxCharCount schließen sich gegenseitig aus. Mit Kodierungen wie ASCII sind beide Attribute gleichwertig.

type

Die Kodierung dieser Zeichenfolge, folgende Kodierungen sind möglich:

  • ASCII

  • LATIN-1

  • UTF-8

  • UTF-16-LE oder UTF-16-BE. Wenn weder die Nachsilbe -LE oder -BE angegeben ist, wird die Byte-Reihenfolge -LE (Little Endian) angenommen.

  • UTF-32-LE oder UTF-32-BE. Wenn weder die Nachsilbe -LE oder -BE angegeben ist, wird die Byte-Reihenfolge -LE (Little Endian) angenommen.

Jedes Element kann außerdem ein Attribut name. Dieser Name wird dann in der Strukturansicht angezeigt.

Ein Beispiel einer Strukturdefinition sowohl in XML als auch in JavaScript

Anmerkung

Eine aktuellere aber unvollständige Anleitung zum Schreiben von Strukturdefinitionen finden Sie im KDE UserBase Wiki.

Gemeinsame Schritte für beide Ansätze

Die Metadatendatei hat diesen Inhalt:

        [Desktop Entry]
        Icon=arrow-up❶
        Type=Service
        ServiceTypes=KPluginInfo

        Name=Simple test structure
        Comment=A very simple test structure containing only two items

        X-KDE-PluginInfo-Author=Alex Richardson
        X-KDE-PluginInfo-Email=foo.bar@email.org
        X-KDE-PluginInfo-Name=simplestruct
        X-KDE-PluginInfo-Version=1.0
        X-KDE-PluginInfo-Website=https://www.plugin.org/
        X-KDE-PluginInfo-Category=structure
        X-KDE-PluginInfo-License=LGPL
        X-KDE-PluginInfo-EnabledByDefault=false
        

Das in Okteta benutzte Symbol für die Anzeige dieser Struktur kann durch Ausführung des Befehls kdialog --geticon. Alternativ kann der Pfad zu einem Symbol eingetragen werden.

Die Bedeutung der Felder erschließt sich leicht aus Ihrem Namen, ausgenommen für das Feld X-KDE-PluginInfo-Name. Der Wert dieses Felds muss mit dem Namen des Ordners, in dem diese Datei enthalten ist, und auch dem Namen der.desktop-Datei übereinstimmen. Bei XML-Strukturdefinitionen muss der Wert dieses Feldes außerdem den gleichen Namen wie die .osd-Datei haben.

In diesem Beispiel befindet sich die Datei simplestruct.desktop im Ordner simplestruct. Bei XML-Strukturdefinitionen enthält der Ordner auch noch eine Datei namens simplestruct.osd. Wird JavaScript verwendet, gibt es stattdessen die Datei main.js.

Eine einfache XML-Strukturdefinition

Zuerst wird die Definition einer einfachen Teststruktur erstellt, die nur ganzzahlige Datentypen wie ein „char“, einen vorzeichenbehafteten 32-bit Integerwert und ein Bitfeld enthält. In C/C++ wird das so geschrieben:

          struct simple {
            char aChar;
            int anInt;
            bool bitFlag :1;
            unsigned padding :7;
          };
          

Als erstes wird die .osd-Datei mit dem im vorherigen Abschnitt definierten Dateiformat geschrieben. Diese erhält den Namen simplestruct.osd:


          <?xml version="1.0" encoding="UTF-8"?>
          <data>
            <struct name="simple">
              <primitive name="aChar" type="Char"/>
              <primitive name="anInt" type="Int32"/>
              <bitfield name="bitFlag" type="bool" width="1"/>
              <bitfield name="padding" type="unsigned" width="7"/>
            </struct>
          </data>
          

Dies ist ähnlich wie die C/C++ Definition.

Erstellen Sie nun einen Ordner simplestruct im Strukturinstallationsordner wie im Abschnitt manuelle Installation beschrieben. Kopieren Sie diese beiden Dateien in diesen Ordner. Starten Sie Okteta neu und benutzen Sie die neue Struktur.

Die einfache Struktur in JavaScript

Um die oben gezeigte Struktur in JavaScript zu schreiben, erstellen Sie eine Daten namens main.js anstelle der Datei simplestruct.osd und ändern Sie X-KDE-PluginInfo-Category=structure zu X-KDE-PluginInfo-Category=structure/js. Die Datei sollten folgenden Inhalt haben:

        function init() {
          var structure = struct({
            aChar : char(),
            anInt : int32(),
            bitFlag : bitfield("bool", 1),
            padding : bitfield("unsigned", 7),
          })
          return structure;
        }
        

Die in Okteta angezeigte Struktur ist immer der Rückgabewert der Funktion init.

Die folgenden Funktionen können benutzt werden, um einen primitiven Typ zu erzeugen:

  • char()

  • int8(), int16(), int32() oder int64()

  • uint8(), uint16(), uint32() oder uint64()

  • bool8(), bool16(), bool32() oder bool64()

  • float()

  • double()

Die Funktion „bitfield“ benötigt zwei Parameter, als erstes einen String wie bool, signed oder unsigned. Der zweite Parameter ist ein Integer-Wert, der die Breite in Bits angibt.

Komplexere Strukturen

Als nächstes wird eine komplexere Struktur definiert. Sie wird "complex" genannt und in der Datei complex.osd gespeichert. Diese Struktur enthält zwei Felder, eines mit fester Länge und ein anderes, dessen Länge erst zur Laufzeit bestimmt wird, außerdem noch eine verschachtelte Struktur und einen Verbund.


          <?xml version="1.0" encoding="UTF-8"?>
          <data>
            <struct name="complex">
              <primitive name="size" type="UInt8" />
              <union name="aUnion">
                <array name="fourBytes" length="4">
                  <primitive type="Int8" />
                </array>
              </union>
              <struct name="nested">
                <array name="string" length="size"> <!-- references the field size above -->
                  <primitive type="Char" />
                </array>
              </struct>
            </struct>
          </data>
          

Dies entspricht folgendem Pseudocode in C/C++

struct complex {
            uint8_t size;
            union aUnion {
              int8_t fourBytes[4];
            };
            struct nested {
              char string[size] //not valid C++, references value of the uint8 size
            };
          };
          

Anmerkung

Referenzfelder für dynamische Felder müssen vor dem Feld definiert werden.

Als nächstes wird die Datei complex.desktop wie im vorher gezeigten Beispiel erstellt. Benutzen Sie für X-KDE-PluginInfo-Name den richtigen Namen und installieren Sie beide Dateien.

Weitere Informationen

Einige Beispiele von Strukturdefinitionen finden Sie im Git-Archiv. Dort ist zum Beispiel der Vorspann für PNG- und ELF-Dateien enthalten. Ein XML-Schema, das die Struktur von .osd-Dateien beschreibt, finden Sie hier. Brauchen Sie weitere Informationen, kontaktieren Sie .