553 lines
12 KiB
C++
553 lines
12 KiB
C++
#include "StdAfx.h"
|
|
#include "Fdbf.h"
|
|
//*****************************************************************************************
|
|
Fdbf::Fdbf(void)
|
|
{
|
|
}
|
|
//*****************************************************************************************
|
|
Fdbf::~Fdbf(void)
|
|
{
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::lee( Cb_file *file)
|
|
{
|
|
int ncol;
|
|
colm.n =0;
|
|
iniCol.n =0;
|
|
buf.n=0;
|
|
if(!file->lee(&head, sizeof(head)))
|
|
return false;
|
|
ncol = (head.nb_cab - sizeof(Hdr_dbf) - 1) / sizeof(Fld_dbf);
|
|
if(ncol<=0)
|
|
return false;
|
|
if(!(colm+=ncol))
|
|
return false;
|
|
if(!(iniCol+=ncol))
|
|
return false;
|
|
colm.n = ncol;
|
|
iniCol.n = ncol;
|
|
//pilla info de campos-----------------------
|
|
if(!file->lee(&colm[0], sizeof(Fld_dbf)*colm.n))
|
|
return false;
|
|
int aux =1;
|
|
for(int i =0; i<colm.n; i++)
|
|
{
|
|
iniCol[i]=aux;
|
|
aux+=colm[i].nb;
|
|
}
|
|
//lee reserva
|
|
if(!file->lee(&ncol, 1))
|
|
return false;
|
|
if(!(buf+=head.nb_rec))
|
|
return false;
|
|
buf.n = head.nb_rec;
|
|
f= file;
|
|
nReadRow =0;
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::leeNexRow()//devuelve 1 si ok 0 si no mas -1 si error
|
|
{
|
|
if(nReadRow>=head.nrec)
|
|
return 0;
|
|
if(!f->lee(&buf[0], head.nb_rec))
|
|
return -1;
|
|
nReadRow++;
|
|
return 1;
|
|
}
|
|
//*****************************************************************************************
|
|
char* Fdbf::getName(int ncol)
|
|
{
|
|
if(ncol>=colm.n)
|
|
return 0;
|
|
return colm[ncol].nombre;
|
|
}
|
|
//*****************************************************************************************
|
|
BYTE Fdbf::getType(int ncol)
|
|
{
|
|
if(ncol>=colm.n)
|
|
return 0;
|
|
return colm[ncol].tipo;
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::getSize(int ncol)
|
|
{
|
|
if(ncol>=colm.n)
|
|
return 0;
|
|
return (int)colm[ncol].nb;
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::getNrow()
|
|
{
|
|
return head.nrec;
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::getNcolm()
|
|
{
|
|
return colm.n;
|
|
}
|
|
//*****************************************************************************************
|
|
char* Fdbf::get(int ncol)
|
|
{
|
|
if(ncol>=colm.n)
|
|
return 0;
|
|
//if(!f->lee(&buf[0], head.nb_rec))
|
|
// return NULL;
|
|
return &buf[iniCol[ncol]];
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::bufMem(int ncol)
|
|
{
|
|
char*d = get(ncol);
|
|
int nb = colm[ncol].nb+1;
|
|
if(buf2.m<nb)
|
|
{
|
|
buf2.n=0;
|
|
if(!(buf2+=nb))
|
|
return false;
|
|
}
|
|
buf2.n = nb;
|
|
char *s=&buf2[0];
|
|
memcpy(s,d,nb-1);
|
|
buf2[nb-1] = 0;
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
double Fdbf::getD(int col)
|
|
{
|
|
if(!bufMem(col))
|
|
return 0;
|
|
char *str=&buf2[0];
|
|
/*double k;
|
|
if ((*camp)[ic].tipo == 6)
|
|
{
|
|
sscanf(str,"%x",&k);
|
|
return(k);
|
|
}
|
|
else if ((*camp)[ic].tipo == 7)
|
|
{
|
|
str[2] = 0;
|
|
str[5] = 0;
|
|
k = atol(str) * 3600;
|
|
k = atol(&str[3]) * 60 + k;
|
|
k = atol(&str[6]) + k;
|
|
return(k);
|
|
}*/
|
|
return(atof(&buf2[0]));
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::getI(int col)
|
|
{
|
|
return (int)getD(col);
|
|
}
|
|
//*****************************************************************************************
|
|
char* Fdbf::getStr(int col)
|
|
{
|
|
if(!bufMem(col))
|
|
return 0;
|
|
char *str=&buf2[0];
|
|
char*s=&buf2[buf2.n-1];
|
|
while((*s == ' ' || *s==0) && s!=str)
|
|
{
|
|
*s = 0;
|
|
s--;
|
|
}
|
|
|
|
return str;
|
|
}
|
|
//*****************************************************************************************
|
|
__int64 Fdbf::getI64(int col)
|
|
{
|
|
if(!bufMem(col))
|
|
return 0;
|
|
char *str=&buf2[0];
|
|
int dd,mm,aa;
|
|
dd = atol(&str[6]);
|
|
str[6] = 0;
|
|
mm = atol(&str[4]);
|
|
str[4] = 0;
|
|
aa = atol(str);
|
|
|
|
try
|
|
{
|
|
CTime tt;
|
|
if (aa == 0 || mm == 0 || dd == 0)
|
|
tt = CTime::GetCurrentTime();
|
|
else
|
|
{
|
|
CTime t2(aa, mm, dd, 0, 0, 0, -1);
|
|
tt = t2;
|
|
}
|
|
return(tt.GetTime());
|
|
}
|
|
catch (...)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::set(int ncol, int nRow, Cb_file *file)
|
|
{
|
|
f = file;
|
|
colm.n =0;
|
|
nReadRow =-1;
|
|
if(!(colm+=ncol))
|
|
return false;
|
|
iniCol.n =0;
|
|
if(!(iniCol+=ncol))
|
|
return false;
|
|
memset(&head,0,sizeof(Hdr_dbf));
|
|
|
|
CTime tt = CTime::GetCurrentTime();
|
|
colm.n = ncol;
|
|
iniCol.n = ncol;
|
|
head.ver =3;
|
|
head.dia=(BYTE)tt.GetDay();
|
|
head.mes=(BYTE)tt.GetMonth();
|
|
head.dia=(BYTE)(tt.GetYear() - 1900);
|
|
head.nrec=nRow;
|
|
head.nb_cab = (short) (ncol * sizeof(Fld_dbf) + 1 + sizeof(Hdr_dbf));
|
|
if(!f->escribe(&head, sizeof(head)))
|
|
return false;
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::setCol(int icol, char *name, BYTE type, int size, int ndecimals)
|
|
{
|
|
if(icol<0 || icol>colm.n)
|
|
return false;
|
|
nReadRow =-1;
|
|
int i =0;
|
|
//copia de nombre segura--------
|
|
for(; i<11; i++)
|
|
{
|
|
colm[icol].nombre[i]=name[i];
|
|
if(!name[i])
|
|
break;
|
|
}
|
|
colm[icol].nombre[i] =0;
|
|
//------------------------------
|
|
colm[icol].tipo = type;
|
|
colm[icol].nb = size;
|
|
colm[icol].nd = ndecimals;
|
|
|
|
switch(type)
|
|
{
|
|
case(DBF_TYPE_DATA_I64):
|
|
case(DBF_TYPE_DATA_STR):
|
|
case(DBF_TYPE_DATA_BIN):
|
|
case(DBF_TYPE_DATA_I):
|
|
colm[icol].nd =0;
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::iniciaRecords()
|
|
{
|
|
if(nReadRow>=0)
|
|
return true;
|
|
nReadRow =0;
|
|
int nb =1;
|
|
for(int i =0; i<colm.n; i++)
|
|
{
|
|
iniCol[i]=nb;
|
|
nb +=colm[i].nb;
|
|
}
|
|
buf.n =0;
|
|
if(!(buf+=nb))
|
|
return false;
|
|
buf.n =nb;
|
|
head.nb_rec = nb;
|
|
if(!f->irAini())
|
|
return false;
|
|
if(!f->escribe(&head, sizeof(head)))
|
|
return false;
|
|
//graba info------------------------
|
|
if(!f->escribe(&colm[0], sizeof(Fld_dbf)*colm.n))
|
|
return false;
|
|
//graba terminacion de head
|
|
char ff = 13;
|
|
if(! f->escribe(&ff, sizeof(ff)))
|
|
return false;
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::addVal(int icol, int v)
|
|
{
|
|
char st1[64];
|
|
if(!iniciaRecords())
|
|
return false;
|
|
buf2.n =0;
|
|
|
|
if(!(buf2+=(colm[icol].nb+1)))
|
|
return false;
|
|
buf2.n =colm[icol].nb+1;
|
|
|
|
sprintf(st1,"%%0%ldd",colm[icol].nb);
|
|
sprintf(&buf2[0],st1,v);
|
|
|
|
int n = (int)strlen(&buf2[0]);
|
|
if (n > colm[icol].nb)
|
|
n = colm[icol].nb;
|
|
//alinea a la derecha
|
|
char *st = &buf[iniCol[icol]];
|
|
memset(st,0x20, colm[icol].nb);
|
|
memcpy(st+colm[icol].nb-n,&buf2[0],n);
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::addVal(int icol, double v)
|
|
{
|
|
char st1[64];
|
|
if(!iniciaRecords())
|
|
return false;
|
|
buf2.n =0;
|
|
|
|
if(!(buf2+=colm[icol].nb))
|
|
return false;
|
|
buf2.n =colm[icol].nb;
|
|
|
|
sprintf(st1,"%%1.%ldlf",colm[icol].nd);
|
|
sprintf(&buf2[0],st1,v);
|
|
|
|
int n =(int) strlen(&buf2[0]);
|
|
if (n > colm[icol].nb)
|
|
n = colm[icol].nb;
|
|
//alinea a la derecha
|
|
char *st = &buf[iniCol[icol]];
|
|
memset(st,0x20, colm[icol].nb);
|
|
memcpy(st+colm[icol].nb-n,&buf2[0],n);
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::addVal(int icol, __int64 v)
|
|
{
|
|
char st1[32];
|
|
CTime tt(v);
|
|
|
|
if(!iniciaRecords())
|
|
return false;
|
|
|
|
buf2.n =0;
|
|
|
|
if(!(buf2+=colm[icol].nb))
|
|
return false;
|
|
buf2.n =colm[icol].nb;
|
|
|
|
strcpy(st1,tt.Format("%Y%m%d"));
|
|
|
|
sprintf(&buf2[0],st1,v);
|
|
|
|
int n =(int) strlen(&buf2[0]);
|
|
if (n > colm[icol].nb)
|
|
n = colm[icol].nb;
|
|
//alinea a la derecha
|
|
char *st = &buf[iniCol[icol]];
|
|
memset(st,0x20, colm[icol].nb);
|
|
memcpy(st+colm[icol].nb-n,&buf2[0],n);
|
|
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::finRow()
|
|
{
|
|
//comprueba maximo
|
|
if(nReadRow>= head.nrec)
|
|
return false;
|
|
nReadRow++;
|
|
buf[0]=' ';
|
|
//graba buffer en archivo
|
|
if(!f->escribe(&buf[0], buf.n))
|
|
return false;
|
|
//si es el final graba head
|
|
if(nReadRow>= head.nrec)
|
|
{
|
|
buf[0]=26;
|
|
if(!f->escribe(&buf[0], 1))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::addVal(int icol, char* v)
|
|
{
|
|
if(!iniciaRecords())
|
|
return false;
|
|
int i =0;
|
|
char *dt=&buf[iniCol[icol]];
|
|
double maxi = colm[icol].nb;
|
|
//copia de nombre segura--------
|
|
for(; i<maxi; i++)
|
|
{
|
|
dt[i]=v[i];
|
|
if(!v[i])
|
|
break;
|
|
}
|
|
dt[i] =0;
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
bool Fdbf::addVal(int icol, void* v)
|
|
{
|
|
if(!iniciaRecords())
|
|
return false;
|
|
memcpy(&buf[iniCol[icol]],v,colm[icol].nb);
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|
|
int Fdbf::findCol( char *name )
|
|
{
|
|
for(int i =0; i<colm.n;i++)
|
|
{
|
|
if(0==strcmp(colm[i].nombre,name))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
//*****************************************************************************************
|
|
bool ManagerDbf::leer(char* file, ListenerDbf_W* lr)
|
|
{
|
|
Cb_file f;
|
|
if(!f.abre(file,1,0,true))
|
|
return false;
|
|
|
|
return leer(&f,lr);
|
|
}
|
|
//*****************************************************************************************
|
|
bool ManagerDbf::leer(Cb_file* f, ListenerDbf_W* lr)
|
|
{
|
|
Fdbf dbf;
|
|
if(!dbf.lee(f))
|
|
return false;
|
|
int nrow = dbf.getNrow();
|
|
int ncolm = dbf.getNcolm();
|
|
if(!lr->DbfSet(nrow, ncolm))
|
|
return false;
|
|
//prepara las columnas---------------
|
|
for(int i =0; i<ncolm; i++)
|
|
{
|
|
if(!lr->DbfSetColm(dbf.getName(i),dbf.getType(i),dbf.getSize(i)))
|
|
return false;
|
|
}
|
|
//recorre las filas---------------
|
|
int error =dbf.leeNexRow();
|
|
while(error ==1)
|
|
{
|
|
//por cada fila recorre las columnas
|
|
for(int i =0; i<ncolm; i++)
|
|
{
|
|
bool res =false;
|
|
switch(dbf.getType(i))
|
|
{
|
|
case(DBF_TYPE_DATA_STR):
|
|
res =lr->DbfaddVal(i,dbf.getStr(i));
|
|
break;
|
|
case(DBF_TYPE_DATA_I64):
|
|
res =lr->DbfaddVal(i,dbf.getI64(i));
|
|
break;
|
|
case(DBF_TYPE_DATA_D):
|
|
res =lr->DbfaddVal(i,dbf.getD(i));
|
|
break;
|
|
case(DBF_TYPE_DATA_BOOL):
|
|
return false;
|
|
break;
|
|
case(DBF_TYPE_DATA_BIN):
|
|
res =lr->DbfaddVal(i,dbf.get(i));
|
|
break;
|
|
case(DBF_TYPE_DATA_I):
|
|
res =lr->DbfaddVal(i,dbf.getI(i));
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
if(!res)
|
|
return false;
|
|
}
|
|
if(!lr->DbfFinRow())
|
|
return false;
|
|
error =dbf.leeNexRow();
|
|
}
|
|
|
|
return error == 0 && lr->DbfFinRow();
|
|
|
|
}
|
|
//*****************************************************************************************
|
|
bool ManagerDbf::grabar(char* file, ListenerDbf_R* lw)
|
|
{
|
|
Cb_file f;
|
|
if(!f.abre(file,2,true))
|
|
return false;
|
|
return grabar(&f,lw);
|
|
}
|
|
//*****************************************************************************************
|
|
bool ManagerDbf::grabar(Cb_file* f, ListenerDbf_R* lw)
|
|
{
|
|
Fdbf dbf;
|
|
int nrow =-1;
|
|
int ncolm =-1;
|
|
char name[11];
|
|
BYTE type;
|
|
int size;
|
|
int nd;
|
|
if(!lw->DbfGet(&nrow, &ncolm) /*|| nrow<=0 || ncolm<=0*/)
|
|
return false;
|
|
if(!dbf.set(ncolm, nrow, f))
|
|
return false;
|
|
//prepara las columnas---------------
|
|
for(int i =0; i<ncolm; i++)
|
|
{
|
|
if(!lw->DbfGetColm(i,name,&type,&size,&nd))
|
|
return false;
|
|
if(!dbf.setCol(i,name,type,size,nd))
|
|
return false;
|
|
}
|
|
//recorre las filas---------------
|
|
char *cv;
|
|
void *vv;
|
|
double dv;
|
|
int iv;
|
|
__int64 i64v;
|
|
for(int j =0;j<nrow; j++)
|
|
{
|
|
//por cada fila recorre las columnas
|
|
for(int i =0; i<ncolm; i++)
|
|
{
|
|
bool res =false;
|
|
switch(dbf.getType(i))
|
|
{
|
|
case(DBF_TYPE_DATA_STR):
|
|
res =lw->DbfGetVal(j, i, &cv) && dbf.addVal(i,cv);
|
|
break;
|
|
case(DBF_TYPE_DATA_I64):
|
|
res =lw->DbfGetVal(j, i, &i64v) && dbf.addVal(i,i64v);
|
|
break;
|
|
case(DBF_TYPE_DATA_D):
|
|
res =lw->DbfGetVal(j, i, &dv) && dbf.addVal(i,dv);
|
|
break;
|
|
case(DBF_TYPE_DATA_BOOL):
|
|
return false;
|
|
break;
|
|
case(DBF_TYPE_DATA_BIN):
|
|
res =lw->DbfGetVal(j, i, &vv) && dbf.addVal(i,vv);
|
|
break;
|
|
case(DBF_TYPE_DATA_I):
|
|
res = lw->DbfGetVal(j, i, &iv) && dbf.addVal(i,iv);
|
|
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
if(!res)
|
|
return false;
|
|
}
|
|
if(!lw->DbfFinW())
|
|
return false;
|
|
if(!dbf.finRow())
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
//*****************************************************************************************
|