📄 table_dbase.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// Application Programming Interface //
// //
// Library: SAGA_API //
// //
//-------------------------------------------------------//
// //
// table_dbase.cpp //
// //
// Copyright (C) 2005 by Olaf Conrad //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. //
// //
// This library is free software; you can redistribute //
// it and/or modify it under the terms of the GNU Lesser //
// General Public License as published by the Free //
// Software Foundation, version 2.1 of the License. //
// //
// This library is distributed in the hope that it will //
// be useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A //
// PARTICULAR PURPOSE. See the GNU Lesser General Public //
// License for more details. //
// //
// You should have received a copy of the GNU Lesser //
// General Public License along with this program; if //
// not, write to the Free Software Foundation, Inc., //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, //
// USA. //
// //
//-------------------------------------------------------//
// //
// contact: Olaf Conrad //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
// e-mail: oconrad@saga-gis.org //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "api_core.h"
#include "table_dbase.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define XBASE_FLDHDR_SZ 32
#define TRIM_DBF_WHITESPACE
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_Table_DBase::CSG_Table_DBase(void)
{
bOpen = false;
hFile = NULL;
Record = NULL;
FieldOffset = NULL;
FieldDesc = NULL;
nFields = 0;
Result_String = NULL;
}
//---------------------------------------------------------
CSG_Table_DBase::~CSG_Table_DBase(void)
{
Close();
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
// Creates a new DBase-File using FieldDescription...
bool CSG_Table_DBase::Open(const SG_Char *FileName, int anFields, TFieldDesc *aFieldDesc)
{
Close();
#if defined(_SAGA_LINUX) && defined(_SAGA_UNICODE)
if( (hFile = SG_FILE_OPEN(CSG_String(FileName).b_str(), "w+b")) != NULL )
#else
if( (hFile = SG_FILE_OPEN(FileName, SG_T("w+b"))) != NULL )
#endif
{
bOpen = true;
bReadOnly = false;
nFields = anFields;
FieldDesc = (TFieldDesc *)SG_Malloc(nFields * sizeof(TFieldDesc));
memcpy(FieldDesc, aFieldDesc, nFields * sizeof(TFieldDesc));
Header_Write();
nFileBytes = nHeaderBytes;
}
return( bOpen );
}
//---------------------------------------------------------
// Opens an existing DBase-File...
bool CSG_Table_DBase::Open(const SG_Char *FileName)
{
Close();
#if defined(_SAGA_LINUX) && defined(_SAGA_UNICODE)
if( (hFile = SG_FILE_OPEN(CSG_String(FileName).b_str(), "rb")) != NULL )
#else
if( (hFile = SG_FILE_OPEN(FileName, SG_T("rb"))) != NULL )
#endif
{
bOpen = true;
bReadOnly = true;
if( Header_Read() )
{
fseek(hFile, 0, SEEK_END);
nFileBytes = ftell(hFile);
fseek(hFile, 0, SEEK_SET);
}
}
return( bOpen );
}
//---------------------------------------------------------
// Closes DBase-File if one was opened...
void CSG_Table_DBase::Close(void)
{
//-----------------------------------------------------
if( bOpen )
{
Flush_Record();
Header_Write();
bOpen = false;
fclose(hFile);
hFile = NULL;
}
//-----------------------------------------------------
if( Record )
{
SG_Free(Record);
Record = NULL;
}
if( FieldOffset )
{
SG_Free(FieldOffset);
FieldOffset = NULL;
}
if( FieldDesc )
{
SG_Free(FieldDesc);
FieldDesc = NULL;
}
nFields = 0;
if( Result_String )
{
SG_Free(Result_String);
Result_String = NULL;
}
//-----------------------------------------------------
bModified = false;
bRecModified = false;
//-----------------------------------------------------
FileType = 0;
nRecords = 0;
nHeaderBytes = 0;
nRecordBytes = 0;
Transaction = 0;
bEncrypted = 0;
ProductionIdx = 0;
LanguageDrvID = 0;
nFileBytes = 0;
memset(LastUpdate, 0, 3 * sizeof(char));
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#ifdef _SAGA_LINUX
char * _strupr(char *String)
{
if( String )
for(char *p=String; *p; p++)
if( 'a' <= *p && *p <= 'z' )
*p += 'A' - 'a';
return( String );
}
#endif
//---------------------------------------------------------
void CSG_Table_DBase::Header_Write(void)
{
char buf[16];
int iField;
time_t ltime;
struct tm *pTime;
CSG_String s;
if( bOpen && !bReadOnly )
{
//-------------------------------------------------
// Initializations...
FileType = 0x03;
time( <ime );
pTime = localtime( <ime );
LastUpdate[0] = (unsigned char)pTime->tm_year;
LastUpdate[1] = (unsigned char)pTime->tm_mon + 1;
LastUpdate[2] = (unsigned char)pTime->tm_mday;
nHeaderBytes = (nFields + 1) * 32 + 1;
nRecordBytes = 1; // Delete-Flag = Byte 0...
for(iField=0; iField<nFields; iField++)
{
nRecordBytes += FieldDesc[iField].Width;
}
Init_Record();
fseek(hFile, 0, SEEK_SET);
memset(buf, 0, 16 * sizeof(char));
//-------------------------------------------------
// Bytes 0-31: File Header...
fwrite(&FileType , sizeof(char), 1, hFile); // 00 FoxBase+, FoxPro, dBaseIII+, dBaseIV, no memo - 0x03
// FoxBase+, dBaseIII+ with memo - 0x83
// FoxPro with memo - 0xF5
// dBaseIV with memo - 0x8B
// dBaseIV with SQL Table - 0x8E
fwrite(&LastUpdate , sizeof(char), 3, hFile); // 01-03 Last update, format YYYYMMDD **correction: it is YYMMDD**
fwrite(&nRecords , sizeof(char), 4, hFile); // 04-07 Number of records in file (32-bit number)
fwrite(&nHeaderBytes , sizeof(char), 2, hFile); // 08-09 Number of bytes in header (16-bit number)
fwrite(&nRecordBytes , sizeof(char), 2, hFile); // 10-11 Number of bytes in record (16-bit number)
fwrite( buf , sizeof(char), 2, hFile); // 12-13 Reserved, fill with 0x00
fwrite(&Transaction , sizeof(char), 1, hFile); // 14 dBaseIV flag, incomplete transaction
// Begin Transaction sets it to - 0x01
// End Transaction or RollBack reset it to - 0x00
fwrite(&bEncrypted , sizeof(char), 1, hFile); // 15 Encryption flag, encrypted 0x01 else 0x00
// Changing the flag does not encrypt or decrypt the records
fwrite( buf , sizeof(char), 12, hFile); // 16-27 dBaseIV multi-user environment use
fwrite(&ProductionIdx , sizeof(char), 1, hFile); // 28 Production index exists - 0x01 else 0x00
fwrite(&LanguageDrvID , sizeof(char), 1, hFile); // 29 dBaseIV language driver ID
fwrite( buf , sizeof(char), 2, hFile); // 30-31 Reserved fill with 0x00
//-------------------------------------------------
// Bytes 32-n: Field Descriptor Array...
for(iField=0; iField<nFields; iField++)
{
FieldDesc[iField].Name[11] = '\0';
_strupr(FieldDesc[iField].Name);
fwrite( FieldDesc[iField].Name , sizeof(char), 11, hFile); // 00-10 Field Name ASCII padded with 0x00
fwrite(&FieldDesc[iField].Type , sizeof(char), 1, hFile); // 11 Field Type Identifier (see table)
fwrite(&FieldDesc[iField].Displacement , sizeof(char), 4, hFile); // 12-15 Displacement of field in record
fwrite(&FieldDesc[iField].Width , sizeof(char), 1, hFile); // 16 Field length in bytes
fwrite(&FieldDesc[iField].Decimals , sizeof(char), 1, hFile); // 17 Field decimal places
fwrite( buf , sizeof(char), 2, hFile); // 18-19 Reserved
fwrite(&FieldDesc[iField].WorkAreaID , sizeof(char), 1, hFile); // 20 dBaseIV work area ID
fwrite( buf , sizeof(char), 10, hFile); // 21-30 Reserved
fwrite(&FieldDesc[iField].ProductionIdx , sizeof(char), 1, hFile); // 31 Field is part of production index - 0x01 else 0x00
}
//-------------------------------------------------
// Byte n+1: Header Record Terminator (0x0D)...
buf[0] = 0x0D;
fwrite( buf , sizeof(char), 1, hFile);
}
}
//---------------------------------------------------------
bool CSG_Table_DBase::Header_Read(void)
{
bool Result = false;
char buf[16];
if( bOpen )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -