Descrittore del formato di un file
© 2007-2008 Gambino Mario

Versione di questo documento
4.0.0
- Specifiche 4.0.0
3.0.0
- Specifiche 3.0.0
- Definizione di report.
2.0.0
- Specifiche 2.0.0
1.0.0
- Specifiche 1.0.0

Versione delle specifiche descritte
4.0.0
- Aggiunto l'attributo "autore" al nodo <documento>.
- Aggiunto l'attributo "verso" al nodo <ripeti>.
- Aggiunto l'attributo variabile "RIPETI[nome].contatore" che dà accesso al contatore del nodo <ripeti>.
- Aggiunto il nodo <report>.
3.0.0
- Aggiunto l'attributo "mentre" al nodo <ripeti>.
- Sostituito l'attributo "id" con l'attributo "nome" nel nodo <campo>.
- Aggiunto l'attributo "buffer" al nodo <campo>.
- Aggiunto il nodo <buffer>.
- Aggiunto l'attributo "peso" al nodo <documento>.
- Gestione dei caratteri non visualizzabili nei campi di tipo testo.
- Dimensioni di un campo con marcatore.
- Tabelle con righe di tipo testo.
- Gestione dell'attributo variabile "CAMPO[nome].dimensione" che dà accesso all'attributo "dimensione" di un campo.
- Aggiunto il nodo <variabile> che definisce un valore utilizzabile come attributo variabile.
- Aggiunto l'attributo variabile "VARIABILE[nome].valore" che dà accesso al valore di un nodo <variabile>.
- Aggiunti i nodi <somma>, <sottrai>, <dividi> e <moltiplica> che eseguono le operazioni aritmetiche e restituiscono il risultato in un attributo variabile "VARIABILE[nome].valore".
2.0.0
- Calcolo e verifica del checksum: aggiunti nuovi attributi al nodo <struttura> e il nuovo tipo "controllo" al nodo <campo>
1.0.0
- Prima stesura

Prossime implementazioni
- Vuoto per il momento.



Indice

1. Introduzione
1.1 Definizione di report
2. Nodi
2.1 Nodo <documento>
2.2 Nodo <campo>
2.3 Nodo <struttura>
2.3.1 Algoritmi di controllo
2.4 Nodo <se>
2.5 Nodo <altrimenti>
2.6 Nodo <ripeti>
2.7 Nodo <messaggio>
2.8 Nodo <tabella>
2.9 Nodo <riga>
2.10 Nodo <variabile>
2.11 Nodi aritmetici
2.12 Nodo <buffer>
2.13 Nodo <stampa>
3 Attributi variabili
4 Caratteri non visualizzabili
5 Dimensioni con marcatore
6 Dimensioni raggruppate


1. Introduzione

Questo documento illustra le specifiche tecniche che definiscono un particolare documento XML che chiameremo "Descrittore del formato di un file" o semplicemente "Descrittore".

Il descrittore permette di attribuire uno specifico significato logico ai byte letti da un qualsiasi file, sia esso binario, testuale o misto. Un software può utilizzare un descrittore per generare un report.


1.1 Definizione di report

Un report è un file di testo contenente le descrizioni logiche e i valori dei campi indicati nel descrittore. Sia le descrizioni che i valori devono essere in chiaro cioè sotto forma di testo visualizzabile da un qualsiasi editor di testi (NotePad, JEdit...).

Torna all'indice


2. Nodi

Segue l'elenco dei nodi e la loro sintassi riportata attraverso degli esempi.

2.1 Nodo <documento>

<documento ver="4.0.0" desc="File MioFormato Versione 5.0.0" peso="alto-basso" autore="Mario">

E' il primo nodo di ogni descrittore e tutti gli altri devono essere suoi figli.

ver="4.0.0"
Identifica le regole descritte in questo documento, la modifica di uno o più nodi o di una regola si riflette in un valore di versione diverso. Non può essere vuoto.

desc="File MioFormato Versione 5.0.0"
E' una descrizione del tipo di file individuato dal Descrittore. Non può essere vuoto.

peso="alto-basso"
E' un parametro facoltativo che indica come vanno valutati i byte dei campi numerici con dimensioni minori o uguali a 4. Può assumere solo i valori seguenti: autore="Mario"
Indica l'autore del Descrittore. Lo stesso attributo può essere usato nel report per indicare il software che lo ha generato. Facoltativo.

Torna all'indice


2.2 Nodo <campo>

<campo
      nome="baud"
      desc="Baud Rate di trasmissione"
      tipo="numero"
      dimensione="2"
      formato="decimale"
      predefinito="1200"
      minimo="1200"
      massimo="38400"
      segno="no"
      tabella="1"
      buffer=""
/>

E' il nodo fondamentale di un descrittore perché effettua la lettura dei byte attribuendo ad essi un significato logico e applica i controlli indicati nei suoi attributi.

nome="baud"
Individua in modo univoco un <campo>. Può essere vuoto a patto che in nessuna parte del documento sia presente una scrittura del tipo "CAMPO[nome].valore" in cui "nome" fa riferimento proprio a questo attributo (vedi "Attributi variabili" più avanti). Se presente deve essere univoco.
Qualsiasi testo può essere un nome valido, lo sono "baud rate", "12", "3 anni", l'importante è che al momento del suo utilizzo, nella scrittura CAMPO[nome], esso sia riportato allo stesso modo, con gli stessi spazi, le stesse lettere maiuscole e minuscole.

desc="Baud Rate di trasmissione"
Una descrizione obbligatoria che dà un significato logico ai byte letti. Non è necessario che sia univoca ma è chiaro che se più nodi <campo> hanno la stessa descrizione si otterranno risultati poco chiari.

tipo="numero"
Tipo dei byte letti. E' obbligatorio e può assumere solo i valori seguenti
dimensione="2"
Il numero di byte consecutivi da leggere. E' obbligatorio. Può assumere anche "attributi variabili" o "dimensioni raggruppate" o "dimensioni con marcatore" (descritti più avanti).

formato="decimale"
Permette di visualizzare i byte letti in uno dei formati di seguito indicati. E' facoltativo.
predefinito="0" minimo="1200" massimo="38400"
I parametri "predefinito", "minimo" e "massimo" sono facoltativi e servono affinchè un software possa segnalare che eventuali valori letti da un file sono in disaccordo con il formato previsto. Hanno significato solo se il <campo> è di tipo "numero" e la "dimensione" è minore o uguale a 4 o del tipo "n*CAMPO[nome].valore" con n minore o uguale a 4.

segno="no"
E' un parametro facoltativo che si riferisce solo ai campi di tipo "numero" ed indica se il valore letto va considerato con segno o senza, tale scelta può influire il controllo eventualmente effettuato da un software sui parametri "predefinito", "minimo" e "massimo".

tabella="1"
Permette di sostituire il valore del <campo> con quello associato in un nodo <tabella> descritto più avanti. Facoltativo.

buffer=""
Facoltativo. Se presente (il testo al suo interno è ininfluente) indica che il valore del campo non sarà letto direttamente dal file di input ma da un nodo <buffer> precedentemente definito che ha già letto i byte dal file.

Torna all'indice


2.3 Nodo <struttura>

<struttura desc="INTESTAZIONE" separatore="----------">
...
</struttura>

Permette di raggruppare in modo logico i nodi <campo> e tutti gli altri nodi descritti in seguito.

desc="INTESTAZIONE"
Una descrizione facoltativa che un software può scrivere nel report. Non è necessario che sia univoca ma è chiaro che se più nodi <struttura> hanno la stessa descrizione si otterranno risultati poco chiari.
 
separatore="----------"
Un testo facoltativo che un software può stampare per separare visivamente più strutture, tipicamente una riga sopra la descrizione.

2.3.1 Algoritmi di controllo

Dalla versione 2.0.0 delle specifiche è possibile gestire gli algoritmi di integrità dei dati. Per attivare un controllo, un nodo <struttura> deve avere i seguenti attributi facoltativi (che indico con esempi):

controllo-classe="somma"
Indica l'algoritmo di controllo da eseguire sui byte di tutti i campi definiti all'interno della struttura. Per il momento l'unico valore ammesso è "somma" che seleziona il "checksum a 16 bit con scarto del riporto."

controllo-nome="17"
Deve corrispondere all'attributo "nome" di un campo all'interno della struttura il quale deve essere pure di tipo "controllo". Questo campo è quello che contiene il valore già calcolato, un software può applicare l'algoritmo ai byte della struttura e verificare la corretta corrispondenza con questo valore.

controllo-tipo="globale"
Indica che il valore calcolato deve essere mantenuto fino alla fine del file di input e, quindi, anche dopo l'uscita dalla struttura.

Torna all'indice


2.4 Nodo <se>

Questo nodo permette di eseguire i nodi che contiene solo se un'espressione è valutata vera, altrimenti li salta. Può far uso di attributi variabili. Le espressioni gestite sono

"==" (uguaglianza): vera se il valore alla sua sinistra è uguale a quello (o uno tra quelli) alla sua destra;

"!=" (disuguaglianza):" vera se il valore alla sua sinistra è diverso da quello (o tutti quelli) alla sua destra;

Un esempio di uguaglianza è il seguente:

<se vero="CAMPO[0].valore==200">

vero="CAMPO[0].valore==200"
Condizione da verificare. I nodi contenuti vengono valutati solo se il valore del <campo> con attributo "nome" impostato a "0" ha valore uguale a 200.

E' possibile indicare un'elenco di valori, ad esempio:

<se vero="CAMPO[0].valore==200,202,203,204,205,206,207,208,0,1,3,4,5,7,8,2,6">

in tal caso i nodi contenuti vengono valutati solo se il valore del <campo> con attributo "nome" impostato a "0" ha valore uguale a 200 oppure 202 oppure uno degli altri indicati.

Un esempio di disuguaglianza è il seguente

<se vero="CAMPO[15].valore!=05.00.00">

vero="CAMPO[15].valore!=05.00.00"
Condizione da verificare. I nodi contenuti vengono valutati solo se il valore del <campo> con attributo "nome" impostato a "15" ha valore diverso da "05.00.00".

E' possibile indicare un elenco di valori, ad esempio:

<se vero="CAMPO[0].valore!=200,202,203,204,205,206,207,208,0,1,3,4,5,7,8,2,6">

in tal caso i nodi contenuti vengono valutati solo se il valore del <campo> con attributo "nome" impostato a "0" ha valore diverso da 200 e diverso da 202 e diverso da tutti gli altri indicati.

Se l'espressione non è verificata (uguaglianza o disuguaglianza che sia) i nodi all'interno del nodo <se> vengono saltati.

Nel caso di costanti di tipo testo (nell'es. precedente "05.00.00") è possibile usare anche i caratteri non visualizzabili (vedi più avanti).

Torna all'indice


2.5 Nodo <altrimenti>

Questo nodo deve seguire un nodo <se> e i suoi nodi figlio verranno valutati solo se nel precedente nodo <se> l'espressione non è stata verificata

<altrimenti>
...
</altrimenti>

Torna all'indice


2.6 Nodo <ripeti>

Questo nodo permette di ripetere la valutazione dei nodi che contiene per un numero di volte prefissato o in seguito alla valutazione di un attributo variabile. Una sua prima forma è la seguente:

<ripeti per="33" nome="anni" verso="incrementa">
...
</ripeti>


per="33"
Numero di volte (obbligatorio) di valutazione dei nodi. Nell'esempio i nodi contenuti saranno valutati per 33 volte. La ripetizione può far uso anche di attributi variabili come nell'esempio seguente:

<ripeti per="CAMPO[num volte].valore">
...
</ripeti>


nome="anni"
Individua in modo univoco un nodo <ripeti>. Può essere vuoto a patto che in nessuna parte del documento sia presente una scrittura del tipo "RIPETI[nome].contatore" in cui "nome" fa riferimento proprio a questo attributo (vedi "Attributi variabili" più avanti). Se presente deve essere univoco.
Qualsiasi testo può essere un nome valido, lo sono "baud rate", "12", "3 anni", l'importante è che al momento del suo utilizzo, nella scrittura RIPETI[nome], esso sia riportato allo stesso modo, con gli stessi spazi, le stesse lettere maiuscole e minuscole.

verso="incrementa"
Indica come il nodo <ripeti> deve gestire il conteggio delle ripetizioni. E' facoltativo ma se presente può assumere solo i valori seguenti

La seconda forma permette di ripetere secondo il valore di un'espressione:

<ripeti mentre="CAMPO[num volte].valore!=0" nome="anni" verso="incrementa">
...
</ripeti>


mentre="CAMPO[num volte].valore!=0"
E' l'espressione (obbligatoria) da valutare, se vera, avviene la ripetizione. In questo caso è spontaneo l'uso di attributi variabili. Le possibili espressioni sono quelle già viste per il nodo <se>

Gli attributi "nome" e "verso" hanno il significato già descritto. E' possibile conoscere il valore assunto dal contatore utilizzando l'attributo variabile del tipo "RIPETI[nome].contatore" (vedi "Attributi variabili" più avanti).

Gli attributi "per" e "mentre" sono obbligatori nelle due distinte forme del nodo e non possono essere presenti entrambi.

Torna all'indice


2.7 Nodo <messaggio>

<messaggio msg="ATTENZIONE!!!" />

Permette di dare un avviso all'utilizzatore. Non altera in nessun modo il flusso di lettura del file di input. Tipicamente il software visualizzerà il messaggio indicato facendo uso della propria interfaccia utente.

Torna all'indice


2.8 Nodo <tabella>

Una tabella permette di associare delle descrizioni ai valori letti mediante un <campo>. L'associazione può avvenire con l'intero valore letto o con un singolo bit del valore. Esistono tre tipi di nodi <tabella> come indicato negli esempi seguenti

<tabella id="0" tipo="numero">
...
</tabella>

<tabella id="0" tipo="testo">
...
</tabella>

<tabella id="0" tipo="bit">
...
</tabella>

id="0"
Individua in modo univoco una <tabella>. E' obbligatorio e deve essere numerico e univoco. Mediante il suo valore è possibile associare la tabella ad un <campo> riportandolo nella sua proprietà "tabella". Una tabella può essere definita in un qualsiasi punto del descrittore ma prima che un <campo> vi faccia riferimento.

tipo="numero"
Tipo della tabella. E' obbligatorio e può assumere solo i valori seguenti (vedere anche il nodo <riga>)
Torna all'indice


2.9 Nodo <riga>

Definisce le associazioni tra un numero, un testo o un bit ed una descrizione. Deve essere definito all'interno di un nodo <tebella>.

<riga valore="33" desc="gli anni del signore"/>

se il nodo <riga> si trova all'interno di un nodo <tabella> con attributo "tipo" uguale a "numero" e il valore del campo è "33" esso deve essere sostituito nel report dalla descrizione "gli anni del signore";

se invece si trova in una <tabella> con "tipo" uguale a "bit":

<riga valore="0" desc="assoluto"/>
<riga valore="1" desc="extraurbano"/>

se il bit "0" del valore del campo è settato a 1 esso deve essere sostituito dalla descrizione "assoluto". Se più bit risultano settati le descrizioni dovranno essere presenti nel report in modo da non ripetere la descrizione del campo, ad esempio:

Orario = assoluto | extraurbano

Se un bit non è previsto dalla tabella il suo valore non verrà indicato, nel caso dell'esempio precedente non sarà possibile sapere il valore dei bit "2" e "3" perché non hanno associata una <riga>.

Può essere utile inserire il nodo <riga> all'interno di un nodo <tabella> con attributo "tipo" uguale a "testo" nel caso in cui il valore del campo sia poco descrittivo:

<riga valore="[12" desc="font alto 12"/>

E' possibile usare anche caratteri non visualizzabili così da renderli leggibili nel report (vedi "Caratteri non visualizzabili" più avanti):

<riga valore="\0d\0a" desc="Ritorno a capo"/>

Se il valore assunto da un <campo> non è previsto dalla tabella esso verrà visualizzato secondo gli attributi "tipo" e "formato" del <campo>.

Torna all'indice


2.10 Nodo <variabile>

Mediante questo nodo è possibile utilizzare il risultato di alcune operazioni aritmetiche (vedi "Nodi aritmetici" più avanti) oppure definire delle costanti numeriche a cui far riferimento in altri punti del descrittore oppure permettere all'utilizzatore di un software di introdurre un valore numerico facendo uso dell'intefaccia del software.

<variabile nome="eta" desc="Gli anni del signore" valore="33"/>

nome="eta"
Individua in modo univoco una <variabile> quindi è obbligatorio. Permette di far riferimento a questo nodo in scritture del tipo "VARIABILE[nome].valore" (vedi "Attributi variabili" più avanti).

desc="Gli anni del signore"
Una descrizione obbligatoria. Non è necessario che sia univoca ma è chiaro che se più nodi <variabile> hanno la stessa descrizione si otterranno risultati poco chiari.

valore="33"
Il valore iniziale della <variabile>. Non è obbligatorio. Se presente deve essere numerico o un attributo variabile numerico, se assente assume il valore zero.

Se l'attributo "valore" è il testo "?" (punto interrogativo), un software può dare all'utente la possibilità di inserire un valore numerico facendo uso della propria interfaccia. In questo modo si può parametrizzare un descrittore come nell'esempio:

<variabile nome="cifre" desc="Numero di cifre" valore="?"/>

Torna all'indice


2.11 Nodi aritmetici

I nodi aritmetici permettono di eseguire le operazioni aritmetiche di base (somma, sottrazione, divisione e moltiplicazione) su operandi che possono essere costanti numeriche o attributi variabili (vedi "Attributi variabili" più avanti) e ripongono il risultato in un attributo variabile necessariamente del tipo VARIABILE[nome].valore precedentemente definito.

I nodi disponibili sono (descritti con degli esempi):

<sottrai op1="3" op2="CAMPO[0].dimensione" ris="VARIABILE[1].valore" />

sottrae al numero 3 la dimensione del <campo> con "nome" uguale "0", il risultato va a sostituire il valore della <variabile> con "nome" uguale a "1".

<somma op1="34" op2="30" ris="VARIABILE[2].valore" />

somma le costanti numeriche 34 e 30 e il risultato va a sostituire il valore della <variabile> con "nome" uguale a "2".

<dividi op1="VARIABILE[1].valore" op2="VARIABILE[2].valore" ris="VARIABILE[1].valore" />

divide il valore della <variabile> con "nome" uguale a "1" con il valore della <variabile> con "nome" uguale a "2" e il risultato va a sostituire il valore della <variabile> con "nome" uguale a "1" (che è anche il primo operando).

<moltiplica op1="VARIABILE[1].valore" op2="CAMPO[2].valore" ris=VARIABILE[3].valore" />

moltiplica il valore della <variabile> con "nome" uguale a "1" con il valore letto dal file del <campo> con "nome" uguale a "2", il risultato va a sostituire il valore della <variabile> con "nome" uguale a "3".

In generale "op1" e "op2" individuano i 2 operandi mentre "ris" indica il nodo <variabile> che conterrà il risultato e che sarà utilizzabile in qualsiasi altro punto in cui si può far uso di attributi variabili.

Torna all'indice


2.12 Nodo <buffer>

Come il nodo <campo>, anche questo legge i byte dal file di input ma li salva in un'area di memoria condivisa da tutto il descrittore che chiamiamo buffer. Ha lo scopo di rendere diponibili i byte del buffer ai nodi <campo> che li leggeranno al posto di accedere al file di input. Più chiamate a questo nodo sovrascrivono sempre la stessa area di memoria. Un nodo <campo> accede ai byte del buffer invece che a quelli del file di input se presenta l'attributo "buffer".

<buffer dimensione="100"/>

dimensione="100"
Il numero di byte da leggere dal file di input. Può assumere anche attributi variabili. Questa operazione porta avanti il punto d'accesso al file quindi un successivo <campo> che legge dal file accede al byte 101. Se invece presenta l'attributo "buffer" legge proprio da questi 100 byte e porta avanti il punto d'accesso al buffer.

Si osservi l'esempio seguente:

<buffer dimensione="100"/>
<campo
      desc="Baud Rate di trasmissione"
      tipo="numero"
      dimensione="2"
      buffer=""
/>
<campo
      desc="Byte dati"
      tipo="numero"
      dimensione="1"
      buffer=""
/>

il primo campo legge il primo e il secondo byte dal buffer, il secondo campo legge il terzo byte dal byffer.

Torna all'indice


2.13 Nodo <stampa>

<stampa testo="commento" nuovalinea="si"/>

Questo nodo permette di stampare (scrivere) un qualsiasi testo nel file di report, indipendentemente dai dati letti dal file di input.

testo="commento"
E' il testo obbligatorio che si vuole scrivere nel report. Può contenere anche gli attributi variabili.

nuovalinea="si"
Indica se al termine del testo il software che genera il report deve inserire un "ritorno a capo" oppure no. E' facoltativo ma se presente può assumere solo i valori seguenti:

Torna all'indice


3 Attributi variabili

Gli attributi variabili vengono usati per rendere flessibile la lettura di un file. Il formato di un file, ad esempio, può avere campi con dimensione variabile e cioè che dipendono dal valore letto da un altro campo, intere strutture possono essere lette o meno secondo il valore assunto dai campi già letti.

Un attributo variabile viene indicato con una delle seguenti scritture:

Nel caso di un nodo <campo>, se "nome" ne individua uno di tipo testo allora la scrittura "CAMPO[nome].valore" ha sempre senso mentre se individua un <campo> di tipo numerico ha senso solo se la sua "dimensione" è minore o uguale a 4.

Gli attributi variabili possono essere usati con i nodi <se> (per rendere variabile l'attributo "vero"), <ripeti> (per rendere variabile l'attributo "per" o "mentre"), <campo> (per rendere variabile l'attributo "dimensione"), uno dei nodi aritmetici quali <sottrai>, <somma>, <dividi> e <moltiplica> (per rendere variabili gli attributi "op1", "op2" e "ris").

Torna all'indice


4 Caratteri non visualizzabili

Per definizione, un report deve contenere sono testi visualizzabili con un qualsiasi editor di testi. Il fatto che un campo sia di tipo "testo" non garantisce questa condizione perché potrebbe contenere dei caratteri non visualizzabili rappresentanti formattazioni particolari o comunque controlli specifici insieme al testo.

Un byte non è visualizzabile se ha un valore ascii esadecimale minore di 0x20 oppure maggiore di 0x7D.

Si definisce che tali byte (letti mediante un <campo> di tipo testo) devono essere inseriti nel report con la sequenza "\xx" con "xx" pari al valore ascii esadecimale. Ad esempio il byte 0x01, se letto da un campo di tipo testo, sarà inserito come "\01" (testo di 3 byte che rappresenta un solo byte letto dal file di input). Poichè il carattere "\" è utilizzato nella sequenza, se il testo stesso contiene uno "\" esso deve essere inserito nel report come "\\" (testo di 2 byte che rappresenta il singolo byte "\").


5 Dimensioni con marcatore

Le dimensioni con marcatore permettono di gestire quei campi che contengono dati di lunghezza variabile cioè non prefissata a priori ma individuata da una sequanza definita di byte che chiamiamo marcatore. Ad esempio un nodo <campo> può avere la dimensione

dimensione="#\0d\0a"

in cui il carattere # indica che devono essere letti i byte fino alla lettura del testo indicato. Sottolineo il fatto che si tratta di un testo quindi, come nell'esempio precedente, può contenere caratteri non visualizzabili, anzi, è necessario farne uso se il marcatore previsto dal file invece è numerico (necessariamente non visualizzabile).

ATTENZIONE che il marcatore fa parte del valore del campo, altrimenti nel report non si avrebbe traccia della sua presenza.

La scrittura che segue il carattere "#" può essere anche un attributo variabile.

Torna all'indice


6 Dimensioni raggruppate

Le dimensioni raggruppate permettono di gestire quei campi che contengono una lista di valori. Ad esempio un nodo <campo> può avere la dimensione

dimensione="2*4"

in cui si indica che devono essere letti 8 byte ma questi sono raggruppati logicamente come 4 gruppi da 2 byte. Una o entrambe le parti separate dal carattere "*" possono essere attributi variabili.