Hallo,
bei der mplementierung des lesen und schreibens von dbase 7 dateien, stoße ich auf ein Problem.
uns zwar habe ich Probleme mit den TIME_FIELD - 2 longs das erste long ist für Datum BC das 2te long für Zeit:
MyXBase.cc:
dbf.h:
kann mir da einer helfen um dbase dateien zu lesen und zu schreiben?
danke schonmal
bei der mplementierung des lesen und schreibens von dbase 7 dateien, stoße ich auf ein Problem.
uns zwar habe ich Probleme mit den TIME_FIELD - 2 longs das erste long ist für Datum BC das 2te long für Zeit:
MyXBase.cc:
Code:
#include "all.h"
extern "C" void DisplayErrorMessage(int line,char *msg)
{
QMessageBox* msgBox = new QMessageBox();
msgBox->setWindowTitle("Programmfehler!");
msgBox->setText(QString("Error: %1: %2").arg(line).arg(msg));
msgBox->exec();
}
char *ChrMonth[] = { "christl. Monate",
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
0
};
char *leapstring[] = { "Gemeinjahr", "Schaltjahr", 0 };
class MyQDateStamp
{
public:
int tag, monat, jahr;
char* monstr, *leap;
public:
MyQDateStamp(int Tag, int Monat, char* MonStr, int Jahr, char* Leap)
{
tag = Tag;
monat = Monat;
monstr = MonStr;
jahr = Jahr;
leap = Leap;
}
void print(void)
{
cout << tag << " / " << monstr << " / " << jahr << " (" << leap << ")" << endl;
}
};
int SchaltJul(int y) { return y % 4 == 0 ? 1 : 0; }
int getDayJul(int d, int m, int y)
{
int x;
m -= 3;
if (m < 0) {
m += 12;
y--;
}
x = floor(y*365.25) + floor(m*30.6 + 0.5) + d + 1721117;
return x;
}
int getDay(int d, int m, int y)
{
return getDayJul(d,m,y);
}
MyQDateStamp* makeDateJul(int jd)
{
int tz = jd - 1721117;
int y = floor((tz-0.2) / 365.25);
int r = tz - floor(y * 365.25);
int m = floor((r - 0.5) / 30.6);
int d = r - floor(m * 30.6 + 0.5);
m += 3;
if(m > 12) {
m-= 12;
y++;
}
char *ms = ChrMonth[m];
int s = SchaltJul(y);
char * l = leapstring[s];
MyQDateStamp *x = new MyQDateStamp(d, m, ms, y, l);
return x;
}
MyQDateStamp* makeDate(int jd)
{
return makeDateJul(jd);
}
void save_all_browsers(QList<MyQDataBrowser*> ptr)
{
cout << "write data ..." << endl;
ptr[0]->workArea->dbf_write_header();
}
void xbase_add_path(QString str)
{
mydata::data_paths << str;
}
void xbase_select(int w)
{
if (w <= 0)
{
if ((mydata::wa.count() <= 0))
{
print_console("Fehler: keine Tabellen offen.");
return;
}
w = 1;
}
mydata::MyQCurrentWorkArea = w;
}
int xbase_count_records(QString field, QString filter)
{
if (mydata::MyQCurrentWorkArea <= 0)
{
print_console("Fehler: Es ist keine Tabelle geöffnet.");
exit(1);
}
int i, cnt = 0 ;
for (i = 0; i < mydata::wa.at(mydata::MyQCurrentWorkArea-1)->content[field].count(); i++)
{
if (mydata::wa.at(mydata::MyQCurrentWorkArea-1)->content[field].at(i).value_text.trimmed() == filter.trimmed())
++cnt;
}
if (cnt <= 0) {
print_console("Warnung: Datenbankfeld \"" + field + "\"nicht gefunden.");
return -1;
}
mydata::wa.at(
mydata::MyQCurrentWorkArea-1)->record_count = cnt;
return cnt;
}
QString xbase_open_dbf(QString str)
{
QString dbf;
if (!str.endsWith(".dbf"))
str = str + QString(".dbf");
if (!mydata::data_paths.contains(QCoreApplication::applicationDirPath())) {
mydata::data_paths << QCoreApplication::applicationDirPath() + "/";
mydata::data_paths << QCoreApplication::applicationDirPath() + "/data/";
}
int i;
FILE *data = NULL;
bool found = false;
for (i = 0; i < mydata::data_paths.count(); i++)
{
if (found == true) break;
dbf = QString(mydata::data_paths.at(i) + str);
if ((data = fopen(QString(dbf).toStdString().c_str(),"rb")) != NULL)
{
fclose(data);
found = true;
}
}
if (found == false) {
str = str + QString(" not found"); } else {
str = str + QString(" was found"); }
print_console(str);
MyQWorkArea *WA = new MyQWorkArea(dbf);
mydata::wa.append(WA);
if (mydata::MyQCurrentWorkArea <= 0)
mydata::MyQCurrentWorkArea = mydata::wa.count();
return dbf;
}
MyQWorkArea::MyQWorkArea(QString dbf)
{
this->dbFile = dbf;
mydata::data_paths << QCoreApplication::applicationDirPath();
mydata::data_paths << QCoreApplication::applicationDirPath() + "/data";
if ((dbHandle = open(dbf.toStdString().c_str(), O_RDONLY)) == -1) {
msgbox("Fehler",QString("Kann Datei: %1\nnicht öffnen").arg(dbf));
return;
}
db = &db_buf;
dbf_read_header();
dbf_read_fields();
}
void MyQWorkArea::dbf_read_header(void)
{
if ((read(dbHandle, (char *)db, sizeof(struct DB_HEADER))) == -1 ) {
msgbox("Fehler!","kann dbf Header nicht lesen.");
return;
}
this->dbVersion = db->version;
this->header_length = rotate2b(db->header_length) / 32;
this->record_length = rotate2b(db->record_length);
}
void MyQWorkArea::dbf_write_header(void)
{
FILE *h;
int r,c;
if (!(h = fopen("./data/test.dbf","wb"))) {
msgbox("Fehler!", "kann Datenbankdatei nicht schreibend offnen.");
return;
}
if ((fwrite(db,1,sizeof(struct DB_HEADER),h)) == -1) {
msgbox("Fehler!", "kann dbf Header nicht schreiben.");
return;
}
for (r = 0; r < map_head.count(); r++)
{
if((fwrite(header[r],1,sizeof(struct DB_FIELD),h)) == -1) {
msgbox("Fehler","kann Felddaten nicht schreiben.");
return;
}
}
char d = 0x0d;
fwrite(&d,1,1,h);
for (r = 0; r < db->records; r++)
{
d = 0x20;
fwrite(&d,1,1,h); // delete flag
for (c = 0; c < map_field.count(); c++)
{
int pad = map_field[map_head[ c]].length;
int ft = header[ c]->field_type;
if (ft == FIELD_CHAR)
{
content[map_head[ c]][r].value_text.resize(
header[ c]->length_binary);
printf("write_char: >%s<\n",
content[map_head[ c]][r].value_text.toStdString().c_str());
fwrite(
content[map_head[ c]][r].value_text.toStdString().c_str(),
1,header[ c]->length_binary,h);
}
else if (ft == FIELD_NUMERIC)
{
content[map_head[ c]][r].value_text.toStdString().insert(0, pad -
content[map_head[ c]][r].value_text.size(), ' ');
fwrite(
content[map_head[ c]][r].value_text.toStdString().c_str(),1,strlen(
content[map_head[ c]][r].value_text.toStdString().c_str() ),h);
}
else if (ft == FIELD_LOGIC)
{
fwrite(
content[map_head[ c]][r].value_text.toStdString().c_str(),1,1,h);
}
else if (ft == FIELD_DATE)
{
QString str = content[map_head[ c]][r].value_text;
QChar * data = str.data();
QString year4 = QString(data[9]);
QString year3 = QString(data[8]);
QString year2 = QString(data[7]);
QString year1 = QString(data[6]);
QString month2 = QString(data[4]);
QString month1 = QString(data[3]);
QString day2 = QString(data[1]);
QString day1 = QString(data[0]);
str = QString(
year1 + year2 +
year3 + year4 +
month1 + month2 +
day1 + day2 );
fwrite(
str.toStdString().c_str(),1,strlen(
str.toStdString().c_str() ),h);
}
else if (ft == FIELD_TIME)
{
QString ts = content[map_head[ c]][r].value_text;
int d1,m1,y1,h2,m2,s2;
sscanf(ts.toStdString().c_str(),
"%02d.%02d.%4d %02d:%02d:%02d",
&d1,&m1,&y1,
&h2,&m2,&s2);
h2 = h2 * 3600000;
m2 = m2 * 60000;
s2 = s2 * 1000;
long int t2 = h2 + m2 + s2;
long int p2 = getDay(d1,m1,y1);
cout << "dtest: " << p2 << endl;
fwrite(&p2,1,sizeof(long int),h); // date
fwrite(&t2,1,sizeof(long int),h); // time
}
}
}
d = 0x1a; // file end mark
fwrite(&d,1,1,h);
fclose(h);
}
void MyQWorkArea::dbf_read_fields(void)
{
struct DB_FIELD *hdr;
unsigned char *record;
int a,k=0;
for (a = 0; a < 127; a++)
header[a] = (struct DB_FIELD*) malloc(sizeof(struct DB_FIELD) * header_length);
if (header[k] == NULL) {
msgbox("Fehler","kann kein Speicher anfordern.");
return;
}
char c[1];
int h = 1;
lseek(dbHandle, header_length, SEEK_SET);
int pos = 0;
while (1)
{
read(dbHandle,c,1);
if (c[0] == 0x0d) break;
pos++;
}
int psize = pos / sizeof(struct DB_FIELD);
h = --psize;
lseek(dbHandle, 0, SEEK_SET);
dbf_read_header();
//print_console(QString("\n::> %1, %2").arg(pos).arg(psize));
pos = 0;
for (hdr = header[k] + 1; --header_length; hdr++, k++)
{
if (psize-- < 1) break;
if((read(dbHandle, header[k], sizeof(struct DB_FIELD))) == -1) {
msgbox("Fehler","kann Feld nicht einlesen.");
return;
}
//print_console(QString("--> %1").arg(int(header->field_type)));
Node nfield;
nfield.name = new char[strlen((char*)header[k]->field_name)+1];
strcpy(nfield.name,(char*)header[k]->field_name);
nfield.type = header[k]->field_type;
nfield.length = header[k]->length_binary;
nfield.prec = header[k]->dec_count_binary;
map_field.insert(QString((char*)header[k]->field_name), nfield);
map_head .insert(pos++, QString((char*)header[k]->field_name));
}
if ((record = (unsigned char*) malloc(record_length + 1)) == NULL) {
perror("malloc");
exit(1);
}
record[record_length] = '\0';
char *flag_byte;
lseek(dbHandle, rotate2b(db->header_length), SEEK_SET);
MyQMemoryTable mt;
QVector<class MyQMemoryTable> memtab[200];
int f; char dflag;
int l1 = 0;
for (int i = 0; i < db->records; i++)
{
read(dbHandle, &dflag, 1);
for (f = 0; f < map_field.count(); f++)
{
mt.value_type = map_field[map_head[f]].type;
if (mt.value_type == FIELD_NUMERIC || mt.value_type == FIELD_CHAR)
{
char buffer[2048];
read(dbHandle,buffer,header[f]->length_binary);
map_field[map_head[f]].value = QString(buffer);
map_field[map_head[f]].value.resize(header[f]->length_binary);
mt.value_text = QString(buffer);
mt.value_text.resize(header[f]->length_binary);
memtab[f].append(mt);
content.insert(map_head[f],memtab[f]);
continue;
}
else if (mt.value_type == FIELD_LOGIC)
{
char l;
read(dbHandle,&l,1);
map_field[map_head[f]].value = QString(QChar(l));
mt.value_text = QString(QChar(l));
memtab[f].append(mt);
content.insert(map_head[f],memtab[f]);
continue;
}
else if (mt.value_type == FIELD_TIME)
{
long int tim;
long int dat;
read(dbHandle,&dat,sizeof(long int));
read(dbHandle,&tim,sizeof(long int));
cout << "data: " << dat << endl;
int r2;
int h2 = tim / 3600000;
r2 = tim % 3600000;
int m2 = r2 / 60000;
r2 = r2 % 60000;
int s2 = r2 / 1000;
cout << int(dat) << endl;
MyQDateStamp *datstamp;
datstamp=makeDate(dat);
datstamp->print();
char buffer[200];
sprintf(buffer,
"%02d.%02d.%d %02d:%02d:%02d",
datstamp->tag,
datstamp->monat,
datstamp->jahr,
h2,m2,s2);
cout << ":::>> " << buffer << endl;
mt.value_text = QString(buffer);
memtab[f].append(mt);
content.insert(map_head[f],memtab[f]);
}
else if (mt.value_type == FIELD_DATE)
{
char buffer[2048];
read(dbHandle,buffer,header[f]->length_binary);
QString year = QString(buffer).left(4);
QChar * data = QString(buffer).data();
QString month1 = QString(data[4]);
QString month2 = QString(data[5]);
QString day1 = QString(data[6]);
QString day2 = QString(data[7]);
QString str = QString(
day1 + day2 + "." +
month1 + month2 + "." + year);
map_field[map_head[f]].value = str;
mt.value_text = str;
memtab[f].append(mt);
content.insert(map_head[f],memtab[f]);
continue;
}
}
}
//free(record);
}
void xbase_print_field(QString field)
{
MyQWorkArea *wa = mydata::wa.at(0);
print_console(wa->dbFile);
print_console(wa->record_length);
print_console(field);
//print_console(wa->content["name"].at(0).value_text);
}
void MyQMemoryTable::setText(QString str)
{
value_text = str;
}
dbf.h:
Code:
#ifndef __DBF_H__
#define __DBF_H__
#include "all.h"
#define dBase3 0x03
#define dBase3WM 0x83
#define dBase4 0x04
#define dBase4WM 0x8B
#define dBase5 0x05
#define dBase7 0x07
#define FIELD_CHAR 0x43
#define FIELD_NUMERIC 0x4e
#define FIELD_LOGIC 0x4c
#define FIELD_DATE 0x44
#define FIELD_TIME '@'
struct DB_HEADER {
unsigned char version;
unsigned char last_update[3];
unsigned int records;
unsigned short header_length;
unsigned short record_length;
unsigned char reserved01[2];
unsigned char transaction;
unsigned char encryption;
unsigned char reserved02[12];
unsigned char mdx;
unsigned char language;
unsigned char reserved03[2];
unsigned char driver_name[32];
unsigned char reserved04[4];
};
struct DB_FIELD {
unsigned char field_name[32];
unsigned char field_type;
unsigned char length_binary;
unsigned char dec_count_binary;
unsigned char reserved1[2];
unsigned char mdx;
unsigned char reserved2[2];
unsigned long next_auto_inc;
unsigned long reserved3;
};
#endif
kann mir da einer helfen um dbase dateien zu lesen und zu schreiben?
danke schonmal