Passa al contenuto principale

2. Array tipizzati

2. Array tipizzati

Gli array tipizzati sono array omogenei di numeri, tutti codificati in una singola forma di rappresentazione binaria. La concatenazione di tali rappresentazioni è codificata come un’unica stringa di byte CBOR (tipo principale 2), racchiusa da un singolo tag che indica il tipo e la codifica di tutti i numeri rappresentati nella stringa di byte.

2.1 Tipi di numeri

Tre classi di numeri sono di interesse: interi senza segno (uint), interi con segno (complemento a due, sint) e numeri in virgola mobile IEEE 754 binari (che sono sempre con segno). Per ciascuna di queste classi, esistono più lunghezze di rappresentazione in uso:

             +-----------+--------+--------+-----------+
| Length ll | uint | sint | float |
+===========+========+========+===========+
| 0 | uint8 | sint8 | binary16 |
+-----------+--------+--------+-----------+
| 1 | uint16 | sint16 | binary32 |
+-----------+--------+--------+-----------+
| 2 | uint32 | sint32 | binary64 |
+-----------+--------+--------+-----------+
| 3 | uint64 | sint64 | binary128 |
+-----------+--------+--------+-----------+

Table 1: Length Values

Qui, sintN indica un intero con segno di esattamente N bit (ad esempio, sint16) e uintN indica un intero senza segno di esattamente N bit (ad esempio, uint32). Il nome binaryN indica la forma numerica omonima definita in IEEE 754 [IEEE754].

Poiché uno degli obiettivi di questi tag è poter trasferire direttamente gli ArrayBuffer sottostanti ai Typed Array senza ricodificarli, e poiché questi possono essere in big-endian (network byte order) o in little-endian, è necessario definire tag per entrambe le varianti.

In totale, ciò porta a 24 varianti. Nel tag, è necessario esprimere la scelta tra intero e virgola mobile, il segno (per gli interi), l’endianness e uno dei quattro valori di lunghezza.

Per semplificare l’implementazione, viene allocato un intervallo di tag che consente di recuperare tutte queste informazioni dai bit del tag: valori di tag da 64 a 87.

Il valore è suddiviso in 5 campi di bit: 0b010, f, s, e e ll come dettagliato nella Tabella 2.

  +-------+-------------------------------------------------------+
| Field | Use |
+=======+=======================================================+
| 0b010 | the constant bits 0, 1, 0 |
+-------+-------------------------------------------------------+
| f | 0 for integer, 1 for float |
+-------+-------------------------------------------------------+
| s | 0 for float or unsigned integer, 1 for signed integer |
+-------+-------------------------------------------------------+
| e | 0 for big endian, 1 for little endian |
+-------+-------------------------------------------------------+
| ll | A number for the length (Table 1). |
+-------+-------------------------------------------------------+

Table 2: Bit Fields in the Low 8 Bits of the Tag

Il numero di byte in ciascun elemento dell’array può quindi essere calcolato come "2**(f + ll)" (oppure "1 << (f + ll)" in un tipico linguaggio di programmazione). (Si noti che f e ll sono, rispettivamente, i due bit meno significativi di ciascun nibble da 4 bit nel byte.)

Nella rappresentazione CBOR, il numero totale di elementi dell’array non è espresso esplicitamente ma è implicato dalla lunghezza della stringa di byte e dalla lunghezza di ciascuna rappresentazione. Può essere calcolato dalla lunghezza, in byte, della stringa di byte che comprende la rappresentazione dell’array invertendo la formula precedente: "bytelength >> (f + ll)".

Per i valori uint8/sint8, l’endianness è ridondante. Viene usato e assegnato solo il tag per la variante big-endian. Il tag che significherebbe la variante little-endian di sint8 MUST NOT essere usato; il suo numero di tag è marcato come riservato. Come caso speciale, il tag che significherebbe la variante little-endian di uint8 è invece assegnato a significare che i numeri nell’array usano una conversione con saturazione (clamped) da interi, come descritto più in dettaglio nella Sezione 7.1.11 (http://www.ecma-international.org/ecma-262/6.0/#sec-touint8clamp) della specifica JavaScript ES10 ("ToUint8Clamp") [ECMA-ES10]; l’assunzione è che una rappresentazione interna del programma di questo array dopo la decodifica venga marcata in questo modo per un’ulteriore elaborazione che consenta il “roundtripping” degli array tipizzati JavaScript attraverso CBOR.

I numeri in virgola mobile binari IEEE 754 sono sempre con segno. Pertanto, per le varianti float ("f" == 1), non è necessario distinguere tra varianti con segno e senza segno; il bit "s" è sempre zero. I numeri di tag in cui "s" sarebbe uno (che avrebbero valori di tag da 88 a 95) rimangono disponibili per l’uso da parte di altre specifiche.