# Soporte para formatos adicionales de archivos

Esta sección describe como crear lectores adicionales para la lectura de archivos de datos no soportados. Si no está familiarizado con los conceptos de fuentes de datos, por favor, lea Conceptos de fuentes de datos

## Creando lectores de fuentes de datos

Si desea usar un formato de archivos diferente a aquellos que ya están soportados, puede escribir sus propios lectores de datos de fuentes.

Todos los lectores de fuentes de &kst; son plugins normales de &kde;. Como todos los plugins de &kde;, cada lector de fuentes de datos debe tener una librería dinámica y un archivo `*.desktop`. Antes de escribir el lector, debe decidirse el nombre de la librería a usar por el plugin. Este debe ser un nombre válido como variable C, pues se usará en los nombres de las funciones de la librería dinámica. Por ejemplo, el nombre de librería del lector para archivos ASCII es ascii.

Los plugins de &kde; no son lo mismo que los plugins de &kst; que se usan para manipular datos. Todas las referencias a plugins que damos en esta sección se refieren a plugins de &kde;.

### La librería dinámica

Un lector de fuentes de datos debe ser una subclase de la clase abstracta `KstDataSource`. Asegúrese de que incluye el archivo de cabecera para dicha `KstDataSource` en el código de su lector:

    #include <kstdatasource.h>

Hay ciertos requerimientos que su lector tiene que cumplir. Unos son que hay que exportar ciertas funciones C. Otros son consecuencia de heredar de la clase `KstDataSource`. A continuación explicamos tales requerimientos, junto con sugerencias y explicaciones generales.

#### Funciones en C a exportar

A continuación se listan las funciones en C a exportar. En los ejemplos siguientes, se debe reemplazar todas las instancias de la `<libname>` con el nombre de librería del plugin.

`KstDataSource *create_<libname>(const QString& `filename`, const QString& `type`)`

  Esta función debe crear un nuevo lector de datos fuentes del tipo `<libname>`, donde `<libname>` es el nombre de librería del plugin. Se retorna un puntero al nuevo lector del tipo `KstDataSource`.

`bool understands_<libname>(const QString& `filename`)`

  Esta función bebe retornar verdad si el archivo especificado por `filename` es de un tipo válido soportado por este lector, y falso si no lo es. Esta función solo debe examinar los contenidos del archivo para validar, y no debe basarse en la extensión del archivo.

`QStringList provides_<libname>()`

  Esta función retorna una lista del tipo `QStringList` con los tipos de archivos soportados por este lector. Las cadenas que se retornan son arbitrarias, pero deben ser descriptivas y apropiadas sobre el tipo de archivo.

#### Variables miembros protegidas

`KstDataSource` contiene varias variables miembro protegidas que el lector puede usar. Las describimos a continuación.

`bool _valid`

  Esta variable debe ser `true` (verdad) si nuestro lector de fuentes de datos es válido. Lo más probable es que así sea, a menos de que exista una condición de error (tal que el archivo de datos no sea legible por el lector). Esta variable se usa en conjunción con la función `isValid()` de `KstDataSource`, la cual no suele reimplementarse en las subclases.

`QStringList _fieldList`

  Esta variable debe contener una lista de los nombres de los campos en la fuente de datos.

`QString _filename`

  Esta variable debe asociarse al nombre del archivo de datos al que se asocia el lector de datos.

`QString _source`

  Esta variable debe contener el nombre del tipo de la fuente.

#### Funciones virtuales

La clase `KstDataSource` contiene numerosas funciones virtuales que deben redefinirse en nuestro lector de datos. Estas funciones están en los archivos de plantilla `template.h` y `template.cpp`, listados la sección Plantillas ejemplo. A continuación se presenta una descripción de las funciones.

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

  El constructor del lector de datos. El nombre del archivo del cual se leen los datos es `filename`, y el tipo de datos que contiene es `type`. Lo más normal es que este constructor invoque el constructor de la clase `KstDataSource` en la lista de inicialización del constructor, y que llame a la función `update` (ver más abajo) para inicializar las variables miembro. En particular, hay que asignar la variable `bool _valid` de forma adecuada.

`virtual ~TemplateSource()`

  El destructor del lector de datos. Debe liberar la memoria dinámica que se halla requerido al sistema.

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

  Esta función debe leer cualesquiera datos nuevos que se hayan añadido al archivo de datos desde la última llamada a `update`, y actualizar las variables miembro de forma apropiada. La función debe retornar `KstObject::UPDATE` si ha habido cambios en el archivo, y `KstObject::NO_CHANGE` si no.

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

  Esta función debe leer `n` estructuras de datos, comenzando en la estructura `s` desde el campo especificado por el campo `campo`, y retornar los contenidos en el vector `v`. Si `n` vale menos que 0, la función debe leer 1 muestra comenzando en la estructura `s`. Debe retornarse el número de estructuras que se hayan leído.

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

  Esta función debe retornar verdad cuando el campo `field` es un campo válido en la fuente de datos actual, o falso cuando no lo es.

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

  Esta función retorna la tasa de muestras por estructuras para el campo especificado por `field`. Si las fuentes de datos no hacen uso de este concepto, el número de muestras por estructura debe valer `1`.

`virtual int frameCount() const`

  Esta función debe retornar el número de estructuras en la fuente de datos existentes en el momento de la última llamada `update`.

`virtual QString fileType() const ```

  Esta función debe retornar el tipo del archivo de datos que se está usando, normalmente el mismo que el parámetro `type` que se pasó al constructor. Alternativamente, puede contener un mensaje de error (para indicar, por ejemplo, que el campo no es válido).

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

  Esta función debe guardar la información de descripción del archivo a `ts`. En la mayoría de los casos es suficiente usar la implementación dada por `KstDataSource`.

#### Plantillas ejemplo

Puede usar los dos archivos plantilla siguientes para crear nuevas librerías dinámicas. Simplemente modifique los cuerpos de las funciones como sea necesario para su fuente de datos particular.

    /***************************************************************************
                      template.h  -  Plantilla de plugin para fuentes de datos
                                 -------------------
        begin                : Fri Oct 17 2003
        copyright            : (C) 2003 The University of Toronto
        email                :
     ***************************************************************************/

    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/

    #ifndef TEMPLATE_H
    #define TEMPLATE_H

    #include &lt;kstdatasource.h&gt;

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

      virtual ~TemplateSource();

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

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

      virtual bool isValidField(const QString &field) const;

      virtual int samplesPerFrame(const QString &field);

      virtual int frameCount() const;

      virtual QString fileType() const;

      virtual void save(QTextStream &ts);
    };

    #endif

    /***************************************************************************
                        template.cpp  -  Plantilla de fuente de datos
                                 -------------------
        begin                : Fri Oct 17 2003
        copyright            : (C) 2003 The University of Toronto
        email                :
     ***************************************************************************/

    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/

    #include "template.h"

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

    TemplateSource::~TemplateSource() {
    }

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

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

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

    int TemplateSource::samplesPerFrame(const QString &field) {
      Q_UNUSED(field)
      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& filename, const QString& type) {
      return new TemplateSource(filename, type);
    }

    QStringList provides_template() {
      QStringList rc;
      // create the stringlist
      return rc;
    }

    bool understands_template(const QString& filename) {
      // determine if it is an X file
      Q_UNUSED(filename)
      return false;
    }

    }

### El archivo `.desktop`

A continación se muestra un ejemplo del archivo `.desktop` para la plantilla del 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.

Debería añadir traducciones en lenguajes adicionales para los campos Name y Comment, añadiendo campos Name y Comment adicionales con el sufijo `[xx]` añadido, donde `xx` es el código de dos letras del lenguaje. Por ejemplo, para añadir la traducción española, deberían añadirser estas líneas:

    Name[es]=Plantilla de lectura de ficheros
    Comment[es]=Plantilla de código para hacer un complemento de lectura de ficheros.

El campo `X-Kst-Plugin-Library` debe ser exactamente igual al nombre de librería del plugin.

### Compilando y copiando

Para compilar e instalar una versión personalizada de nuestro lector de datos, cree un nuevo directorio bajo `kst/datasources` del paquete con las fuentes de kst. Ponga sus fuentes junto con el archivo `.desktop` en tal directorio. Entonces edite `kst/datasources/Makefile.am` tal que `SUBDIRS` contenga el nombre del nuevo subdirectorio. Por ejemplo, si el nuevo subdirectorio se llama `template`, `SUBDIRS` puede cambiarse a:

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

Despues de tener a los archivos en el directorio ya creado, se necesita crear ahí un archivo `Makefile.am`. Use el ejemplo siguiente como plantilla, reemplazando template con el nombre de su librería en `kde_module_LTLIBRARIES`, `kstdata_template_la_SOURCES` y `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

Una vez que se haya hecho esto, puede compilar y reinstalar &kst; desde el paquete fuente modificado, o alternativamente, solo instalar las nuevas librerías, como sigue (usando el subdirectorio template como ejemplo). Primero cambie las directorio raíz de las fuentes de &kst;. Entonces,

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

Vuelva a lanzar &kst; y se debería cargar el nuevo lector de datos.