# Ondersteuning van extra bestandstypen

In deze sectie wordt beschreven hoe u extra leesprogramma's kunt maken voor bestandstypen die niet worden ondersteund. Als u het idee achter de gegevensbronnen nog niet kent, moet u Concepten gegevensbronnen eerst even lezen.

## Het maken van leesprogramma's voor gegevensbronnen

Als u een bestandsformaat wilt gebruiken dat nog niet wordt ondersteund, kunt u er voor kiezen zelf een programma te maken dat dit bestandsformaat kan lezen.

Alle leesprogramma's voor gegevensbronnen in &kst; zijn gewone plugins voor &kde;. Zoals alle plugins van &kde; moet elk leesprogramma voor gegevensbronnen een "shared object file" hebben en een `*.desktop`-bestand. Voordat u met het schrijven van het leesprogramma begint moet u de plugin een bibliotheeknaam geven. Deze naam moet een geldige naam zijn in (de programmeertaal) C, omdat die in de functienamen zal worden gebruikt van het "shared object" (gedeelde object). Bijvoorbeeld: de bibliotheeknaam van het leesprogramma voor ASCII-bestanden is ASCII.

De plugins van &kde; zijn niet het zelfde als die die in &kst; worden gebruikt voor het verwerken van gegevens. Alle verwijzingen naar plugins in deze sectie betreffen &kde;-plugins.

### Het "Shared Object" (gedeelde object)

Een leesprogramma voor een gegevensbron moet een "subclass" zijn van de abstracte "class" `KstDataSource`. Zorg ervoor dat u in de broncode van uw leesprogramma het "header"- bestand opneemt voor `KstDataSource`:

    #include <kstdatasource.h>

Er zijn bepaalde eisen waaraan een leesprogramma voor een gegevensbron moet voldoen. Een ervan betreft de aanwezigheid van geëxporteerde C-functies. Andere eisen volgen uit het feit dat leesprogramma's voor gegevensbronnen erven ("inherit") van `KstDataSource`. Beide soorten eisen, samen met suggesties en algemene uitleg, vindt u in de volgende secties terug.

#### Geëxporteerde C- functies

Hieronder volgt een lijst van geëxporteerde C- functies. In al deze voorbeelden moet `<biebnaam>` worden vervangen door de werkelijke bibliotheeknaam van de plugin.

`KstDataSource *create_<biebnaam>(const QString& `bestandsnaam`, const QString& `type`)`

- Deze functie moet een nieuw leesprogramma voor gegevensbronnen maken van het type `<biebnaam>`, waarin `<biebnaam>` de bibliotheeknaam is van de plugin. De functie moet een "pointer" van het type `KstDataSource` naar het nieuwe leesprogramma retourneren.

`bool understands_<biebnaam>(const QString& `bestandsnaam`)`

- Deze functie moet de waarde "true" (waar) retourneren als het type van het bestand `bestandsnaam` door dit leesprogramma wordt ondersteund, en anders "false" (onwaar). De functie moet de inhoud van het bestand controleren, en niet afgaan op extensies in de bestandsnaam.

`QStringList provides_<biebnaam>()`

- Deze functie moet een `QStringList` van bestandstypen retourneren die door dit leesprogramma worden ondersteund. De geretourneerde "strings" (tekenreeksen) kunnen van alles zijn, maar moeten de werkelijke bestandstypen beschrijven en er bij passen.

#### "Protected Member Variables" (beschermde lidvariabelen)

`KstDataSource` kent diverse beschermde lidvariabelen voor gebruik in het leesprogramma voor gegevensbronnen. Hieronder volgt een beschrijving.

`bool _valid`

- Deze variabele moet de waarde `true` (waar) hebben als het zelf gemaakte leesprogramma voor gegevensbronnen in orde is. Hoogstwaarschijnlijk is dat wel het geval, behalve als er een fout optreedt (zoals het onleesbaar zijn van het gegevensbestand door het leesprogramma). Deze variabele wordt gebruikt in de functie `isValid()` van `KstDataSource`, die in de "subclasses" gewoonlijk niet opnieuw wordt geïmplementeerd.

`QStringList _fieldList`

- Deze variabele moet een lijst bevatten van de veldnamen in de gegevensbron.

`QString _filename`

- Deze variabele moet de naam bevatten van het gegevensbestand die behoort bij deze gegevensbron.

`QString _source`

- Deze variabele moet de typenaam bevatten van de bron

#### Virtuele functies

De "class" `KstDataSource` bevat vele virtuele functies die in het eigen leesprogramma voor gegevensbronnen opnieuw moeten worden gedefinieerd. Deze functies vindt u in de "template"bestanden (sjabloonbestanden) `template.h` en `template.cpp`, opgenomen in de sectie Voorbeeldsjablonen. Een beschrijving van deze functies volgt.

`TemplateSource(const QString&amp; `bestandsnaam`, const QString&amp; `type`)`

- De "constructor" voor het leesprogramma voor gegevensbronnen. `bestandsnaam` is de naam van het bestand waaruit gegevens moeten worden gelezen en `type` is het type van de gegevens in het bestand. Deze constructor zal hoogstwaarschijnlijk de constructor van de `KstDataSource` aanroepen in de lijst van te initialiseren constructors, en waarschijnlijk de functie `update` (zie hier onder) aanroepen om lidvariabelen (member variables) te initialiseren. In het bijzonder moet de variabele `bool _valid` de juiste waarde hebben.

`virtual ~TemplateSource()`

- De "destructor" voor het leesprogramma voor gegevensbronnen. Al het dynamisch toegewezen (allocated) geheugen moet weer worden vrijgegeven.

`virtual KstObject::UpdateType update(`int = -1`)`

- Deze functie moet alle nieuwe gegevens in het gegevensbestand, sinds de laatste keer dat de functie `update` werd aangeroepen, inlezen en de lidvariabelen dienovereenkomstig aanpassen. De functie moet `KstObject::UPDATE` retourneren als het bestand is gewijzigd en anders `KstObject::NO_CHANGE`.

`virtual int readField(double *`v`, const QString &`veld`, int `s`, int `n`)`

- Deze functie moet `n` "frames" van gegevens inlezen, te beginnen met frame `s` vanaf het veld met de naam `veld`, en dit in het "array" `v` retourneren. Als `n` kleiner is dan 0 moet de functie 1 monster (sample) lezen vanaf frame `s`. Het aantal ingelezen monsters moet worden geretourneerd.

`virtual bool isValidField(const QString &`veld`) const`

- Deze functie moet "true" (waar) retourneren als het veld met de naam `veld` een geldig veld is in de huidige gegevensbron, en "false" (onwaar) als het niet geldig is.

`virtual int samplesPerFrame(const QString& `veld`)`

- Deze functie moet het aantal monsters per frame retourneren voor het veld met de naam `veld`. Voor gegevensbronnen die hier geen gebruik van maken kan het aantal monsters per frame op `1` worden gesteld.

`virtual int frameCount() const`

- Deze functie moet het totale aantal frames in de gegevensbron retourneren tijdens de laatste keer dat de functie `update` werd aangeroepen.

`virtual QString fileType() const ```

- Deze functie moet het bestandstype retourneren van het gegevensbestand dat nu in gebruik is, dit is gewoonlijk hetzelfde als de `type`-parameter die aan de "constructor" werd meegegeven. Ook kan die een foutmelding bevatten (om aan te geven, bijvoorbeeld, dat het bestandstype niet goed is).

`virtual void save(QTextStream &`ts`)`

- Deze functie moet de beschrijving van het bestand opslaan in `ts`. In de meeste gevallen is de implementatie die beschikbaar is in `KstDataSource` voldoende.

#### Voorbeelden van templates (sjablonen)

In het algemeen kunnen de volgende twee "template"bestanden worden gebruikt voor het maken van nieuwe "shared object files". U kunt ze eenvoudig aanpassen voor uw gegevensbron.

    /***************************************************************************
                      template.h  -  sjabloon voor gegevensbron plugin
                                 -------------------
        begin                : Vri Okt 17 2003
        copyright            : (C) 2003 De Universiteit van Toronto
        email                :
     ***************************************************************************/

    /***************************************************************************
     *
     *   Dit programma is vrije software; U kunt het verspreiden en/of wijzigen
     *   onder de voorwaarden van de GNU General Public License zoals gepubliceerd
     *   door de Free Software Foundation; zowel version 2 van de licentie, als
     *   (als u wilt)   elke volgende versie.
     *
     ***************************************************************************/

    #ifndef TEMPLATE_H
    #define TEMPLATE_H

    #include &lt;kstdatasource.h&gt;

    class TemplateSource : public KstDataSource {
    public:
      TemplateSource(const QString& bestandsnaam, const QString& type);

      virtual ~TemplateSource();

      virtual KstObject::UpdateType update(int = -1);

      virtual int readField(double *v, const QString &veld, int s, int n);

      virtual bool isValidField(const QString &veld) const;

      virtual int samplesPerFrame(const QString &veld);

      virtual int frameCount() const;

      virtual QString fileType() const;

      virtual void save(QTextStream &ts);
    };

    #endif

    /***************************************************************************
                        template.cpp  -  sjabloon voor gegevensbron
                                 -------------------
        begin                : Vri Okt 17 2003
        copyright            : (C) 2003 de Universiteit van Toronto
        email                :
     ***************************************************************************/

    /***************************************************************************
     *
     *   Dit programma is vrije software; U kunt het verspreiden en/of wijzigen
     *   onder de voorwaarden van de GNU General Public License zoals gepubliceerd
     *   door de Free Software Foundation; zowel version 2 van de licentie, als
     *   (als u wilt)   elke volgende versie.
     *
     ***************************************************************************/

    #include "template.h"

    TemplateSource::TemplateSource(const QString& bestandsnaam, const QString& type)
    : KstDataSource(bestandsnaam, type) {
    }

    TemplateSource::~TemplateSource() {
    }

    KstObject::UpdateType TemplateSource::update(int u) {
      Q_UNUSED(u)
      return KstObject::NO_CHANGE;
    }

    int TemplateSource::readField(double *v, const QString& veld, int s, int n) {
      Q_UNUSED(v)
      Q_UNUSED(veld)
      Q_UNUSED(s)
      Q_UNUSED(n)
      return -1;
    }

    bool TemplateSource::isValidField(const QString& veld) const {
      Q_UNUSED(veld)
      return false;
    }

    int TemplateSource::samplesPerFrame(const QString &veld) {
      Q_UNUSED(veld)
      return 0;
    }

    int TemplateSource::frameCount() const {
      return 0;
    }

    QString TemplateSource::fileType() const {
      return QString::null;
    }

    void TemplateSource::save(QTextStream &ts) {
      KstDataSource::save(ts);
    }

    extern "C" {
    KstDataSource *create_template(const QString& bestandsnaam, const QString& type) {
      return new TemplateSource(bestandsnaam, type);
    }

    QStringList provides_template() {
      QStringList rc;
      // de lijst van strings maken
      return rc;
    }

    bool understands_template(const QString& bestandsnaam) {
      // stel vast of het een X- bestand is
      Q_UNUSED(bestandsnaam)
      return false;
    }

    }

### Het `.desktop`-bestand

Het volgende is een voorbeeld van een `.desktop`-bestand voor de template plugin:

    [Desktop Entry]
    Encoding=UTF-8
    Type=Service
    ServiceTypes=Kst Data Source
    X-KDE-ModuleType=Plugin
    X-Kst-Plugin-Library=template
    X-Kst-Plugin-Author=The University of Toronto
    Name=File Reader Template
    Comment=Long description of the file reader template.

Hieraan kunt u vertalingen toevoegen van de Name- en Comment-regels (naam en commentaar) voor andere talen door er extra Name- en Comment-regels aan toe te voegen met `[xx]` aan het eind van de veldnamen, waarin `xx` de tweeletterige taalcode is (nl voor Nederlands). Bijvoorbeeld, voor het toevoegen van Nederlandse vertalingen moet u de volgende regels toevoegen:

    Name[nl]=Sjabloon (template) voor leesprogramma voor bestanden
    Comment[nl]=Sjabloon voor de programmacode van een leesprogramma voor bestanden

Het veld `X-Kst-Plugin-Library` moet exact gelijk zijn aan de bibliotheeknaam die is gekozen voor de plugin.

### Compileren en kopiëren

Om het nieuwe aangepaste leesprogramma voor gegevensbronnen te compileren en te installeren maken wij eerst een nieuwe map onder `kst/datasources` van het bronpakket. Plaats de bronbestanden voor het object, samen met het `.desktop`-bestand in de nieuwe map. Daarna wijzigen we `kst/datasources/Makefile.am` zo dat `SUBDIRS` de naam bevat van de nieuwe submap. Bijvoorbeeld, als de nieuwe submap `template` heet kan `SUBDIRS` als volgt worden gewijzigd:

    SUBDIRS=ascii dirfile frame indirect template $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)

Als de vereiste bestanden in de nieuw gemaakte submap zijn geplaatst moet er ook een `Makefile.am` in worden gemaakt. Gebruik het volgende voorbeeld als een sjabloon (template) waarin u elke keer dat er template staat dit vervangt door uw bibliotheeknaam `kde_module_LTLIBRARIES`, `kstdata_template_la_SOURCES` en `services_DATA`.

    INCLUDES=-I$(srcdir)/../.. $(all_includes)

    kde_module_LTLIBRARIES=kstdata_template.la

    kstdata_template_la_LDFLAGS=$(all_libraries) -module -avoid-version
    kstdata_template_la_SOURCES=template.cpp

    METASOURCES=AUTO

    services_DATA=kstdata_template.desktop
    servicesdir=$(kde_servicesdir)/kst

Als dit is gebeurd kunt u &kst; compileren en weer installeren vanuit het gewijzigde bronpakket, of anders alleen de nieuwe bibliotheken installeren, als volgt (de template-submap wordt als voorbeeld gebruikt). Ga eerst naar de root-map van het bronpakket van &kst;. Daarna:

    ./configure --prefix=`kde-config --prefix`
    cd ./kst/datasources/template
    make
    make install

Als u nu &kst; opnieuw start moet het nieuwe leesprogramma voor gegevensbronnen worden ingelezen.