Eina d'estructures

General

L'eina Estructures permet analitzar i editar matrius de bytes basades en definicions d'estructura que pot crear l'usuari, i que es poden construir a partir de matrius, unions, tipus primitius i valors enumerats.

Té un diàleg de configuració propi, al qual es pot arribar utilitzant el botó Arranjament. Hi ha diverses opcions que es poden configurar, com l'estil (decimal, hexadecimal o binari) en el qual es mostren els valors. A més, és possible triar quines definicions d'estructura es carreguen i quines estructures es mostren en la vista.

Les estructures es defineixen en fitxers de definició d'estructura de l'Okteta (basats en XML, amb l'extensió de fitxer .osd). A més, un fitxer .desktop conté metadades sobre aquest fitxer de descripció d'estructura, com ara autor, pàgina d'inici i llicència.

Actualment no hi ha suport integrat per a la creació o edició de definicions d'estructura, per tant, això ha de fer-se manualment com es descriu en les seccions següents.

Instal·lació de les definicions d'estructura

Instal·lació utilitzant el KNewStuff

La manera més fàcil d'instal·lar definicions noves d'estructura és utilitzant el suport integrat del KNewStuff a l'Okteta. Per a instal·lar una estructura existent obriu el diàleg de configuració de l'eina Estructura. Allà seleccioneu la pestanya Gestió d'estructures i premeu el botó Obtén estructures noves.... El diàleg que es mostra ara us permet instal·lar i desinstal·lar estructures.

Instal·lació manual de les definicions d'estructura

L'eina Estructura cerca descripcions d'estructura en el subdirectori okteta/structures/ del directori de l'usuari per a les dades del programa (que es troba executant qtpaths --paths GenericDataLocation). És possible que hàgiu de crear aquest directori si encara no hi ha cap definició d'estructura instal·lada.

Hi ha dos fitxers per a cada definició d'estructura: un fitxer per a la definició real i un fitxer .desktop per a les metadades (autor, versió, etc.).

En aquest directori hi ha un subdirectori per a cada definició d'estructura, que conté tant el fitxer .desktop com el fitxer .osd o main.js d'aquesta definició.

Per exemple, amb el directori de dades del programa qtpaths --paths GenericDataLocation i una definició d'estructura anomenada ExampleStructure, hi ha el directori okteta/structures/ExampleStructure que conté un fitxer ExampleStructure.desktop i un fitxer ExampleStructure.osd.

Ús de les estructures instal·lades recentment

Després d'instal·lar una definició nova d'estructura haureu de reiniciar l'Okteta abans de poder-la utilitzar. Un cop s'ha iniciat l'Okteta, obriu el diàleg de configuració de l'eina Estructura. Allà seleccioneu la pestanya Gestió d'estructures i assegureu-vos que la definició de l'estructura corresponent està marcada. Després canvieu a la pestanya Estructures i assegureu-vos que l'element desitjat està llistat a la dreta.

Compartint les definicions d'estructura

Per a les estructures normals és possible que no necessiteu crear una definició vosaltres mateixos, però en el seu lloc podeu reutilitzar una definició ja existent des de llocs com store.kde.org.

També és possible que vulgueu compartir una definició vós mateix. Per a fer-ho, creeu un arxiu de fitxer (p. ex. un arxiu tar comprimit amb zip, .tar.gz) que contingui només el subdirectori amb el fitxer .desktop i el fitxer de definició d'estructura. Mirant l'exemple de l'última secció aquest seria el directori ExampleStructure amb tot el seu contingut. Utilitzar aquest format per a compartir les definicions d'estructures permet instal·lar-les dins de l'Okteta i no requereix cap instal·lació manual.

Creació de definicions d'estructura

Nota

Una guia més actualitzada, però no completada per a l'escriptura de les definicions d'estructura es pot trobar en el Wiki UserBase de KDE.

Hi ha dues maneres diferents de crear definicions d'estructures. El primer és escriure la definició en XML, l'altre és utilitzant JavaScript. L'enfocament JavaScript permet crear estructures més complexes amb característiques com ara validar l'estructura. L'ús de l'XML dona menys característiques, però si tot el que necessiteu és una estructura estàtica, aquest pot ser l'enfocament més fàcil. Si es necessita una estructura dinàmica, és a dir, on les longituds de la matriu depenen d'altres valors de l'estructura o la disposició de l'estructura és diferent quan algun valor membre canvia, llavors haureu d'escriure la definició de l'estructura en JavaScript. Hi ha una excepció a aquesta regla: si teniu una matriu on se suposa que la longitud és exactament el mateix que un altre valor en l'estructura, llavors podeu utilitzar XML. Però si és una mica com length -1 ha de ser JavaScript.

Format del fitxer XML de definició d'estructura

Nota

Una guia més actualitzada, però no completada per a l'escriptura de les definicions d'estructura es pot trobar en el Wiki UserBase de KDE.

El fitxer XML .osd té un element arrel: <data> sense atributs. Dins d'aquest element ha d'haver-hi un dels elements següents:

<primitive>

Es pot crear un tipus de dades «primitive» com, p. ex., int o float. Aquest element no accepta subelements i pot tenir els atributs següents:

type

El tipus d'aquest tipus primitiu. Ha de ser un dels següents:

  • char per a un caràcter ASCII de 8 bits

  • int8, int16, int32, int64 per a un enter amb signe d'aquesta mida

  • uint8, uint16, uint32, uint64 per a un enter sense signe d'aquesta mida

  • bool8, bool16, bool32, bool64 per a un booleà sense signe (0 = fals, qualsevol altre valor = cert) d'aquesta mida

  • float per un nombre de coma flotant IEEE754 de 32 bits

  • double per un nombre de coma flotant IEEE754 de 64 bits

<bitfield>

Per a crear un camp de bits. Aquest element no accepta subelements i pot tenir els atributs següents:

width

El nombre de bits que utilitza aquest camp de bits. Cal que sigui entre 1 i 64.

type

El tipus d'aquest camp de bits. Ha de ser un dels següents:

  • unsigned per a un camp de bits on el valor s'interpretarà com un valor sense signe (interval de valors de 0 a 2width - 1)

  • signed per a un camp de bits on el valor s'interpretarà com un valor amb signe (interval de valors des de -2width - 1 a 2width - 1 - 1)

  • bool per a un camp de bits on el valor s'interpretarà com un valor booleà

Nota

Recordeu sempre afegir un farciment després d'un <bitfield>, ja que en cas contrari l'element següent (excepte les cadenes i matrius, que afegeixen automàticament el farciment) començarà enmig d'un byte. Òbviament, no és necessari fer farciments si voleu aquest comportament.

<enum>

Per a crear un tipus primitiu, però on els valors es mostren com a membres d'una enumeració si és possible. Aquest element no accepta subelements (tot i que necessitareu una etiqueta <enumDef> al fitxer per a fer-hi referència). Té els atributs següents:

enum

L'enumeració subjacent per a aquest valor. Ha de coincidir amb l'atribut name d'una de les etiquetes <enumDef> en aquest fitxer.

type

El tipus d'aquesta enumeració. Vegeu l'atribut tipus de <primitive>. La diferència només és que Double i Float no tenen sentit.

<flags>

Això és el mateix que <enum> amb l'única diferència que els valors es representen com a bitwise-or de tots els valors de l'enumeració.

<struct>

Per a crear una estructura. Tots els altres elements (incloent-hi <struct>) poden ser un fill d'això i després formar part de l'estructura resultant

<union>

Per a crear una unió. Bàsicament el mateix que <struct> excepte el fet que tots els elements fills començaran des del mateix desplaçament. Útil per a interpretar la mateixa seqüència de bytes de diverses maneres.

<array>

Per a crear una matriu. Aquest element accepta exactament un fill (el tipus subjacent de la matriu), que pot ser qualsevol dels elements, fins i tot la mateixa <array>. També té els atributs següents:

length

El nombre d'elements d'aquesta matriu com a nombre decimal. També pot ser una cadena que coincideixi amb l'atribut «name» d'un element <primitive>, <enum> o <flags> definits prèviament. Llavors la longitud serà el valor d'aquest element. Actualment es limita a 10000, ja que les matrius més grans utilitzarien massa memòria i alentirien massa l'eina.

<string>

Per a crear una cadena en diverses codificacions. Per defecte obtindreu una cadena a l'estil C finalitzada amb NULL. No obstant això, es poden crear tipus de cadena diferents amb els atributs següents:

terminatedBy

Aquest atribut determina amb quin punt de codi Unicode finalitza la cadena. Ha de ser un nombre hexadecimal (opcionalment començant per 0x). Quan la codificació és ASCII, només són significatius els valors fins a 0x7f. Si no s'ha establert ni aquest ni maxCharCount ni maxByteCount, s'assumeix que s'estableix a 0 (cadena a l'estil C)

maxCharCount

El nombre màxim de caràcters que pot tenir aquesta cadena. Si també s'ha establert terminatedBy, llavors qualsevol cosa que arribi primer finalitza la cadena. Això és mútuament excloent amb maxByteCount

maxByteCount

El nombre màxim de bytes que aquesta cadena pot tenir de longitud. Si també s'ha establert terminatedBy, llavors qualsevol cosa que arribi primer finalitza la cadena. Això és mútuament excloent amb maxCharCount. Amb codificacions com ASCII això és el mateix que maxCharCount.

type

La codificació d'aquesta cadena. Pot ser una de les següents:

  • ASCII

  • LATIN-1

  • UTF-8

  • UTF-16-LE o UTF-16-BE. Si no es donen els sufixes -LE ni -BE, s'assumeix «little endian».

  • UTF-32-LE o UTF-32-BE. Si no es donen els sufixes -LE ni -BE, s'assumeix «little endian».

Tots els elements també accepten un atribut name que és visible a la vista d'estructures.

Un exemple de definició d'estructura tant en XML com en JavaScript

Nota

Una guia més actualitzada, però no completada per a l'escriptura de les definicions d'estructura es pot trobar en el Wiki UserBase de KDE.

El pas comú compartit per ambdós enfocaments

El nostre fitxer de metadades hauria de ser així:

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

        Name=Estructura simple de prova
        Comment=Una estructura de prova senzilla que conté dos elements

        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
        

La icona mostrada a l'Okteta per a aquesta estructura pot ser qualsevol cosa trobada mitjançant l'execució de kdialog --geticon o un camí a una icona

Aquests camps haurien de ser força autoexplicatius, excepte X-KDE-PluginInfo-Name. El valor d'aquest camp ha de coincidir amb el nom del directori que conté el fitxer així com el nom del fitxer .desktop. En crear les definicions d'estructura XML el nom del fitxer .osd també ha de coincidir amb el nom.

En aquest exemple tindríem un directori anomenat simpletruct que conté el fitxer simpletruct.desktop. En definir estructures en XML el directori també conté un fitxer anomenat simpletruct.osd. Utilitzant JavaScript en el seu lloc tindríem un fitxer anomenat main.js.

Una definició d'estructura XML senzilla

Per a començar creem una definició per a una estructura de prova molt senzilla que conté només tipus de dades integrals (un caràcter, un enter amb signe de 32 bits i un camp de bits). Això s'expressa en C/C++ com:

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

El primer pas és escriure el fitxer .osd d'acord amb el format de fitxer definit a la secció anterior. Invocarem simpletruct.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>
          

que és força similar a la definició en C/C++.

Ara creeu un directori simpletruct dins del directori d'instal·lació de l'estructura (vegeu manualment les definicions d'estructura) i copieu els dos fitxers a aquest directori. Ara podeu reiniciar l'Okteta i utilitzar l'estructura nova.

L'estructura senzilla en JavaScript

Per a implementar l'estructura anterior en JavaScript, creeu un fitxer anomenat main.js en lloc de simpletruct.osd i canvieu X-KDE-PluginInfo-Category=structure a X-KDE-PluginInfo-Category=structure/js. El contingut d'aquest fitxer hauria de ser:

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

L'estructura mostrada per l'Okteta és sempre el valor de retorn de la funció init.

Les funcions següents es poden anomenar per a crear un tipus primitiu:

  • char()

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

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

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

  • float()

  • double()

La funció camp de bits té dos paràmetres, el primer és una cadena que consta d'un bool, signed o unsigned. El segon paràmetre és un enter que estableix l'amplada en bits.

Estructures més complexes

A continuació creem una definició d'una estructura més complexa que anomenarem «complex» i desarem en un fitxer anomenat complex.osd. Aquesta estructura contindrà dues matrius (una amb longitud fixa i una altra on la longitud es determina en temps d'execució) així com una estructura imbricada i una unió.


          <?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"> <!-- fa referència a la mida del camp anterior -->
                  <primitive type="Char" />
                </array>
              </struct>
            </struct>
          </data>
          

Això correspondria al següent en pseudocodi C/C++

struct complex {
            uint8_t size;
            union aUnion {
              int8_t fourBytes[4];
            };
            struct nested {
              char string[size] //no és C++ vàlid, fa referència al valor de la mida d'«uint8»
            };
          };
          

Nota

Òbviament només podeu tenir camps de referència de matrius de longitud dinàmica abans de la matriu.

A continuació creem el fitxer complex.desktop com en l'exemple anterior (assegureu-vos que heu establert X-KDE-PluginInfo-Name correctament) i també feu el mateix per a instal·lar els dos fitxers.

Informació addicional

Es poden trobar algunes definicions d'estructura d'exemple al repositori Git. Això inclou per exemple la capçalera de fitxer per a fitxers PNG i la capçalera de fitxer ELF. Es pot trobar un esquema XML que descriu l'estructura del fitxer .osd aquí. Si es necessita més informació us podeu posar en contacte amb mi a