mozilla
Vos résultats de recherche

    Les tableaux typés en JavaScript

    Brouillon
    Cette page n'est pas terminée.

    Les applications web deviennent de plus en plus performantes et profitent de fonctionnalités comme la manipulation du son ou de la vidéo. Elles accèdent aux données brutes via des WebSockets, etc. On voit ici que manipuler des données binaires brutes devient intéressant. Auparavant, la méthode utilisée consistait à utiliser une chaîne de caractères pour représenter les données et d'utiliser la méthode charCodeAt() pour lire les différents octets.

    Cette méthode reste lente et risquée, notamment quond on souhaite (re)convertir les données binaires (en nombres flottants par exemple).

    Les tableaux typés JavaScript fournissent un mécanisme d'accès efficace pour les données brutes binaires.

    Documentation

    ArrayBuffer
    ArrayBuffer est un type de données qui est utilisé pour représenter une mémoire tampon de longueur fixe pour les données binaires. Il est impossible de manipuler directement le contenu d'un ArrayBuffer. Par contre, en créant un objet ArrayBufferView, on peut représenter la mémoire tampon en un format donné et utiliser cette vue pour lire/écrire du contenu.
    ArrayBufferView
    Le type ArrayBufferView décrit une vue sur les données d'un ArrayBuffer. On peut créer différentes vues pour la même mémoire tampon, chacune de ces vues pointant vers un indice différent de la même zone. Ainsi, on peut travailler avec différents types de données placés à différents endroits.
    DataView

    La vue DataView fournit une interface de bas niveau pour lire et écrire des données dans un ArrayBuffer.

    StringView Non présent dans le code natif
    Dans cet article, nous avons présenté une bibliothèque dont les buts sont :
    • de créer une interface semblable au C pour les chaînes de caractères (c'est à dire un tableau de codes de caractères, soit une vue ArrayBufferView en JavaScript) qui se base sur l'interface JavaScript ArrayBuffer,
    • de créer une bibliothèque facilement extensible que chacun peut améliorer en ajoutant des méthodes à l'objet StringView.prototype,
    • de créer un ensemble de méthodes pour les objets dont la structure est proche des chaînes de caractères (des stringViews) et qui fonctionnent sur hich work strictly on arrays of numbers rather than on creating new immutable JavaScript strings,
    • de fonctionner avec les différents encodages autres que l'UTF-16 par défaut pour DOMStrings,
    Getting ArrayBuffers or typed arrays from Base64-encoded strings
    Des fragments de code pour obtenir des ArrayBuffers ou des tableaux typés à partir de chaînes de caractères encodées en Base 64.
    FileReader.prototype.readAsArrayBuffer()
    La méthode FileReader.prototype.readAsArrayBuffer() permet de lire le contenu d'un objet Blob ou File.
    XMLHttpRequest.prototype.send()
    La méthode send() des instances XMLHttpRequest supporte désormais les tableaux typés et les en arguments.

    Voir tous...

    Communauté

    Outils

    Les mémoires tampons et les vues : l'architecture autour des tableaux typés

    Pour être le plus flexible et efficace possible, l'implémentation des tableaux typés est séparée en deux avec, d'un côté : la mémoire tampon (le buffer) et de l'autre : la vue. Un buffer (implémenté par ArrayBuffer) est un objet représentant un fragment de données : il n'a pas de format à proprement parler et ne fournit aucun outil pour accéder à son contenu. Pour accéder à la mémoire du buffer, on doit utiliser une vue. Une vue fournit un contexte (un type de données, un emplacement de départ ou offset, et un nombre d'éléments) permettant de transformer la données en un tableau typé. Les vues sont implémentées avec ArrayBufferView et ses sous-classes.

    Sous-classes de tableaux typés

    Les sous-classes suivantes fournissent des vues sur le buffer pour accéder à des données d'un certain type. Les classes utilisant plus d'un octet (ex : Int16Array) se base sur l'ordre des octets de la plate-forme. Si on souhaite disposer d'un contrôle sur cet ordre, on utilisera DataView.

    Type Taille Description Équivalent d'un type C
    Int8Array 1 Entier signé en complément à deux sur 8 bits signed char
    Uint8Array 1 Entier non signé sur 8 bits unsigned char
    Uint8ClampedArray 1 Entier non signé sur 8 bits unsigned char
    Int16Array 2 Entier signé en complément à deux sur 16 bits short
    Uint16Array 2 Entier non signé sur 16 bits unsigned short
    Int32Array 4 Entier signé en complément à deux sur 32 bits int
    Uint32Array 4 Entier non signé sur 32 bits unsigned int
    Float32Array 4 Nombre flottant sur 32 bits (selon la norme IEEE) float
    Float64Array 8 Nombre flottant sur 64 bits (selon la norme IEEE) double

    Classes génériques pour les tableaux typés

    Type Description
    DataView La vue DataView fournit une interface de bas niveau pour lire et écrire des données dans un ArrayBuffer.
    StringView Non natif La vue StringView fournit une interface analogue à une interface C pour les chaînes de caractères (une ArrayBufferView en JavaScript) basée sur l'interface JavaScript ArrayBuffer.

    Utiliser les vues sur les buffers

    On commence par créer un buffer sur 16 octets :

    var buffer = new ArrayBuffer(16);
    

    On dispose donc d'un morceau de mémoire dont les octets ont été pré-initialisés à 0. On peut, pour le moment, tester sa taille :

    if (buffer.byteLength == 16) {
      alert("On a bien 16 octets");
    } else {
      alert("Il y a un problème de taille !");
    } 
    

    Avant de travailler avec ce buffer, il est nécessaire de créer une vue. Ici, on créer une vue qui traite les données du buffer comme celles d'un tableau d'entiers signés sur 32 bits :

    var int32Vue = new Int32Array(buffer);
    

    On peut désormais accéder aux éléments du tableau « normalement » :

    for (var i=0; i<int32Vue.length; i++) {
      int32Vue[i] = i*2;
    }
    

    On remplit ici les 4 entrées du tableau (4 entrée de 4 octets qui donnent 16 octets) avec les valeurs 0, 2, 4 et 6.

    Plusieurs vues sur les mêmes données

    On peut créer plusieurs vues pour les mêmes données. En utilisant le code ci-avant et celui-ci :

    var int16Vue = new Int16Array(buffer);
    
    for (var i=0; i<int16Vue.length; i++) {
      console.log("Entrée " + i + " : " + int16Vue[i]);
    }
    

    On crée une vue sur 16 bits et on partage le même buffer sur lequel on avait écrit avec une vue 32 bits. Le code ci-avant affichera dans l'ordre les chiffres suivants 0, 0, 2, 0, 4, 0, 6, 0.

    Pour aller plus loin, on peut faire :

    int16Vue[0] = 32;
    console.log("L'entrée 0 du tableau 32-bit est " + int32Vue[0]);
    

    Le code produira "L'entrée 0 du tableau 32-bit array est 32". Autrement dit, les deux vues manipulent bien les mêmes données mais sous des formats différents.

    Travailler avec des structures de données complexes

    En combinant un buffer avec différentes vues de différents types, qui commencent à différents endroits du buffer, on peut interagir avec des objets qui contiennent plusieurs types de données. Cela permet entre autres, d'interagir avec des données provenant de WebGL, de fichiers, de structures C utilisant js-ctypes.

    Avec cette structure C :

    struct uneStruct {
      unsigned long id;
      char nomUtilisateur[16];
      float montant;
    };

    On peut accéder à un buffer contenant des données de ce format de cette façon :

    var buffer = new ArrayBuffer(24);
    
    // ... lecture des données dans le buffer ...
    
    var idVue = new Uint32Array(buffer, 0, 1);
    var nomUtilisateurVue = new Uint8Array(buffer, 4, 16);
    var montantVue = new Float32Array(buffer, 20, 1);

    On peut alors accéder au montant grâce à montantVue[0].

    Note : L'alignement des structures de données d'une structure C dépend de la plate-forme utilisée. Il faut donc faire attention et tenir compte des décalages induits éventuels.

    Conversion en tableaux classiques

    Une fois le traitement effectué, on peut vouloir convertir le tableau en un tableau normal afin de bénéficier du prototype Array. Voici un exemple de méthode :

    var tableauTypé = new Uint8Array( [ 1, 2, 3, 4 ] ),
        tableauNormal = Array.apply( [], tableauTypé );
    tableauNormal.length === 4;
    tableauNormal.constructor === Array;
    

    Compatibilité

    Les tableaux typés sont également disponibles sous WebKit. Chrome 7 supporte ArrayBuffer, Float32Array, Int16Array et Uint8Array. Chrome 9 et Firefox 15 supportent les objets DataView. Internet Explorer 10 supporte tous les types à l'exception de Uint8ClampedArray et ArrayBuffer.prototype.slice.

    Spécification

    Voir aussi

     

    Étiquettes et contributeurs liés au document

    Contributeurs ayant participé à cette page : teoli, SphinxKnight
    Dernière mise à jour par : teoli,