TNB Library
TnbDBaseFile.h
[詳解]
1#pragma once
11#include "TnbFile.h"
12#include "TnbGrid.h"
13
14
15
16//TNB Library
17namespace TNB
18{
19
20
21
22#pragma pack(push)
23#pragma pack(1)
24
25
26
44class CDBaseFile : public CGrid
45{
46 DEFSUPER(CGrid);
47public:
48
55 bool LoadFile(LPCTSTR lpszFileName)
56 {
57 _super::AllDeleteRecord();
58 CFileReader fr;
59 if ( fr.Open(lpszFileName) )
60 {
61 try
62 {
63 m_Load(fr);
64 }
65 catch ( CTnbException& e )
66 {
67 e.OnCatch();
68 _super::AllDeleteRecord();
69 return false;
70 }
71 catch ( ... )
72 {
73 throw;
74 }
75 return true;
76 }
77 return false;
78 }
79
86 bool SaveFile(LPCTSTR lpszFileName) const
87 {
88 CFileWriter fw;
89 if ( fw.New(lpszFileName) )
90 {
91 try
92 {
93 m_Save(fw);
94 }
95 catch ( CTnbException& e )
96 {
97 e.OnCatch();
98 return false;
99 }
100 catch ( ... )
101 {
102 throw;
103 }
104 return true;
105 }
106 return false;
107 }
108
109private:
113 struct THead
114 {
115 BYTE version :3;
116 BYTE withMemoFile4 :1;
117 BYTE withSqlTable :3;
118 BYTE withMemoFile :1;
119 BYTE year;
120 BYTE month;
121 BYTE day;
122 DWORD recordCount;
123 WORD headBytes;
124 WORD recordBytes;
125 BYTE padding1[2];
126 BYTE transaction;
127 BYTE encryptionFlag;
128 BYTE padding2[12];
129 BYTE withMdxFile;
130 BYTE language;
131 BYTE padding3[2];
132 THead(void)
133 {
134 Zero(*this);
135 version = 3;
136 }
137 void SetTime(const SYSTEMTIME& st)
138 {
139 year = static_cast<BYTE>(st.wYear - 1900);
140 month = static_cast<BYTE>(st.wMonth);
141 day = static_cast<BYTE>(st.wDay);
142 }
143 };
144 C_ASSERT ( sizeof(THead) == 32 );
145
149 struct TField
150 {
151 char name[11];
152 char type;
153 BYTE padding1[4];
154 BYTE fieldLength;
155 BYTE decimalLength;
156 BYTE padding2[2];
157 BYTE wordId;
158 BYTE padding3[10];
159 BYTE withMdxField;
160 TField(void)
161 {
162 Zero(*this);
163 }
165 void SetName(LPCTSTR lpsz)
166 {
167 Zero(name);
168 CAscii s = lpsz;
169 if ( s.GetLength() > 10 )
170 {
171 s = s.Left(10);
172 }
173 STRLIB::Copy(name, s);
174 }
175 };
176 C_ASSERT ( sizeof(TField) == 32 );
177
184 void m_Load(const IReader& r)
185 {
186 //=== ヘッダ読込み
187 THead hd;
188 r.ReadExactly(sizeof(THead), &hd);
189 if ( hd.version != 3 )
190 {
191 throw CNotSupportException();
192 }
193 //=== フィールド読込み
194 size_t fieldCount = (hd.headBytes - sizeof(THead)) / sizeof(TField); //フィールド数
195 size_t recordBytesTemp = 0;
196 loop ( i, fieldCount )
197 {
198 TField fd;
199 r.ReadExactly(sizeof(TField), &fd);
200 TFieldInfo fi(CStr(fd.name), fd.fieldLength, fd.decimalLength, static_cast<EFieldType>(fd.type));
201 if ( _super::AddField(fi) == INVALID_INDEX )
202 {
204 }
205 recordBytesTemp += fd.fieldLength;
206 }
207 BYTE b;
208 r.ReadExactly(sizeof(BYTE), &b);
209 if ( b != 0x0D )
210 {
212 }
213 recordBytesTemp++;
214 if ( recordBytesTemp != hd.recordBytes )
215 {
216 TRACE2("ヘッダのレコードサイズ(%d)と各フィールドに書かれているサイズの合計(%d)が異なります。\n", hd.recordBytes, recordBytesTemp);
218 }
219 //=== レコード読込み
220 loop ( i, hd.recordCount )
221 {
222 CWorkMemT<char> buf(hd.recordBytes); //レコードのバイト数
223 char* B = buf.Ref();
224 r.ReadExactly(hd.recordBytes, B);
225 if ( B[0] != 0x20 )
226 {
227 continue; //sp以外はデリートレコード
228 }
229 B++;
230 INDEX rec = _super::AddRecord();
231 ASSERT( rec != INVALID_INDEX );
232 loop ( i, fieldCount )
233 {
234 TFieldInfo fi;
235 EFieldKind k = _super::GetFieldInfo(fi, i);
236 ASSERT( k != EK_Invalid );
237 CAscii a;
238 a.SetFromLeft(B, fi.width);
239 if ( ! _super::SetStringRecord(rec, i, CStr(a)) )
240 {
242 }
243 B += fi.width;
244 }
245 }
246 //=== 終端
247 r.ReadExactly(sizeof(BYTE), &b);
248 if ( b != 0x1A )
249 {
251 }
252 _super::Dump();
253 }
254
261 void m_Save(IWriter& _w) const
262 {
263 //=== ヘッダ書き出し
264 THead hd;
265 {
266 SYSTEMTIME st;
267 ::GetLocalTime(&st);
268 hd.SetTime(st);
269 size_t rb = 0;
270 loop ( i, _super::GetFieldCount() )
271 {
272 TFieldInfo fi;
273 _super::GetFieldInfo(fi, i);
274 rb += fi.width;
275 }
276 hd.recordCount = ToDword(_super::GetRecordCount());
277 hd.recordBytes = ToWord(rb + 1);
278 hd.headBytes = ToWord(_super::GetFieldCount() * sizeof(TField) + sizeof(THead) + 1);
279 }
280 _w.Write(sizeof(THead), &hd);
281 //=== フィールド書き出し
282 CWorkMemT<size_t> widths(_super::GetFieldCount());
283 loop ( i, _super::GetFieldCount() )
284 {
285 TFieldInfo fi;
286 if ( _super::GetFieldInfo(fi, i) == EK_Invalid )
287 {
289 }
290 widths[i] = fi.width;
291 TField fd;
292 fd.SetName(fi.name);
293 fd.fieldLength = static_cast<BYTE>(fi.width);
294 fd.decimalLength = static_cast<BYTE>(fi.decimals);
295 fd.type = static_cast<char>(fi.type);
296 _w.Write(sizeof(TField), &fd);
297 }
298 BYTE b = 0x0D;
299 _w.Write(sizeof(BYTE), &b);
300 //=== レコード書き出し
301 loop ( i, GetRecordCount() )
302 {
303 CWorkMemT<char> buf(hd.recordBytes); //レコードのバイト数
304 char* B = buf.Ref();
305 *B++ = 0x20;
306 INDEX rec = i;
307 size_t len = 1;
308 loop ( j, _super::GetFieldCount() )
309 {
310 size_t l = widths[j];
311 CAscii a = _super::GetStringRecord(rec, j, true) + CStr::Lineup(' ', l);
312 a = a.Left(l);
313 TNB::MemCopy(B, a, l);
314 B += l;
315 len += l;
316 }
317 ASSERT ( len == hd.recordBytes );
318 _w.Write(hd.recordBytes, buf.Ref());
319 }
320 //=== 終端
321 b = 0x1A;
322 _w.Write(sizeof(BYTE), &b);
323 }
324
325 friend class CDBaseFileTest;
326};
327
328
329
330#pragma pack(pop)
331
332
333
334}; // TNB
335
336
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ファイル関係のヘッダ
グリッド情報管理関係のヘッダ
追加失敗例外
Definition: TnbException.h:94
dBaseファイル管理クラス
Definition: TnbDBaseFile.h:45
bool SaveFile(LPCTSTR lpszFileName) const
[書出] DBFファイル書き出し
Definition: TnbDBaseFile.h:86
bool LoadFile(LPCTSTR lpszFileName)
[読込] DBFファイル読込み
Definition: TnbDBaseFile.h:55
ファイル読み込みクラス
Definition: TnbFile.h:338
bool Open(LPCTSTR lpszName, bool boIsShare=true, bool boDummy=false)
[操作] オープン
Definition: TnbFile.h:364
ファイル書き込みクラス
Definition: TnbFile.h:475
bool New(LPCTSTR lpszName, bool boIsShare=true)
[操作] 新規オープン.
Definition: TnbFile.h:501
グリッド管理クラス.
Definition: TnbGrid.h:33
EFieldKind
フィールド種類
Definition: TnbGrid.h:38
@ EK_Invalid
不正
Definition: TnbGrid.h:43
EFieldType
フィールドタイプ
Definition: TnbGrid.h:48
size_t GetRecordCount(void) const
[取得] レコード数取得
Definition: TnbGrid.h:148
パラメータ不正例外
Definition: TnbException.h:159
サポート外例外
Definition: TnbException.h:185
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
CStrT & SetFromLeft(const TYP *lpText, size_t iLen)
[代入] 文字数制限代入.
Definition: TnbStr.h:278
static CStrT Lineup(TCHAR t, size_t length)
[作成] 指定文字を並べた文字列作成
Definition: TnbStr.h:1222
例外ベースクラス
Definition: TnbException.h:36
void OnCatch(void) const
[表示] 内容表示
Definition: TnbException.h:69
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:395
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
void Copy(LPSTR _dst, LPCSTR src)
[複製] 文字列コピー(ASCII/SJIS用)
Definition: TnbStrLib.h:89
void Zero(V &value)
[設定] ゼロクリア.
Definition: TnbDef.h:399
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376
システムタイム型.
Definition: TnbTime.h:876
WORD wYear
Definition: TnbTime.h:877
WORD wMonth
Definition: TnbTime.h:878
WORD wDay
Definition: TnbTime.h:880
読み込みインターフェース
Definition: TnbReader.h:36
void ReadExactly(size_t size, LPVOID _P) const
[取得] 読み込み.
Definition: TnbReader.h:114
書き込みインターフェース
Definition: TnbWriter.h:36
virtual void Write(size_t size, LPCVOID P)=0
[保存] 書き込み