TEST BEFORE USE - NO WARRANTY
/* DBF.C - Implementierung von DBF.H, Korrektum 2021 */
/* 1994, 2021 by Frank Werner, Public Domain */
#include <dos.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "dbf.h"
const char HEADERTERMINATOR = 0x0D;
const char FILETERMINATOR = 0x1A;
const char SPACE = 0x20;
const char DELETEDCHAR = 0x2A;
FILEHEADER Header;
FIELDDESCRIPTION Field [MAX_NUMFIELDS];
long ulNumFields;
int bEOF;
int bOkay;
DBFERR DBF_Init (void)
// Initialize DBF-Module, 06.12.1994/We
{
return (DBFERR_NO_ERROR);
}
DBFERR DBF_CallError (long ulLine, long ulCode, char * pszErrMsg)
// Ausgabe der übergebenen Fehlermeldung, 07.06.1993/We
{
char Buffer [80];
sprintf (Buffer, "%s (Zeile %d, Code %x)", pszErrMsg, ulLine, ulCode);
if (MessageBox (NULL, Buffer, "FEHLER in DBF, Fortsetzen ?",
MB_APPLMODAL | MB_ICONSTOP | MB_YESNO) == IDNO)
{
return (FALSE);
}
else
{
return (DBFERR_NO_ERROR);
}
}
DBFERR DBF_DefineField (long ulNr, char *pszName, char cType, char
bLength, char bDecimals)
// Definiert ein Feld, 07.06.1993/We
{
memset (&Field [ulNr], 0, sizeof (FIELDDESCRIPTION));
ulNumFields = ulNr;
strcpy (Field [ulNr].szName, pszName);
Field [ulNr].cType = cType;
Field [ulNr].bLength = bLength;
Field [ulNr].bDecimals = bDecimals;
return (DBFERR_NO_ERROR);
}
DBFERR WriteHeader (DBFHANDLE Handle)
// Schreibt den Header der dBase-Datei, 07.06.1993/We
{
long ulCtr, ulLocal, ulWritten;
/* RecLength + HeaderLength berechnen */
Header.usLength = 32 + ((ulNumFields + 1) * 32) + 1; // ulNumFields +
1, da Feldzählung bei Null beginnt!
/* Header schreiben */
ulLocal = fseek (Handle, 0, SEEK_SET);
ulWritten = fwrite (&Header, 32, 1, Handle);
/* Feldinfo schreiben */
for (ulCtr = 0; ulCtr <= ulNumFields; ulCtr++)
{
ulWritten = fwrite (&Field [ulCtr], 32, 1, Handle);
}
/* Header-Terminator schreiben */
ulLocal = fseek (Handle, Header.usLength - 1, SEEK_SET);
ulWritten = fwrite (&HEADERTERMINATOR, sizeof (HEADERTERMINATOR), 1,
Handle);
return (DBFERR_NO_ERROR);
}
DBFERR ReadHeader (DBFHANDLE Handle)
// Liest den Header ein, 12.06.1993/We
{
long ulRead, ulLocal;
ulLocal = fseek (Handle, 0, SEEK_SET);
ulRead = fread (&Header, sizeof (Header), 1, Handle);
return (DBFERR_NO_ERROR);
}
DBFERR DBF_Create (PDBFHANDLE pHandle, char * pszFilename)
// Erzeugt eine DBF-Datei, 12.06.1993/We
{
long Ctr, ulAction;
struct dosdate_t dt;
/* Struct leeren, aktuelles Systemdatum holen */
memset (&Header, 0, sizeof (Header));
_dos_getdate (&dt);
/* Datei erzeugen */
*pHandle = fopen (pszFilename, "wb");
if (pHandle)
{
/* Header mit Daten füllen */
Header.bVersion = 0x003;
Header.usLength = 32 + ((ulNumFields + 1) * 32) + 1; // ulNumFields +
1, da Feldzählung bei Null beginnt!
Header.usRecLen = 0;
Header.bYear = dt.year - 2000;
Header.bMonth = dt.month;
Header.bDay = dt.day;
/* Felderdaten schreiben */
for (Ctr = 0; Ctr <= ulNumFields; Ctr ++)
{
Header.usRecLen += Field [Ctr].bLength;
Field [Ctr].ulDataAddr = 0;
}
Header.usRecLen ++; // wg. DELETED-Flag (20/2A)
WriteHeader (*pHandle);
return (DBFERR_NO_ERROR);
}
else
{
return (FALSE);
}
}
DBFERR DBF_Use (PDBFHANDLE pHandle, char *pszFilename)
// Öffnet eine DBF-Datei zur Benutzung, 12.06.1993/We
{
long ulAction;
*pHandle = fopen (pszFilename, "rb");
if (*pHandle != NULL)
{
ReadHeader (*pHandle);
return (TRUE);
}
else
{
return (DBFERR_FILE_NOT_FOUND);
}
}
DBFERR DBF_Close (DBFHANDLE Handle)
// Schließt aktuelle DBF-Datei, 12.06.1993/We
{
long ulWritten, ulLocal;
WriteHeader (Handle);
ulLocal = fseek (Handle, 0, SEEK_END);
ulWritten = fwrite (&FILETERMINATOR, sizeof (FILETERMINATOR), 1, Handle);
fclose (Handle);
return (DBFERR_NO_ERROR);
}
DBFERR DBF_Write (DBFHANDLE Handle, long ulRecNo, void *pBuffer, long
ulSize)
// Schreibt den pBuffer in die Datei Handle, 06.12.93/We
{
long ulWritten;
if (ulRecNo > Header.ulNumRecs)
{
DBF_Append (Handle, pBuffer, ulSize); // Anhängen statt Schreiben
return (DBFERR_NO_ERROR);
}
else
{
DBF_Locate (Handle, ulRecNo);
ulWritten = fwrite (&SPACE, sizeof (SPACE), 1, Handle);
ulWritten = fwrite (pBuffer, ulSize, 1, Handle);
Header.usRecLen = ulSize + 1;
return (DBFERR_NO_ERROR);
}
}
DBFERR DBF_Append (DBFHANDLE Handle, void *pBuffer, long ulSize)
// Hängt einen Datensatz an, 14.06.1993/We
{
long ulWritten;
DBF_Locate (Handle, Header.ulNumRecs);
ulWritten = fwrite (&SPACE, sizeof (SPACE), 1, Handle);
ulWritten = fwrite (pBuffer, ulSize, 1, Handle);
Header.ulNumRecs ++;
Header.usRecLen = ulSize + 1;
return (DBFERR_NO_ERROR);
}
DBFERR DBF_Read (DBFHANDLE Handle, long ulRecNo, void *pBuffer, long ulSize)
// Liest einen Datensatz ein, 14.06.1993/We
{
long ulRead;
if (ulRecNo > Header.ulNumRecs)
{
DBF_CallError (__LINE__, 2, "Datensatznummer zu groß!");
return (DBFERR_RECNO_TOO_BIG);
}
else
{
DBF_Locate (Handle, ulRecNo);
ulRead = fread (pBuffer, 1, 1, Handle); // Flag REC_DELETED lesen
ulRead = fread (pBuffer, ulSize, 1, Handle); // Eigentliche Daten lesen
Header.usRecLen = ulSize + 1;
return (DBFERR_NO_ERROR);
}
}
DBFERR DBF_Locate (DBFHANDLE Handle, long ulRecNo)
// Setzt den Filepointer auf den Anfang des Records, 14.06.93/We
{
long ulNewPosition, ulLocal;
ulNewPosition = Header.usLength + (ulRecNo * Header.usRecLen);
ulLocal = fseek (Handle, ulNewPosition, SEEK_SET);
return (DBFERR_NO_ERROR);
}
DBFERR DBF_Delete (DBFHANDLE Handle, long ulRecNo)
// Markiert den Record als gelöscht, 14.06.1993/We
{
long ulWritten;
DBF_Locate (Handle, ulRecNo);
ulWritten = fwrite (&DELETEDCHAR, sizeof (DELETEDCHAR), 1, Handle);
return (DBFERR_NO_ERROR);
}
DBFERR DBF_Deleted (DBFHANDLE Handle, long ulRecNo)
// Ist der Record gelöscht ?, 14.06.1993/We
{
long ulBuffer, ulRead;
DBF_Locate (Handle, ulRecNo);
ulRead = fread (&ulBuffer, sizeof (ulBuffer), 1, Handle);
if (ulBuffer == DELETEDCHAR)
{
return (DBFERR_REC_DELETED);
}
else
{
return (DBFERR_REC_NOT_DELETED);
}
}