utiles_v2017/Fdbf.cpp

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;
}
//*****************************************************************************************