Serie ficheros virtuales 




C Ficheros virtuales


 

 

 

B.II.2 NET Ficheros virtuales. Las clases wFile y vbFile. 

 

 B.II.2.1 Introducción

 B.II.2.2 La implementación de la clase wFile

 B.II.2.3 Limitaciones de uso de la clase wFile en .Net

 B.II.2.4 La implementación de la clase vbFile para uso en VisualBasic.Net

 B.II.2.5 La clase AlfaConv, núcleo de soporte de la clase vbFile

 B.II.2.6 Los servicios de SRAlfaConv, núcleo de soporte de la clase AlfaConv

 B.II.2.7 Notas para el enlace de compilación de AlfaConv con SRAlfaConv

 

                                                                                                                                ________



B.II.2.1 Introducción

 

La clase wFile proporciona un interfaz NET a los servicios de SRRCW.

 

La clase vbFile proporciona un interfaz NET a los servicios de SRRCW, con una funcionalidad limitada a cadenas *String.

 

La idea es que las estructuras pueden soportarse mediante cadenas y resolver entonces problemas directamente en Visual Basic.

 

 

Alternativamente, se pueden construir clases interfaz NET especializadas, como se hace en CMagic y en CJvida, lo que será objeto de capítulos posteriores.

 

                                                                                                                                ________

 

 

B.II.2.2 La implementación de la clase wFile

 

Siguiendo la lista de funciones de SRRCW, la clase wFile ofrece la siguiente

 

 

Lista de métodos de wFile por grupos funcionales

 

 

Funciones de gestión de objetos

 

 

// Crear por constructores

 

wFile(void)

 

wFile(long lDimD)

wFile(int iDimC, long lDimD)

wFile(int iDimC, long lDimD, long lMaxNreg)

 

wFile(const char *cName)

wFile(const char *cName, long lDimD)

wFile(const char *cName, int iDimC, long lDimD)

wFile(const char *cName, int iDimC, long lDimD, long lMaxNreg)

 

wFile(const char *cName, const char *cOpci, long lDimD, long lMaxNreg)

wFile(const char *cName, const char *cOpci, long lDimD)

 

 

 

// Crear, añadiendo nuevos ficheros a la clase en curso

 

// Bajo formato que limpia datos previos si existieran

 

long NEW(const char *cName, int iDimC)

long NEW(const char *cName, int iDimC, long lDimD)

long NEW(const char *cName, int iDimC, long lDimD, long lMaxNreg)

 

 

 

// Crear, añadiendo si procede nuevos ficheros a la clase en curso

 

// Bajo formato sin limpiar datos previos si existieran

 

long NOW(const char *cName, int iDimC)

long NOW(const char *cName, int iDimC, long lDimD)

long NOW(const char *cName, int iDimC, long lDimD, long lMaxNreg)

 

 

 

// Reconstructores completos de un ítem de clase

 

long RESIZ(int iDimC, long lDimD, long lMaxNreg)

long RESIZ(int iDimC, long lDimD)

 

long RESIZ(const char *cName, int iDimC, long lDimD, long lMaxNreg)

long RESIZ(const char *cName, int iDimC, long lDimD)

 

long RESIZ(const char *cName, const char *cOpci, long lDimD, long lMaxNreg)

long RESIZ(const char *cName, const char *cOpci, long lDimD)

 

 

 

// Reconstructores reducidos para cambiar exclusivamente el nº máximo de registros permitidos

 

long RESIZ(long lMaxNreg)

long RESIZ(const char *cName, long lMaxNreg)

 

 

 

// Creación de vías de acceso suplementarias

 

long CRTLF(const char *cLF, int iKPOS, int iKLEN)

long CRTLF(const char *cLF, const char *cName, int iKPOS, int iKLEN)

 

 

 

// Vaciado de datos

 

long CLRF(const char *cLF, long *lNBAJp)

long CLRF(const char *cLF)

 

 

 

// Eliminación completa

 

short int ERASE(void)

short int ERASE(const char *cName)

 

 

 

// Cierre total

 

short int CLOSE(void)

 

                                                                                                                                ________

 

 

Funciones de caché básico. Núcleo del sistema

 

// Grupo CHAIN

 

long CHAIN(const void *vClav, void *vDato)

long CHAIN(void *vDato)

 

long CHAIN(const char *cName, const void *vClav, void *vDato)

long CHAIN(const char *cName, void *vDato)

 

long VER(const void *vClav)

long VER(const char *cName, const void *vClav)

 

 

 

// Grupo WRITE

 

long WRITE(const void *vClav, const void *vDato)

long WRITE(const void *vDato)

 

long WRITE(const char *cLF, const void *vClav, const void *vDato)

long WRITE(const char *cLF, const void *vDato)

 

 

 

// Funciones derivadas directas

 

 

// Grupo UPDATE

 

long UPDATE(const void *vClav, const void *vDato)

long UPDATE(const void *vDato)

 

long UPDATE(const char *cLF, const void *vClav, const void *vDato)

long UPDATE(const char *cLF, const void *vDato)

 

 

 

// Funciones derivadas intrínsicamente del orden

 

 

// Grupo DELETE

 

long DELET(const void *vClav)

long DELET(const char *cLF, const void *vClav)

 

 

 

// Grupo Posicionamiento

 

long SETEQ(const void *vCLVp, long lLong)

long SETEQ(const void *vCLVp)

 

long SETEQ(const char *cLF, const void *vCLVp, long lLong)

long SETEQ(const char *cLF, const void *vCLVp)

 

 

long SETGT(const void *vCLVp, long lLong)

long SETGT(const void *vCLVp)

 

long SETGT(const char *cLF, const void *vCLVp, long lLong)

long SETGT(const char *cLF, const void *vCLVp)

 

 

long SETGTT(const void *vCLVp, long lLong)

long SETGTT(const void *vCLVp)

 

long SETGTT(const char *cLF, const void *vCLVp, long lLong)

long SETGTT(const char *cLF, const void *vCLVp)

 

 

long SETLL(const void *vCLVp, long lLong)

long SETLL(const void *vCLVp)

 

long SETLL(const char *cLF, const void *vCLVp, long lLong)

long SETLL(const char *cLF, const void *vCLVp)

 

 

 

// Grupo READ

 

short int READ(long lINDIp, void *vDato, void *vClav)

short int READ(long lINDIp, void *vDato)

 

short int READ(const char *cLF, long lINDIp, void *vDato, void *vClav)

short int READ(const char *cLF, long lINDIp, void *vDato)

 

 

long READE(const void *vCLVp, long lLong, void *vDato, void *vClav)

long READE(const void *vCLVp, long lLong, void *vDato)

 

long READE(const char *cLF, const void *vCLVp, long lLong, void *vDato, void *vClav)

long READE(const char *cLF, const void *vCLVp, long lLong, void *vDato)

 

 

long READPE(const void *vCLVp, long lLong, void *vDato, void *vClav)

long READPE(const void *vCLVp, long lLong, void *vDato)

 

long READPE(const char *cLF, const void *vCLVp, long lLong, void *vDato, void *vClav)

long READPE(const char *cLF, const void *vCLVp, long lLong, void *vDato)

 

 

                                                                                                                                ________

 

Extensión de base de datos

 

 

// Copia de datos

 

long CPY(const char *cORG, const char *cDES, short int iREP)

long CPY(const char *cORG, const char *cDES)

 

 

// Duplicacion de bases de datos virtuales

 

long DUP(const char *cORG, const char *cDES)

 

 

 

 

Persistencia de datos

 

 

// Restauración desde fichero físico

 

long RSTF(const char *cSAVF)

long RSTF_NAME(const char *cName)

 

 

// Salvado a fichero físico

 

long SAVF(const char *cSAVF)

long SAVF_NAME(const char *cName)

 

 

 

Grupo informativo y de control

 

short int INF(int *iDimCp, long *lDimDp, long *lNITEMp, long *lBAJASp, long *lNIDDp)

short int INF(const char *cLF, int *iDimCp, long *lDimDp, long *lNITEMp, long *lBAJASp, long *lNIDDp)

 

char *Name()

char *Name(const char *cName)

 

long NID()

long NID(const char *cLF)

 

 

 

Grupos de emulación de pilas y colas

 

 

// Grupo emulación pilas (LIFO)

 

long LIFO_NEW(const char *cName, long lDimD, long lMaxNreg)

long LIFO_NEW(const char *cName, long lDimD)

 

 

short int LIFO_READ(const char *cName, void *vDato, char cOpci)

short int LIFO_READ(const char *cName, void *vDato)

 

 

long LIFO_WRIT(const char *cName, const void *vDato)

 

 

 

// Grupo emulación colas (FIFO)

 

long FIFO_NEW(const char *cName, long lDimD, long lMaxNreg)

long FIFO_NEW(const char *cName, long lDimD)

 

 

short int FIFO_READ(const char *cName, void *vDato, char cOpci)

short int FIFO_READ(const char *cName, void *vDato)

 

 

long FIFO_WRIT(const char *cName, const void *vDato)

 

                                                                                                                                ________


 

Ahora entraremos en el detalle de la implementación seleccionando el fragmento de comienzo de wFile y uno de los métodos principales para explicar detalladamente el mecanismo de enlace entre SRRCW y wFile

 

 

El sistema genera el código siguiente en wFile.h al crear el módulo:

 

// wFile.h

 

#pragma once

 

 

#using <mscorlib.dll>

using namespace System;

 

 

 

A continuación se utilizan los pragmas managed/unmanaged para mezclar código administrado y no administrado y así poder incluir los servicios desarrollados sin utilizar .NET; es de remarcar que esta posibilidad esencial sólo se permite en C++.NET, y que no es factible en nigún otro lenguaje de la familia net:

 

 

#pragma unmanaged

#include "srrcalx.h"

#include "srrcwx.h"

#pragma managed

 

 

 

El programa continua su desarrollo implementando wFile

 

   //--------------------------------------------------------------------------------- 

   // Clase wFile. Evolución de SRRCM..SRRCW a .NET                        

   //--------------------------------------------------------------------------------- 

   namespace wFile 

   { 

    public __gc class wFile 

    { 

     // TODO: agregar aquí los métodos de la clase. 

 

     private

 

     long lNID;   // Nid asociado a cada fichero virtual 

     char *cFILE; // Nombre *dft, paso de SRRCAL_wFile 

                  //  cFILE Es para utilizar sólo en invocaciones únicas, en otro caso deben usarse las versiones con cName|cLF explícito 

  

    public

    . . . 

 

   //----------------------------------------------------------------------------------- 

   // 

   // Método  CHAIN 

   // 

   // DESCRIPCION: Recupera un Item de Memoria por Clave                 

   // 

   //                                                                    

   // PARAMETROS.: Formato completo 

   // 

   // (entrada) vClav: Clave del Item                                    

   // (salida ) vDato: Datos del Item         

   // 

   //                            

   // PARAMETROS.: Formato compacto 

   // 

   // (I/O)     vClav: Clave + datos del Item                                    

   //       

   // 

   // Además de las versiones con nombre para ficheros explícitos o para lógicos 

   //                                                                    

   // RETORNO....:                                                       

   //                 0: Error de Proceso (No encontrado, ...)           

   //                >0: Indice en memoria-claves del Item encontrado    

   //                    (formato 1..N)                                  

   // 

   //---------------------------------------------------------------------------------- 

   long CHAIN(const void *vClav, void *vDato) 

   { 

    return SRRCW_CHAIN(cFILE, vClav, vDato); 

   } 

 

   long CHAIN(void *vDato) 

   { 

    return SRRCW_CHAIN(cFILE, vDato); 

   } 

 

   long CHAIN(const char *cName, const void *vClav, void *vDato) 

   { 

    return SRRCW_CHAIN(cName, vClav, vDato); 

   } 

  

. . . 

                                                                                                                                ________ 

 



B.II.2.3 Limitaciones de uso de la clase wFile en .Net

 

wFile resulta un interfaz directo de SRRCW, apropiado para lenguajes .NET que puedan utilizar punteros como el propio C++ no administrado.

 

Una relación completa de sus métodos se incluye en el anexo C, donde se presentan con ejemplos tomados del programa de muestra PruebasWfile del que expone ahora una muestra

 

 



 

Por su parte, en VisualBasic.Net wFile se reconoce, pero los métodos que utilizan punteros son inaccesibles.

 

Un problema adicional está en los parámetros de salida, que tampoco se pueden utilizar directamente y hay que recurrir a funciones estilo “get”.

 

Por ello, se va a introducir ahora la clase vbFile que permite utilizar SRRCW, aunque con una funcionalidad limitada a cadenas String, como en el prototipo siguiente que recupera los datos grabados para una clave dada:

 

                              String *CHAIND(String *sClav);

 

y que ya es accesible en VisualBasic.

 

 

Con esta clase y encapsulando en cadenas String las estructuras que se precisen, pueden hacerse desarrollos directos, pero conviene señalar que una alternativa más eficaz es utilizar clases finales al estilo de CMagic y CJvida, que se verán posteriormente, que ya no utilizan punteros sino parámetros de control y que soportan por ello interfaces de presentación C y VisualBasic.

 

                                                                                                                                ________

 

 

B.II.2.4 La implementación de la clase vbFile, para uso en VisualBasic.Net

 

Como wFile, vbFile también sigue la lista de funciones de SRRCW, ofreciendo la siguiente

 

 

Lista de procedimientos de vbFile por grupos funcionales

 

 

Funciones de gestión de objetos

 

// Constructores

 

vbFile(void)

vbFile(long lDimD)

vbFile(int iDimC, long lDimD)

vbFile(int iDimC, long lDimD, long lMaxNreg)

 

 

// Versiones con nombre

 

vbFile(String *sFILE)

vbFile(String *sFILE, long lDimD)

vbFile(String *sFILE, int iDimC, long lDimD)

vbFile(String *sFILE, int iDimC, long lDimD, long lMaxNreg)

 

 

// Destructor nominal y efectivo

 

vbFile::~vbFile()

short int CLOSE(void)

 

 

// Reconstructores interfaz a (SRRCW_ERASE + SRRCW_NEW)

 

long RESIZ(String *sFILE, int iDimC, long lDimD, long lMaxNreg)

long RESIZ(String *sFILE, int iDimC, long lDimD)

 

long RESIZ(int iDimC, long lDimD, long lMaxNreg)

long RESIZ(int iDimC, long lDimD)

 

 

// Interfaz no reconstructor, se limita a cambiar el tamaño máximo de registros

 

long RESIZ(String *sFILE, long lMaxNreg)

long RESIZ(long lMaxNreg)

 

 

 

// Agregadores. Permiten añadir ficheros adicionales a una clase

 

// Agradores NEW. Si los ficheros no existe los crean, si ya existen los limpian

 

long NEW(String *sName, int iDimC)

long NEW(String *sName, int iDimC, long lDimD)

long NEW(String *sName, int iDimC, long lDimD, long lMaxNreg)

 

long LIFO_NEW(String *sName, long lDimD, long lMaxNreg)

long LIFO_NEW(String *sName, long lDimD)

 

long FIFO_NEW(String *sName, long lDimD, long lMaxNreg)

long FIFO_NEW(String *sName, long lDimD)

 

 

// Agregadores Now. Son condicionales, solo agregan ficheros nuevos

 

long NOW(String *sName, int iDimC)

long NOW(String *sName, int iDimC, long lDimD)

long NOW(String *sName, int iDimC, long lDimD, long lMaxNreg)

 

 

// REORGANIZE: Reorganiza un vbFile suprimiendo físicamente los elementos borrados

 

short int REORGANIZE(void)

short int REORGANIZE(String *sFILE)

 

 

 

Creación de lógicos (Vías de acceso suplementarias)

 

long CRTLF(String *sLF, int iKPOS, int iKLEN)

long CRTLF(String *sLF, String *sFILE, int iKPOS, int iKLEN)

 

 

 

Vaciado de datos

 

long CLRF(long *lNBAJp)

long CLRF()

long CLRF(String *sLF, long *lNBAJp)

long CLRF(String *sLF)

 

 

 

Eliminación completa de un archivo o una base de datos

 

short int ERASE(void)

short int ERASE(String *sName)

 

 

 

Cierre de la aplicación

 

short int CLOSE(void)

 

 

 

Funciones de caché básico. Núcleo del sistema

 

Recuperación de datos por clave

 

long CHAIN(String *sClav, String *sDato)

long CHAIN(String *sDato)

long CHAIN(String *sLF, String *sClav, String *sDato)

 

String *CHAIND(String *sClav)

String *CHAINLFD(String *sLF, String *sClav)

 

 

long VER(String *sClav)

long VER(String *sFILE, String *sClav)

 

 

 

Grabación de datos

 

long WRITE(String *sClav, String *sDato)

long WRITE(String *sDato)

long WRITE(String *sLF, String *sClav, String *sDato)

 

long WRITELF(String *sLF, String *sDato)

 

 

 

Actualización de ítem por clave

 

long UPDATE(String *sClav, String *sDato)

long UPDATE(String *sDato)

long UPDATE(String *sLF, String *sClav, String *sDato)

 

long UPDATELF(String *sLF, String *sDato)

 

 

 

Eliminación de ítem por clave

 

long DELET(String *sClav)

long DELET(String *sLF, String *sClav)

 

 

 

Posicionamiento (SETLL..)

 

long SETEQ(String *sCLVp, long lLong)

long SETEQ(String *sCLVp)

long SETEQ(String *sLF, String *sCLVp, long lLong)

long SETEQ(String *sLF, String *sCLVp)

 

long SETGT(String *sCLVp, long lLong)

long SETGT(String *sCLVp)

long SETGT(String *sLF, String *sCLVp, long lLong)

long SETGT(String *sLF, String *sCLVp)

 

long SETGTT(String *sCLVp, long lLong)

long SETGTT(String *sCLVp)

long SETGTT(String *sLF, String *sCLVp, long lLong)

long SETGTT(String *sLF, String *sCLVp)

 

long SETLL(String *sCLVp, long lLong)

long SETLL(String *sCLVp)

long SETLL(String *sLF, String *sCLVp, long lLong)

long SETLL(String *sLF, String *sCLVp)

 

 

 

Lectura (READ..)

 

short int READ(long lINDIp, String *sDato, String *sClav)

short int READ(long lINDIp, String *sDato)

short int READ(String *sLF, long lINDIp, String *sDato, String *sClav)

short int READ(String *sLF, long lINDIp, String *sDato)

 

String *READD(long lINDIp) // Read de datos

String *READK(long lINDIp) // Read de claves

String *READLFD(String *sLF, long lINDIp) // Read de datos para LF

String *READLFK(String *sLF, long lINDIp) // Read de claves para LF

 

 

long READE(String *sCLVp, long lLong, String *sDato, String *sClav)

long READE(String *sCLVp, long lLong, String *sDato)

 

long READE(String *sLF, String *sCLVp, long lLong, String *sDato, String *sClav)

long READE(String *sLF, String *sCLVp, long lLong, String *sDato)

 

String *READED(String *sCLVp, long lLong)

String *READEK(String *sCLVp, long lLong)

 

String *READELFD(String *sLF, String *sCLVp, long lLong)

String *READELFK(String *sLF, String *sCLVp, long lLong)

 

 

long READPE(String *sCLVp, long lLong, String *sDato, String *sClav)

long READPE(String *sCLVp, long lLong, String *sDato)

 

long READPE(String *sLF, String *sCLVp, long lLong, String *sDato, String *sClav)

long READPE(String *sLF, String *sCLVp, long lLong, String *sDato)

 

String *READPED(String *sCLVp, long lLong)

String *READPEK(String *sCLVp, long lLong)

 

String *READPELFD(String *sLF, String *sCLVp, long lLong)

String *READPELFK(String *sLF, String *sCLVp, long lLong)

 

 

 

Extensiones de base de datos. CPY y DUP

 

long CPY(String *sORG, String *sDES, short int iREP)

long CPY(String *sORG, String *sDES)

 

long DUP(String *sORG, String *sDES)

 

 

 

Persistencia de datos. RSTF y SAVF

 

long RSTF(String *sSAVF)

long RSTF_NAME(String *sFILE)

 

 

long SAVF(String *sSAVF)

long SAVF_NAME(String *sFILE)

 

 

 

Grupo informativo y de control. INF, NAME y NID

 

int INF_DimC(void)

int INF_DimC(String *sLF)

long INF_DimD(void)

long INF_DimD(String *sLF)

long INF_NITEM(void)

long INF_NITEM(String *sLF)

long INF_BAJAS(void)

long INF_BAJAS(String *sLF)

long INF_NETO(void)

long INF_NETO(String *sLF)

long INF_NIDD(void)

long INF_NIDD(String *sLF)

 

 

long NID()

long NID(String *sLF)

 

 

String *Name()

String *Name(String *sFILE)

 

 

 

Pilas y colas

 

// Constructores para pilas y colas s/ sOpci: C=Cola P=Pila

 

vbFile(String *sFILE, String *sOpci, long lDimD, long lMaxNreg)

vbFile(String *sFILE, String *sOpci, long lDimD)

 

 

// Reconstructores interfaz a SRRCW_FIFO_NEW (colas), SRRCW_LIFO_NEW (pilas) s/ sOpci

 

long RESIZ(String *sFILE, String *sOpci, long lDimD, long lMaxNreg)

long RESIZ(String *sFILE, String *sOpci, long lDimD)

 

 

 

Métodos específicos para pilas (LIFO)

 

long LIFO_NEW(String *sName, long lDimD, long lMaxNreg)

long LIFO_NEW(String *sName, long lDimD)

 

String *LIFO_READ(String *sFILE, String *sOpci)

String *LIFO_READ(String *sFILE)

 

long LIFO_WRIT(String *sFILE, String *sDato)

 

 

 

Métodos específicos para colas (FIFO)

 

long FIFO_NEW(String *sName, long lDimD, long lMaxNreg)

long FIFO_NEW(String *sName, long lDimD)

 

String *FIFO_READ(String *sFILE, String *sOpci)

String *FIFO_READ(String *sFILE)

 

long FIFO_WRIT(String *sFILE, String *sDato)



                                                                                                                                ________


 

El cuanto al detalle de la implementación, exponemos ahora el fragmento inicial de vbFile y uno de sus métodos principales para explicar el mecanismo de enlace entre SRRCW y vbFile:

 

 

   // vbFile.h

 

   #pragma once

 

 

   // Include base de .NET

 

   #using <mscorlib.dll>

   using namespace System;

 

 

 

   // Include de clases .NET externas de usuario

 

   #using "AlfaConv.dll"  // Soporte de conversión  char*   versus   String* 

 

 

 

Como en wFile, a continuación se utilizan los pragmas managed/unmanaged para mezclar código administrado y no administrado:

 

   #pragma unmanaged

   #include "srrcalx.h"

   #include "srrcwx.h"

   #pragma managed

 

[El uso de  AlfaConv  y de estos pragmas es la base del funcionamiento de esta clase]

 

 

 

   //-----------------------------------------------------------------------------------

   // Clase vbFile. Interfaz SRRCW para uso en Visual Basic NET             

   //-----------------------------------------------------------------------------------

   namespace vbFile

   {

    public __gc class vbFile

    {

     // TODO: agregar aquí los métodos de la clase.

 

     private:

 

      long lNID;   // Nid asociado

      char *cFILE; // Nombre *dft, paso de SRRCAL_wFile

 

      // El uso del nombre suministrado por defecto cFILE simplifica el manejo en programas de llamada que utilicen un único ejemplar de

      // la clase, al estilo de cómo hacía la clase vFile que vimos en la primera parte. En otro caso deben usarse las versiones con sName

      // explícito

 

 

      // Clase para conversiones String* a char*

      static AlfaConv::AlfaConv *ALFACONV = new AlfaConv::AlfaConv();

 

     public:

 

      vbFile(void)

      {

       // Genera nombre interno "000000000n" secuencial

       

       cFILE = SRRCAL_wFile();

 

 

       // Genera identificador asociado

 

       lNID = SRRCW_NEW(cFILE, 10);

       return;

      }

             

     . . .

 

 

      // Versiones con nombre

 

      vbFile(String *sFILE)

      {

 

       // Convierte sFILE

  

       cFILE = ALFACONV->sTOc(sFILE);

  

 

       // Genera identificador asociado

 

       lNID = SRRCW_NEW(cFILE, 10);

       return;

      }

 

     . . .

 

 

      //-------------------------------------------------------------------------------

      // Método  CHAIN

      //

      // DESCRIPCION: Recupera un Item de Memoria por Clave               

      //

      //                                                                  

      // PARAMETROS.: Formato completo

      //

      // (entrada) sClav: Clave del Item                                   

      // (salida ) sDato: Datos del Item       

      //

      //                          

      // PARAMETROS.: Formato compacto

      //

      // (I/O)     sDato: Clave + datos del Item en un solo parámetro

      //     

      //

      // Además de las versiones con nombre

      //

      //                                                                  

      // RETORNO....:                                                     

      //                 0: Error de Proceso (No encontrado, ...)         

      //                >0: Indice en memoria-claves del Item encontrado  

      //                    (formato 1..N)                                

      //

      //-------------------------------------------------------------------------------

      long CHAIN(String *sClav, String *sDato)

      {

       long lresul = 0;   // Control de resultados

       char *cClav;       // Soporte de paso de clave

       char cDato[32766]; // Soporte de paso de datos

 

       // Convierte *String a *char haciéndolo accesible a SRRCW

       cClav = ALFACONV->sTOc(sClav);

 

       // Emite el chain

       lresul = SRRCW_CHAIN(cFILE, cClav, cDato);

 

       // La conversión de *char a *String es directa

       sDato = cDato;

 

       // Devuelve el índice obtenido en SRRCW_CHAIN

       return lresul;

      }

    

 

      // Método “compacto” donde se reciben Clave + Datos del Item en un solo parámetro

      long CHAIN(String *sDato)

      {

       long lresul = 0; // Control de resultados

 

       char *cDato = ALFACONV->sTOc(sDato);

       lresul = SRRCW_CHAIN(cFILE, cDato);

       sDato = cDato;

 

       return lresul;

      }

  

 

      // Versiones con nombre explícito de fichero virtual

  

      long CHAIN(String *sLF, String *sClav, String *sDato)

      {

       long lresul = 0;   // Control de resultados

       char *cLF;         // Paso de nombre de LF

       char *cClav;       // Paso de clave

       char cDato[32766]; // Paso de datos

 

       // Convierte *String a *char haciéndolos accesible a SRRCW

       cLF = ALFACONV->sTOc(sLF);

       cClav = ALFACONV->sTOc(sClav);

 

       // Emite el chain

       lresul = SRRCW_CHAIN(cLF, cClav, cDato);

 

       // La conversión de *char a *String es directa

       sDato = cDato;

 

       // Devuelve el índice obtenido en SRRCW_CHAIN

       return lresul;

      }

 

 

      // Funciones tipo "get" para uso en VisualBasic

 

      String *CHAIND(String *sClav)

      {

       long lresul = 0;     // Control de resultados

       char cDato[32766];   // Paso de datos

       String *sDato = " "; // Valor de retorno

 

       // Convierte *String a *char haciéndolo accesible a SRRCW

       char *cClav = ALFACONV->sTOc(sClav); // Para convertir String* a char* se precisa codificación (Que veremos más adelante)

 

       // Emite el chain

       lresul = SRRCW_CHAIN(cClav, cDato);

       if (lresul <= 0) return sDato;

 

       // La conversión de *char a *String es directa

       sDato = cDato;

 

       // Devuelve el índice obtenido en SRRCW_CHAIN

       return sDato;

      }

 

 

      // Función tipo "get" con nombre explícito de fichero para uso en VisualBasic

 

      String *CHAINLFD(String *sLF, String *sClav)

      {

       long lresul = 0;     // Control de resultados

       char cDato[32766];   // Paso de datos

       String *sDato = " "; // Valor de retorno

 

       char *cLF = ALFACONV->sTOc(sLF);

       char *cClav = ALFACONV->sTOc(sClav);

 

       lresul = SRRCW_CHAIN(cLF, cClav, cDato);

       if (lresul <= 0) return sDato;

 

       sDato = cDato;

       return sDato;

      }

 

                                                                                                                                 ________


 

Una relación completa comentada de sus métodos se incluye en el anexo C dedicado a manuales de usuario, donde se presentan con ejemplos tomados del programa de muestra PruebasVbFile (Versión simplificada del progrma PruebasWfile citado antes) del que expone ahora una muestra

 

 

                                                                                                                                ________

 

 

B.II.2.5 La clase AlfaConv, núcleo de soporte de la clase vbFile

 

La clase vbFile que acabamos de introducir se apoya a su vez en la clase de conversión auxiliar AlfaConv, que es un mero interfaz de clases .Net del programa de servicio SRAlfaConv C++, de la misma manera en que lo es wFile respecto de SRRCW, y que exponemos ahora:

 

   // AlfaConv.h

 

   #pragma once

 

   #using <mscorlib.dll>

   using namespace System;

 

   #include "SRAlfaConv.h"

 

   namespace AlfaConv

   {

    public __gc class AlfaConv

    {

     // TODO: agregar aquí los métodos de la clase.

 

    public:

 

    AlfaConv()

    {

     return;

    }

 

    ~AlfaConv()

   {

    return;

   }

 

    long s2l(String *s) // Auxiliar conversión String* a long

    {

     return SRALFACONV_S2L(s);

    }

 

    char *sTOc(String *s) // Auxiliar conversión String* a char*

    {

     return SRALFACONV_STOC(s);

    }

 

   };

  }


                                                                                                                                 ________

 

 

B.II.2.6 Los servicios de SRAlfaConv, núcleo de soporte de la clase AlfaConv

 

 

A continuación se expone el código de los servicios de SRAlfaConv que utiliza la clase AlfaConv:

 

 

Primero se presenta SRAlfaConv.h

 

 

   // SRAlfaConv.h 

 

   // En esta cabecera se emplea un #define en lugar de 2 fuentes  

 

   // (El resultado es más compacto pero menos explícito, por eso tiende a usarse poco en esta obra) 

 

   #ifndef __SRALFACONV_H 

 

   #define __SRALFACONV_H 

   #ifndef __SRALFACONV__ 

   #define __SRALFACONV_S2L__ __declspec(dllimport) 

   #define __SRALFACONV_STOC__ __declspec(dllimport) 

   #else 

   #define __SRALFACONV_S2L__ __declspec(dllexport) 

   #define __SRALFACONV_STOC__ __declspec(dllexport) 

   #endif 

 

   __SRALFACONV_S2L__ long SRALFACONV_S2L(String *s); 

   __SRALFACONV_STOC__ char *SRALFACONV_STOC(String *s); 

 

   #endif                                                                                                                                 ________  

 

 

Ahora se muestra SRAlfaConv.cpp; para su mejor lectura, conviene empezar por los procedimientos externos del final

 

   // SRAlfaConv.cpp 

 

   #using <mscorlib.dll> 

   using namespace System; 

 

   #include <afx.h> 

   #include <stdexcept> 

 

   #define __SRALFACONV__ 

 

   #include "SRAlfaConv.h" 

 

 

   // Variables globales 

 

   static short int iMaximoSTOC =  99; // Máximo nºde instancias STOC distintas a la vez 

   static short int iContadorSTOC = 0; // Wk.paso entre STOC y salida 

 

 

   // Funciones internas 

   // Funciones auxiliares de salida de STOC, pensadas para ser invocadas  desde clases NET que no permiten el uso directo de memcpy 

 

   char *PrExitSTOC01(char *cEntrada, long ilong) 

   { 

    static char cSalida01[32767]; // Valor de retorno 

 

    memcpy(cSalida01, cEntrada, ilong+1); 

 

    return cSalida01; 

   } 

 

   char *PrExitSTOC02(char *cEntrada, long ilong) 

   { 

    static char cSalida02[32767]; // Valor de retorno 

 

    memcpy(cSalida02, cEntrada, ilong+1); 

 

    return cSalida02; 

   } 

 

   . . .  ( Y así hasta 99)

 

 

   char *PrExitSTOC(char *cEntrada, long ilong) 

  

    switch(iContadorSTOC) 

    { 

     case 1: 

      return PrExitSTOC01(cEntrada, ilong); 

 

     case 2: 

      return PrExitSTOC02(cEntrada, ilong); 

 

     . . . 

    

     case 99: 

      return PrExitSTOC99(cEntrada, ilong); 

   

  

    return PrExitSTOC100(cEntrada, ilong); 

   } 

 

 

   // Funciones externas 

 

 

   // Conversor de cadena *String a long 

 

   __SRALFACONV_S2L__ long SRALFACONV_S2L(String *s) 

  

    Int32 iW = 0; // Wk.Conversión 

    long  lW = 0; // Valor de retorno 

 

    // Convierte, eludiendo errores alfanuméricos 

  

    try 

    { 

     iW = Convert::ToInt32(s); 

    } 

    

    catch (System::FormatException *sys) 

    { 

     iW = 0; 

    } 

    

    catch (std::bad_exception bad) 

    

     iW = 0; 

    } 

 

    // Devuelve en el formato de salida 

    lW = iW; 

 

    return lW; 

   } 

 

 

   // Conversor de cedena *String a cadena *char  

 

   __SRALFACONV_STOC__ char *SRALFACONV_STOC(String *s) 

 

   char c;                 // Wk.1 ítem de retorno 

   char c1[32767];         // Wk.de paso 1 

   char c2[32767];         // Wk.de paso 2 

   char c3[32767];         // Wk.de paso 3 

   char cw[32];            // Wk.de paso aux 

   static char cs[32767];  // Valor de retorno 

   static int cont = 0;    // Contador de procesos 

   int i = 0;              // Contador de for 

 

 

   // Inicialización 

 

   int ilong = s->Length;  // Longitud String s recibida 

   String __pin *sW = s;   // Valor “fijado” auxiliar de s “dinámico” recibido 

 

 

   // Copia String (en formato “fijado”) a variable de trabajo c1, colocando terminador 

 

   memcpy(c1, reinterpret_cast<const void *>( sW ), 13 + 2*ilong); 

   memset(c1+2*ilong+13, '\x00', 1); 

 

 

   // Copia a variable de trabajo c2 

 

   memcpy(c2, c1 + 12, 2*ilong+1); 

 

 

   // Extrae a variable de trabajo c3 carácter a carácter 

 

   for (i=0;i<ilong;++i) 

   { 

    memcpy(cw, c2 + 2*i, 32); 

    c = cw[0]; 

    memset(c3+i, c, 1); 

   } 

 

   memset(c3+ilong, '\x00', 1); 

 

 

   // Vuelca a variable de retorno y termina proceso 

  

   memcpy(cs, c3, ilong+1); 

 

 

   // Para utilizar en cada invocación un ítem distinto, progresa el contador en un bucle de hasta iMaximoSTOC distintos, que luego se van

   // reutilizando (iMaximoSTOC esta sobredimensionado para responder con holgura en la práctica) 

 

   ++cont; 

   if (cont >= iMaximoSTOC) cont = 1; 

 

   iContadorSTOC = cont; 

 

   return PrExitSTOC(cs, ilong); 

 

                                                                                                                                ________

 

 

B.II.2.7 Notas para el enlace de compilación de AlfaConv con SRAlfaConv

 

Aunque este sea el párrafo más corto del capítulo, no deja de tener su importancia porque si no se tienen en cuenta las notas siguientes el sistema simplemente no funcionará:

 

- SRAlfaConv debe construirse como DLL de tipo NO MFC.

 

- Además, para que AlfaConv la reconozca, debe utilizarse la pestaña de dependencias adicionales.



                                                                                                                                ________