# 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 los Conceptos de fuentes de datos.

## Crear 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 extensiones normales de &kde;. Como todas las extensiones de &kde;, cada lector de fuentes de datos debe tener una biblioteca dinámica y un archivo `*.desktop`. Antes de escribir el lector, debe decidirse el nombre de la biblioteca a usar por la extensión. Éste debe ser un nombre válido como variable C, pues se usará en los nombres de las funciones de la biblioteca dinámica. Por ejemplo, el nombre de biblioteca del lector para archivos ASCII es «ascii».

Las extensiones de &kde; no son diferentes de las extensiones de &kst; que se usan para manipular datos. Todas las referencias de las extensiones que damos en esta sección se refieren a extensiones de &kde;.

### La biblioteca 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 deben reemplazar todas las instancias de la `<libname>` con el nombre de la biblioteca de la extensión.

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

  Esta función debe crear un nuevo lector de datos fuentes del tipo `<libname>`, donde `<libname>` es el nombre de biblioteca de la extensión. Se devuelve un puntero al nuevo lector del tipo `KstDataSource`.

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

  Esta función debe devolver el valor verdadero si el archivo especificado por `nombrearchivo` 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 devuelve una lista del tipo `QStringList` con los tipos de archivos soportados por este lector. Las cadenas que se devuelven son arbitrarias, pero deben ser descriptivas y apropiadas para los tipos de archivo actual.

#### 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` (verdadero) si nuestro lector de fuentes de datos es válido. Lo más probable es que así sea, a menos que exista una condición de error (tal que el archivo de datos no sea legible por el lector). Esta variable se usa junto 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 en la sección Plantillas de ejemplo. A continuación se presenta una descripción de las funciones.

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

  El constructor del lector de datos. El nombre del archivo del cual se leen los datos es `nombrearchivo`, 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 devolver `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 devolver 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 devolverse el número de estructuras que se hayan leído.

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

  Esta función debe devolver el valor verdadero si 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 devuelve 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 devolver 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 devolver 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 bibliotecas dinámicas. Simplemente modifique los cuerpos de las funciones como sea necesario para su fuente de datos particular.

    /***************************************************************************
                      template.h  -  Plantilla de extensión para fuentes de datos
                                 -------------------
        inicio               : Vie 17 Oct 2003
        derechos de autor    : (C) 2003. La univerdad de Toronto
        correo electrónico   :
     ***************************************************************************/

    /***************************************************************************
     *                                                                         *
     *   Éste programa es software libre. Puede distribuirlo y/o modificarlo   *
     *   bajo los términos de la Licencia Pública General GNU y publicado por  *
     *   la Free Software Foundation, en su versión 2 de la licencia o         *
     *   posterior (a su elección).                                            *
     *                                                                         *
     ***************************************************************************/

    #ifndef TEMPLATE_H
    #define TEMPLATE_H

    #include &lt;kstdatasource.h&gt;

    class TemplateSource : public KstDataSource {
    public:
      TemplateSource(const QString& nombrearchivo, 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
                                 -------------------
        inicio               : Vie 17 Oct 2003
        derechos de autor    : (C) 2003 La universidad de Toronto
        correo electrónico   :
     ***************************************************************************/

    /***************************************************************************
     *                                                                         *
     *   Éste programa es software libre. Puede distribuirlo y/o modificarlo   *
     *   bajo los términos de la Licencia Pública General GNU y publicado por  *
     *   la Free Software Foundation, en su versión 2 de la licencia o         *
     *   posterior (a su elección).                                            *
     *                                                                         *
     ***************************************************************************/
    n#include "template.h"

    TemplateSource::TemplateSource(const QString& nombrearchivo, const QString& type)
    : KstDataSource(nombrearchivo, 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& nombrearchivo, const QString& type) {
      return new TemplateSource(nombrearchivo, type);
    }

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

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

    }

### El archivo `.desktop`

A continuación se muestra un ejemplo del archivo `.desktop` para la plantilla de la extensión:

    [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 idiomas 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 archivos
    Comment[es]=Plantilla de código para hacer una extensión de lectura de archivos.

El campo `X-Kst-Plugin-Library` debe ser exactamente igual al nombre de la biblioteca de la extensión.

### 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 biblioteca 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 bibliotecas, como sigue (usando el subdirectorio «template» como ejemplo). Primero cambie las directorio raíz de las fuentes de &kst;. Y después escriba

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

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