-
Notifications
You must be signed in to change notification settings - Fork 1
/
dbf.h
225 lines (174 loc) · 9.53 KB
/
dbf.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#ifndef _DBF_H_
#define _DBF_H_
#include "db_utils.h"
#include "cdx.h"
using namespace DBUtils;
#define VISUAL_FOXPRO_TABLE 0x30
#define CHAR_FIELD 'C'
#define CURRENCY_FIELD 'Y'
#define NUMERIC_FIELD 'N'
#define FLOAT_FIELD 'F'
#define DATE_FIELD 'D'
#define DATETIME_FIELD 'T'
#define DOUBLE_FIELD 'B'
#define INTEGER_FIELD 'I'
#define LOGICAL_FIELD 'L'
#define MEMO_FIELD 'M'
#define GENERAL_FIELD 'G'
#define BLOB_FIELD 'W'
#define VARCHAR_FIELD 'V'
#define VARBINARY_FIELD 'Q'
#define PICTURE_FIELD 'P'
#define FIELDS_TYPES "CYNFDTBILMGWVQP" // типы полей
#define MAX_FIELDS 255
#define HEAD_RECORD_TERMINATOR 0x0D
#define DBF_EOF 0x1A
#define NOT_DELETED 0x20
#define DELETED 0x2A
#define DBF_HAS_CDX 0x01
#define DBF_HAS_MEMO 0x02
#define DBF_IS_DBC 0x04
#define COLUMN_SYSTEM 0x01 // System Column (not visible to user)
#define COLUMN_CAN_STORE_NULL 0x02 // Column can store null values
#define COLUMN BINARY 0x04 // Binary column (for CHAR and MEMO only)
#define COLUMN_IS_AUTOINC 0x0C // Column is autoincrementing
#define DBC_PROPERTY_PATH 0x01 // Property Path
#define DBC_PROPERTY_PRIMARYKEY 0x14 // Property Primary key
#pragma pack(push, 1) // Выравнивание структур по границе 1 байта
// Заголовок DBF
struct dbf_header_t // 32 байта
{
unsigned char type; // 0 тип таблицы
unsigned char date[3]; // 1-3 дата модификации YYMMDD
unsigned int rec_count; // 4-7 кол-во записей
unsigned short rec_offset; // 8-9 смещение данных
unsigned short rec_size; // 10-11 размер записи (включая признак удаленной записи)
unsigned char reserved1[16]; // 12-27 зарезервировано
unsigned char flags; // 28 флаги (0x1 - есть CDX, 0x2 - есть MEMO поля, 0x4 - таблица является DBC)
unsigned char code_page; // 29 кодовая страница
unsigned char reserved2[2]; // 30-31 зарезервировано
};
// Поля
struct dbf_field_t // 32 байта
{
char name[11]; // 0-10 имя поля + '\0' (если менее 10 символов, оставшаяся чать должна быть заполнена нулями)
char type; // 11 тип поля
unsigned int offset; // 12-15 смещение данных поля в записи
unsigned char size; // 16 размер поля
unsigned char decimal; // 17 количество десятичных знаков
unsigned char flags; // 18 флаги (0x01, 0x02, 0x04, 0x0C)
unsigned int auto_inc_next; // 19-22 значение автоинкремента
unsigned char auto_inc_step; // 23 шаг автоинкремента
unsigned char reserved[8]; // 24-31 зарезервировано
};
// Заголовок FPT
struct fpt_header_t // 512 байт
{
unsigned int next_block_num; // 0-3 номер следующего свободного блока
unsigned char reserved1[2]; // 4-5 зарезервировано
unsigned short size; // 6-7 размер блока
unsigned char reserved2[504]; // 8-511 зарезервировано
};
// Блок FPT
struct fpt_block_t // 8 байт
{
unsigned int type; // 0-3 тип данных (0 – picture (picture field type), 1 – text (memo field type))
unsigned int size; // 4-7 размер данных, которые начинаются после этого поля
// далее идут данные блока
};
// DBC property
struct dbc_property_t // 6 байт
{
unsigned int size; // 0-3 размер этого блока (заголовок и данные)
unsigned short unknown; // 4-5 всегда 0x0001
unsigned char code; // 6 код property
// далее идут данные property
};
#pragma pack(pop)
class CDBFTable
{
public:
CDBFTable();
~CDBFTable();
bool Open( const char *szFileName, bool bWrite = false, bool bExclusive = false );
void Close( bool bNoClearLastError = false );
bool HasCDX( );
bool Lock( );
bool Unlock( );
bool BeginOfFile( );
bool EndOfFile( );
bool GoTop( );
bool GoBottom( );
bool GoTo( int nPos );
bool Skip( int nCount = 1 );
bool Skip2( int nCount = 1 );
int GetFieldsCount( );
char GetFieldType( int nFieldNum );
int RecCount( );
bool Read( );
unsigned char GetRecordStatus( );
const char *GetBackLink( );
const char *GetTableFileName( );
bool CheckFieldNum( int nFieldNum );
int GetFieldByName( const char *szFieldName );
const char *GetFieldName( int nFieldNum );
bool GetFieldSize( int nFieldNum, int *nSize, int *nDecimal );
// Получение данных
// CHAR
const char *GetChar( int nFieldNum );
const char *GetChar( const char *szFieldName );
// LOGICAL
bool GetLogical( int nFieldNum );
bool GetLogical( const char *szFieldName );
// NUMERIC
double GetNumeric( int nFieldNum );
double GetNumeric( const char *szFieldName );
// INTEGER
int GetInteger( int nFieldNum );
int GetInteger( const char *szFieldName );
// DOUBLE
double GetDouble( int nFieldNum );
double GetDouble( const char *szFieldName );
// DATE
date_t GetDate( int nFieldNum );
date_t GetDate( const char *szFieldName );
// DATETIME
date_time_t GetDateTime( int nFieldNum );
date_time_t GetDateTime( const char *szFieldName );
// MEMO
const void *GetMemo( int nFieldNum, unsigned int *nDataSize );
const void *GetMemo( const char *szFieldName, unsigned int *nDataSize );
bool WriteRecordData( unsigned int nRecNumber, unsigned int nFieldNumber, unsigned char *pData, unsigned char nDataSize );
bool WriteRecordMemoBlock( unsigned int nRecNumber, unsigned int nFieldNumber, unsigned int nBlockNumber );
string GetLastErrorMessage( );
CCompoundIndex m_CDX;
protected:
char m_szName[MAX_PATH]; // Имя таблицы
char m_szFileName[MAX_PATH]; // Имя файла таблицы
char m_szPath[MAX_PATH]; // Путь к таблице
char m_szMemoFileName[MAX_PATH]; // Имя MEMO файла таблицы
HANDLE m_hDBFFile; // Описатель файла DBF
HANDLE m_hFPTFile; // Описатель файла FPT
dbf_header_t m_DBFHeader; // Заголовок DBF
fpt_header_t m_FPTHeader; // Заголовок FPT
vector <dbf_field_t> m_Fields; // Поля таблицы
unsigned int m_FieldsCount; // Количество полей
char m_BackLink[263]; // Путь к контейнеру (если таблица включена в базу данных, иначе 0x00)
int m_RecNo; // Текущая запись
unsigned char *m_RecData; // Буфер для прочитанной записи
unsigned char *m_MemoData; // Буфер для данных MEMO поля
unsigned int m_MemoType; // Тип данных MEMO поля (0, 1)
unsigned int m_MemoSize; // Размер m_MemoData
unsigned int m_MemoRealBlockCount; // Количество реальных (не из заголовка блоков в MEMO файле)
unsigned char m_NoMemoData[255]; // Буфер для обычных полей размером до 254 байт (не мемо). 255-й для нуль терминатора
unsigned int m_LockAttemptMax; // Максимальное количество попыток блокировки
unsigned int m_LockAttemptWait; // Пауза между попытками блокировки
int m_nErrorCode; // код ошибки
string m_sErrorMessage; // сообщение ошибки
bool ReadHeader( ); // Чтение заголовка таблицы
bool ReadFields( ); // Чтение структуры полей
bool ReadMemoHeader( ); // Чтение заголовка memo
bool ReadMemo( unsigned int nBlockNum ); // Чтение мемо блока
bool Set( int nRecNo ); // Установка позиции
};
#endif // _DBF_H_