735 lines
30 KiB
C++
735 lines
30 KiB
C++
#include <io.h>
|
||
#include <mem.h>
|
||
#include <alloc.h>
|
||
#include <string.h>
|
||
|
||
#define __BDatos_CPP
|
||
#include "d:\program\src_dos\libs\bdatos\BDatos.hh"
|
||
|
||
|
||
// ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
#define PROG_NAME "BDatos::JD::"
|
||
// ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
#define VER_HI 1
|
||
#define VER_LOW 0
|
||
#define ARCH_LEN 12
|
||
|
||
#define FALSO 0
|
||
#define CIERTO 1
|
||
|
||
typedef struct
|
||
{
|
||
char code;
|
||
long pos;
|
||
} BTree;
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| Contructor de Clase |
|
||
| |
|
||
| Descripcion: |
|
||
| Se encarga de poner a cero todas las variables utilizadas |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguna) |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
\**************************************************************************/
|
||
BDatos::BDatos()
|
||
{
|
||
BDatosHeader.NRegistros = 0;
|
||
BDatosHeader.NRegTotal = 0;
|
||
BDatosHeader.SizeReg = 0;
|
||
BDatosHeader.VerHi = VER_HI;
|
||
BDatosHeader.VerLow = VER_LOW;
|
||
BDatosHeader.Eof_Code = 26;
|
||
|
||
strcpy( BDatosHeader.NBD, "BDatos::JD::" );
|
||
|
||
memset( BDatosHeader.MyHeader.ProgName, 32, sizeof(char)* 15 );
|
||
BDatosHeader.MyHeader.VerHi = 0;
|
||
BDatosHeader.MyHeader.VerLow = 0;
|
||
|
||
memset( BDatosHeader.MyHeader.Other, 32, sizeof(char)*200 );
|
||
|
||
NRegActual = 0;
|
||
lError = 0x00;
|
||
*cError = 0x00;
|
||
rError = ERROR;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| Destructor de clase |
|
||
| |
|
||
| Descripcion: |
|
||
| Finaliza las operaciones pendientes. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguno) |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
| |
|
||
\**************************************************************************/
|
||
BDatos::~BDatos()
|
||
{
|
||
if ( rError == ERROR ) return;
|
||
fclose( handle_BDatos );
|
||
}
|
||
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| Registros |
|
||
| |
|
||
| Descripcion: |
|
||
| Obtiene el n£mero de registros total de la base de datos. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguna) |
|
||
| |
|
||
| Salidas: numero de registros |
|
||
| |
|
||
\**************************************************************************/
|
||
long BDatos::Registros(void)
|
||
{
|
||
return BDatosHeader.NRegistros;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| NRegTotal |
|
||
| |
|
||
| Descripcion: |
|
||
| Obtiene el n£mero de registros total, total del la base. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguna) |
|
||
| |
|
||
| Salidas: numero de registros |
|
||
| |
|
||
\**************************************************************************/
|
||
long BDatos::NRegTotal(void)
|
||
{
|
||
return BDatosHeader.NRegTotal;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| RegActual |
|
||
| |
|
||
| Descripcion: |
|
||
| Obtiene el n£mero de registro actual. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguna) |
|
||
| |
|
||
| Salidas: numero de registro en tratamiento |
|
||
| |
|
||
\**************************************************************************/
|
||
long BDatos::RegActual(void)
|
||
{
|
||
return NRegActual;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| AbrirReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Abre los ficheros indices y datos. |
|
||
| |
|
||
| |
|
||
| Entradas: nombre fichero "sin comodines" |
|
||
| longitud de un registro "en bytes" |
|
||
| |
|
||
| Salidas: OK ( todo va bien ) |
|
||
| ERROR ( error ) |
|
||
| |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::AbrirReg(char *file, long sizereg)
|
||
{
|
||
// char bdatos[ARCH_LEN];
|
||
char *bdatos;
|
||
|
||
bdatos = file;
|
||
|
||
BDatosHeader.MyHeader = MyHeader;
|
||
|
||
Header NewHeader = BDatosHeader;
|
||
|
||
rError = OK;
|
||
|
||
strncpy( bdatos, file, ARCH_LEN );
|
||
|
||
if ( (handle_BDatos = fopen( bdatos, "r+b" ) ) == NULL )
|
||
{
|
||
// Inicializamos una nueva base de datos
|
||
if ( (handle_BDatos = fopen( bdatos, "w" ) ) == NULL )
|
||
{
|
||
lError = 0x01; ObtenError( lError );
|
||
return (rError = ERROR);
|
||
}
|
||
|
||
rewind( handle_BDatos );
|
||
BDatosHeader.SizeReg = sizereg;
|
||
fwrite( &BDatosHeader, sizeof( BDatosHeader ), 1, handle_BDatos );
|
||
|
||
fclose( handle_BDatos );
|
||
|
||
if ( (handle_BDatos = fopen( bdatos, "r+b" ) ) == NULL )
|
||
{
|
||
lError = 0x01; ObtenError( lError );
|
||
return (rError = ERROR);
|
||
}
|
||
} else {
|
||
|
||
rewind( handle_BDatos );
|
||
fread( &BDatosHeader, sizeof(BDatosHeader), 1, handle_BDatos);
|
||
|
||
if ( BDatosHeader.SizeReg != sizereg || BDatosHeader.VerHi != NewHeader.VerHi )
|
||
{
|
||
lError = 0x03; ObtenError( lError );
|
||
fclose( handle_BDatos );
|
||
return (rError = ERROR);
|
||
}
|
||
}
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| CerrarReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Cierra la base de datos. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguno) |
|
||
| |
|
||
| Salidas: OK ( todo va bien ) |
|
||
| ERROR ( error ) |
|
||
| |
|
||
\**************************************************************************/
|
||
void BDatos::CerrarReg( void )
|
||
{
|
||
if ( rError == ERROR ) return;
|
||
fclose( handle_BDatos );
|
||
rError = ERROR;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| LeeReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Lee el registro de la posici¢n 'pos' y lo almacena en 'dato' |
|
||
| |
|
||
| |
|
||
| Entradas: puntero a los datos |
|
||
| posicion a leer |
|
||
| |
|
||
| Salidas: OK ( todo va bien ) |
|
||
| ERROR ( error ) |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::LeeReg( void *dato, long pos )
|
||
{
|
||
BTree inx;
|
||
|
||
if ( rError == ERROR )
|
||
{
|
||
lError = 0x05; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
if ( pos > BDatosHeader.NRegistros || pos < 0 )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
NRegActual = pos;
|
||
fseek( handle_BDatos, (long)( pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
if ( inx.pos < 0 || inx.code != ' ' )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
fseek( handle_BDatos, (long)( inx.pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
|
||
fread ( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| EscribeReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Escribe el registro en la posici¢n 'pos' de 'dato' |
|
||
| |
|
||
| |
|
||
| Entradas: puntero a los datos |
|
||
| posicion a escribir |
|
||
| |
|
||
| Salidas: OK ( todo va bien ) |
|
||
| ERROR ( error ) |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::EscribeReg( void *dato, long pos )
|
||
{
|
||
BTree inx;
|
||
|
||
if ( rError == ERROR )
|
||
{
|
||
lError = 0x05; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
if ( pos > BDatosHeader.NRegistros || pos < 0 )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
NRegActual = pos;
|
||
fseek( handle_BDatos, (long)( pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
if ( inx.pos < 0 || inx.code != ' ' )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
fseek( handle_BDatos, (long)( inx.pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
|
||
fwrite( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| InsReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Inserta un registro, en la posici¢n 'pos' por arriba o abajo |
|
||
| |
|
||
| |
|
||
| Entradas: puntero a los datos a insertar, posici¢n, ARRIBA o ABAJO |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::InsReg( void *dato, long pos, char ab )
|
||
{
|
||
BTree inx, old_inx;
|
||
unsigned long avance;
|
||
long RegTot;
|
||
|
||
if ( rError == ERROR )
|
||
{
|
||
lError = 0x05; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
// Filtro los datos conflictivos
|
||
if ( pos == 0 && BDatosHeader.NRegistros == 1 && ab == ARRIBA )
|
||
{
|
||
pos = 1;
|
||
} else
|
||
if ( pos == (BDatosHeader.NRegistros - 1) && ab == ARRIBA )
|
||
{
|
||
pos = BDatosHeader.NRegistros;
|
||
}
|
||
|
||
BDatosHeader.NRegistros++;
|
||
if ( pos > (BDatosHeader.NRegistros-1) || pos < 0 )
|
||
// if ( pos >= (BDatosHeader.NRegistros-1) && BDatosHeader.NRegistros!=1 )
|
||
{
|
||
BDatosHeader.NRegistros--;
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
// Si hay fichas eliminadas, utilizamos sus direcciones intermedias.
|
||
if ( (BDatosHeader.NRegTotal - ( BDatosHeader.NRegistros - 1 ) ) > 0 )
|
||
{
|
||
fseek( handle_BDatos, (long)( ( BDatosHeader.NRegistros - 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &old_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
} else {
|
||
old_inx.pos = ( BDatosHeader.NRegistros - 1 );
|
||
BDatosHeader.NRegTotal++;
|
||
}
|
||
|
||
// |<---------- RegTot ----------->|
|
||
// |<----- NRegistros ---->| |
|
||
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
|
||
// ³ 1 ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ * ³ ³ ³ ³ ³ ³
|
||
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
//
|
||
// 2 up Âpos+1
|
||
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
|
||
// ³ 1 ³ 2 ³ * ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ ³ ³ ³ ³ ³
|
||
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
// 2 down Âpos
|
||
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
|
||
// ³ 1 ³ * ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ ³ ³ ³ ³ ³
|
||
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
|
||
avance = ( BDatosHeader.NRegistros - 1 );
|
||
while ( avance > ( pos + ab ) )
|
||
{
|
||
fseek( handle_BDatos, (long)( ( avance - 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
fseek( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fwrite( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
avance--;
|
||
};
|
||
|
||
if ( ( BDatosHeader.NRegistros - 1 ) == 0 )
|
||
fseek( handle_BDatos, sizeof( Header ), SEEK_SET);
|
||
else {
|
||
ab = ( ( BDatosHeader.NRegistros - 1 ) <= ( pos + ab ) ) ? 0 : ab;
|
||
fseek( handle_BDatos, (long)( ( pos + ab ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
}
|
||
|
||
NRegActual = ( BDatosHeader.NRegistros - 1 ) == 0 ? 0 : pos + ab;
|
||
old_inx.code = ' ';
|
||
fwrite( &old_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
fseek( handle_BDatos, (long)( ( old_inx.pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
|
||
fwrite( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
|
||
|
||
rewind( handle_BDatos );
|
||
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
|
||
|
||
return OK;
|
||
|
||
}
|
||
|
||
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| DelReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Borra un registro, de la posici¢n 'pos' |
|
||
| |
|
||
| |
|
||
| Entradas: posici¢n a borrar |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::DelReg( long pos )
|
||
{
|
||
BTree inx, old_inx;
|
||
|
||
if ( rError == ERROR )
|
||
{
|
||
lError = 0x05; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
BDatosHeader.NRegistros--;
|
||
if ( pos > BDatosHeader.NRegistros || pos < 0)
|
||
{
|
||
BDatosHeader.NRegistros++;
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
fseek( handle_BDatos, (long)( ( pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &old_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
// |<---------- RegTot ----------->|
|
||
// |<----- NRegistros ---->| |
|
||
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
|
||
// ³ 1 ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ * ³ ³ ³ ³ ³ ³
|
||
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
//
|
||
|
||
unsigned long avance;
|
||
|
||
avance = pos;
|
||
while ( avance < BDatosHeader.NRegistros )
|
||
{
|
||
fseek ( handle_BDatos, (long)( ( avance + 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread ( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
fseek ( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fwrite( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
avance++;
|
||
};
|
||
|
||
NRegActual = BDatosHeader.NRegistros == 1 ? 0 : ( BDatosHeader.NRegistros - 1);
|
||
fseek( handle_BDatos, (long)( ( BDatosHeader.NRegistros ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
|
||
old_inx.code = '*';
|
||
fwrite( &old_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
rewind( handle_BDatos );
|
||
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| ShortReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Corta el fichero y lo hace mas peque¤o. |
|
||
| |
|
||
| |
|
||
| Entradas: (ninguna) |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::ShortReg(void)
|
||
{
|
||
long avance, recorrido;
|
||
BTree inx, curr_inx;
|
||
void *SWAPdatos;
|
||
char enc;
|
||
|
||
if ( ( BDatosHeader.NRegTotal - BDatosHeader.NRegistros ) <= 0 ) return OK;
|
||
|
||
if ( ( SWAPdatos = calloc( 1, BDatosHeader.SizeReg ) ) == NULL )
|
||
{
|
||
lError = 0x07; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
avance = BDatosHeader.NRegTotal-1;
|
||
while( avance >= BDatosHeader.NRegistros )
|
||
{
|
||
// Obtengo la direcci¢n del campo que est libre y el dato.
|
||
fseek( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
|
||
fread( SWAPdatos, BDatosHeader.SizeReg, 1, handle_BDatos );
|
||
|
||
// Busco la direcci¢n del indice para la ficha actual.
|
||
recorrido = avance; enc = FALSO;
|
||
while( recorrido >= 0 && !enc )
|
||
{
|
||
fseek( handle_BDatos, (long)( ( recorrido ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &curr_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
if ( curr_inx.pos == avance )
|
||
enc = CIERTO;
|
||
else
|
||
recorrido--;
|
||
}
|
||
|
||
// Si alguien de fuera referencia a esa ficha...
|
||
if ( enc )
|
||
{
|
||
curr_inx.pos = inx.pos;
|
||
//Actualizo el indice para comunicarle la nueva posici¢n.
|
||
fseek( handle_BDatos, (long)( ( recorrido ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fwrite( &curr_inx, sizeof( BTree ), 1, handle_BDatos );
|
||
// Pongo la ficha actual en la direcci¢n libre.
|
||
fseek ( handle_BDatos, (long)( ( curr_inx.pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
|
||
fwrite( SWAPdatos, BDatosHeader.SizeReg, 1, handle_BDatos );
|
||
}
|
||
|
||
avance--;
|
||
|
||
};
|
||
|
||
// Actualizo la base de registros
|
||
NRegActual = BDatosHeader.NRegistros - 1;
|
||
BDatosHeader.NRegTotal = BDatosHeader.NRegistros;
|
||
rewind( handle_BDatos );
|
||
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
|
||
|
||
// Corto todo lo que sobra de fichero
|
||
if ( chsize( fileno(handle_BDatos), (long)(sizeof( Header ) + ( BDatosHeader.NRegistros * ( sizeof( BTree ) + BDatosHeader.SizeReg ) )) ) == -1 )
|
||
{
|
||
lError = 0x08; ObtenError( lError );
|
||
return OK; // Este error no es del todo grave, pero se avisa.
|
||
}
|
||
|
||
free( SWAPdatos );
|
||
return OK;
|
||
}
|
||
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| ObtenError |
|
||
| |
|
||
| Descripcion: |
|
||
| Obtiene el error correspondiente al codigo dado. |
|
||
| |
|
||
| |
|
||
| Entradas: codigo de error |
|
||
| |
|
||
| Salidas: (ninguna) |
|
||
| |
|
||
\**************************************************************************/
|
||
void BDatos::ObtenError( int code )
|
||
{
|
||
|
||
switch( code )
|
||
{
|
||
case 0x00:
|
||
strcpy( cError, "No hay errores" );
|
||
break;
|
||
case 0x01:
|
||
strcpy( cError, "Imposible inicializar base de datos" );
|
||
break;
|
||
case 0x02:
|
||
strcpy( cError, "No se puede abrir el fichero" );
|
||
break;
|
||
case 0x03:
|
||
strcpy( cError, "Version de fich. incompatible" );
|
||
break;
|
||
case 0x04:
|
||
strcpy( cError, "No se pudo acceder a esa posici¢n." );
|
||
break;
|
||
case 0x05:
|
||
strcpy( cError, "No hay base de datos en uso..." );
|
||
break;
|
||
case 0x06:
|
||
strcpy( cError, "Tama¤os de estructuras no coinciden" );
|
||
break;
|
||
case 0x07:
|
||
strcpy( cError, "Memoria insuficiente. Operaci¢n cancelada" );
|
||
break;
|
||
case 0x08:
|
||
strcpy( cError, "Acceso de operacion no permitida." );
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/**************************************************************************\
|
||
| |
|
||
| SortReg |
|
||
| |
|
||
| Descripcion: |
|
||
| Ordena la base de datos seg£n especifique el usuario en su |
|
||
| funci¢n fcmp... |
|
||
| |
|
||
| Entradas: /**************************************************************\ |
|
||
| | fcmp ||
|
||
| | ||
|
||
| | Descripcion: ||
|
||
| | funci¢n de entrada a SortReg, debe ser realizada ||
|
||
| | por el usuario y debe ce¤irse a sus par metros.. ||
|
||
| | ||
|
||
| | Entradas: ptrs. a dos estructuras de usuario. ( ejm. A, B ) ||
|
||
| | Salidas: >> 0 si A >> B ||
|
||
| | == 0 si A == B ||
|
||
| | << 0 si A << B ||
|
||
| \************************************************************** |
|
||
| |
|
||
| |
|
||
| |
|
||
| |
|
||
| Salidas: ERROR se cargan los registros con el codigo de error esp. |
|
||
| OK todo ha ido bien |
|
||
| |
|
||
\**************************************************************************/
|
||
int BDatos::SortReg( int (*fcmp)(const void *, const void *) )
|
||
{
|
||
char dev;
|
||
|
||
// Pido memoria para mantener dos elementos auxiliares
|
||
if (
|
||
( A = calloc( 1, BDatosHeader.SizeReg ) ) == NULL ||
|
||
( B = calloc( 1, BDatosHeader.SizeReg ) ) == NULL
|
||
)
|
||
{
|
||
lError = 0x07; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
dev = SortRegi( fcmp, 0, BDatosHeader.NRegistros-1 );
|
||
|
||
free(A); free(B);
|
||
|
||
return dev;
|
||
}
|
||
|
||
int BDatos::SortRegi( int (*fcmp)(const void *, const void *), long izquierda, long derecha )
|
||
{
|
||
BTree inx1, inx2;
|
||
register long i, j;
|
||
|
||
i = izquierda; j = derecha;
|
||
if ( LeeReg( A, (long)(izquierda+derecha)/2 + 1 ) != OK )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
|
||
do {
|
||
if ( LeeReg( B, i )!= OK )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
while( i < derecha && fcmp( B, A ) < 0 )
|
||
{
|
||
i++;
|
||
if ( LeeReg( B, i ) != OK )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
};
|
||
|
||
LeeReg( B, j );
|
||
while( j > izquierda && fcmp( A, B ) < 0 )
|
||
{
|
||
j--;
|
||
if ( LeeReg( B, j ) != OK )
|
||
{
|
||
lError = 0x04; ObtenError( lError );
|
||
return ERROR;
|
||
}
|
||
};
|
||
|
||
if ( i <= j )
|
||
{
|
||
// Intercambiamos solo los indices sin chequear si son
|
||
// accesibles, ( si no lo fueran, se abria abortado )
|
||
fseek( handle_BDatos, (long)( i * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx1, sizeof( BTree ), 1, handle_BDatos );
|
||
fseek( handle_BDatos, (long)( j * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fread( &inx2, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
fseek( handle_BDatos, (long)( j * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fwrite( &inx1, sizeof( BTree ), 1, handle_BDatos );
|
||
fseek( handle_BDatos, (long)( i * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
|
||
fwrite( &inx2, sizeof( BTree ), 1, handle_BDatos );
|
||
|
||
i++; j--;
|
||
}
|
||
|
||
} while( i <= j );
|
||
|
||
if ( izquierda < j ) SortRegi( fcmp, izquierda, j );
|
||
if ( i < derecha ) SortRegi( fcmp, i, derecha );
|
||
|
||
return OK;
|
||
}
|
||
|