source: main/trunk/greenstone2/build-src/packages/isis-gdl/MFFile.h@ 26670

Last change on this file since 26670 was 13518, checked in by mdewsnip, 17 years ago

Running this on a big-endian machine would fail to read little-endian CDS/ISIS files. I've assumed most (all?) CDS/ISIS files are little-endian, and added code to convert the values into the right endianness on big-endian machines.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/**********************************************************************
2 *
3 * MFFile.h
4 * Copyright (C) 2003 UNESCO
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26////////////////////////////////////////////////////////////
27// MFFILE.H: Class definition for blocked I/O on the master
28// file
29////////////////////////////////////////////////////////////
30
31#ifndef _MFFILE_H_
32#define _MFFILE_H_
33#ifndef _MASTER_H_
34#include "Master.h"
35#endif
36#ifndef _BLKFILE_H_
37#include "BlkFile.h"
38#endif
39#include <string>
40
41enum MfLockType
42{
43 MF_READ_LOCK,
44 MF_WRITE_LOCK
45};
46
47struct SMfLockHeader
48{
49 long lockProtect_; // Serialize access to the file lock members
50 long readLock_; // Shared (or read_only) file lock
51 long writeLock_; // Exclusive (or write-only) file lock
52
53 SMfLockHeader() : lockProtect_(0), readLock_(0), writeLock_(0)
54 {}
55};
56
57enum { USERMST=0, MSGMST=1 };
58// binary hex
59// ------ ---
60// 0000 0
61// 0001 1
62// 0010 2
63// 0011 3
64
65class MfAddress
66{
67private:
68 long m_mfb;
69 short m_mfp;
70 char m_status;
71public:
72 MfAddress() { m_status = 0x00; }
73 MfAddress(long mfb, short mfp)
74 { ASSERT(mfb>0); ASSERT(mfp>=0); m_mfb = mfb; m_mfp = mfp; m_status = 0x03; }
75
76 long getMfb() { ASSERT(m_status & 0x01); return m_mfb; }
77 short getMfp() { ASSERT(m_status & 0x02); return m_mfp; }
78
79 void setMfb(long mfb) { ASSERT(mfb>0); m_mfb = mfb; m_status |= 0x01; }
80 void setMfp(short mfp) { ASSERT(mfp>=0); m_mfp = mfp; m_status |= 0x02; }
81 bool isValid() { return (m_status == 0x03); }
82};
83
84/////////////////////////////////////////////////////////////////////////
85// Master File header record aggregate structure
86//
87struct SMfHeader
88{
89 ISIS_LONG ctlmfn_; // Always 0
90 ISIS_LONG nxtmfn_; // MFN to be assigned to next record created
91 ISIS_LONG nxtmfb_; // Last block number allocated (1st is 1)
92 ISIS_INT nxtmfp_; // Offset to next available position in last block (1:MFBLKSIZE)
93 ISIS_INT mftype_; // Type of master file (USERMST or MSGMST)
94 ISIS_LONG reccnt_;
95 ISIS_LONG mfcxx1_;
96 ISIS_LONG mfcxx2_;
97 ISIS_LONG mfcxx3_;
98public:
99 SMfHeader(const char *dbname="");
100 ~SMfHeader() { }
101};
102
103//--------------------------------------------------------------------------
104// SMfHeader::SMfHeader(const char *dbname /* ="" */)
105//
106// Default constructor, initializes the Master file header to default values
107//--------------------------------------------------------------------------
108inline SMfHeader::SMfHeader(const char *dbname /* ="" */)
109{
110 ctlmfn_ = 0;
111 nxtmfn_ = 1L;
112 nxtmfb_ = 1L;
113 nxtmfp_ = MFCTLLEN+1;
114 mftype_ = USERMST;
115 reccnt_ = mfcxx1_=mfcxx2_=mfcxx3_=0;
116}
117
118//////////////////////
119// Master file class
120//
121class MfFile : public BlkFile
122{
123 friend class IsisDb;
124 friend class MfRecord;
125
126protected:
127 SMfHeader mfh_; // Header structure
128 long nextaddr_; // Address of next record
129 char buf_[MFBLKSIZE]; // Buffer to hold 1 Master File block
130 bool hdr_created_; // True if 1st block exists
131 int fileError_;
132 long lastWrittenBlock_;
133
134protected:
135 void WriteMfRecord(long mfb, int mfp, MfRecord &r);
136 void AppendNewBlock();
137
138public:
139 void setNextMfn(long mfn) // Set MFN to be assigned to next record created
140 { mfh_.nxtmfn_ = mfn; }
141
142protected:
143 void setNextMfb(long nxtmfb_) // Set last block number allocated (1st is 1)
144 { mfh_.nxtmfb_ = nxtmfb_; }
145 void setNextMfp(int nxtmfp_) // Set offset to next available position in last block
146 { mfh_.nxtmfp_ = nxtmfp_; }
147 int setm_mftype(int mftype_) // Set type of master file (USERMST or MSGMST)
148 { mfh_.mftype_ = mftype_; }
149 virtual void ReadBlk(void* d, long b) { BlkFile::ReadBlk(d, b); }
150 virtual void WriteBlk(void* d, long b) { BlkFile::WriteBlk(d, b); }
151 void ReadMfHdr(SMfHeader &h);
152 void ReadMfHdr();
153 void WriteMfHdr(SMfHeader &h);
154 void WriteMfHdr();
155 void SetLastWrittenBlock(long b) { lastWrittenBlock_ = b; }
156public:
157 MfFile();
158 virtual ~MfFile();
159
160 int OpenMf(const TCHAR* name, FileSystem::AccessMode mode = FileSystem::FILE_READWRITE);
161 int CreateMf(const TCHAR* name, int MSTtype = USERMST);
162 void CloseMf() { if (ReadyForWriting()) WriteMfHdr(); Close(); }
163
164 // Accessors for the Master File Header
165 long GetNextMfn() // Get MFN to be assigned to next record created
166 { return mfh_.nxtmfn_; }
167 long GetNextMfb() // Get last block number allocated (1st is 1)
168 { return mfh_.nxtmfb_; }
169 int GetNextMfp() // Get offset to next available position in last block
170 { return mfh_.nxtmfp_; }
171 int GetMftype() // Get type of master file (USERMST or MSGMST)
172 { return mfh_.mftype_; }
173 SMfHeader& GetSMfHeader() { return mfh_; }
174
175
176 void CreateMfRecord(MfRecord &m, long &mfb, int &mfp);
177 void AddMfRecord(MfRecord &m, long &mfb, int &mfp);
178 void UpdateMfRecord(MfRecord &m, long &mfb, int &mfp);
179 bool ReadMfRecord(long mfb, int mfp, MfRecord &r);
180
181 void ReadMfRecord(long addr, MfRecord &r);
182 void WriteMfRecord(long addr, MfRecord &r);
183 void RewindMf();
184 bool ReadMfNext(MfRecord &r);
185 void WriteMfNext(MfRecord &r);
186 void ReadLeader(long daddr, MfRecord& m)
187 {
188 m.ReadLeader(*this, daddr);
189 }
190
191
192 void LockMfHdr();
193 void UnlockMfHdr();
194 void LockMfr(long mfn);
195 void UnlockMfr(long mfn);
196
197public: // File lock functions
198 void InitFileLockHdr(SMfLockHeader &hdr);
199 FileError ResetFileLock();
200 FileError WriteFileLockHdr(const SMfLockHeader &hdr);
201 FileError ReadFileLockHdr(SMfLockHeader &hdr);
202 int LockFile(MfLockType l_type = MF_WRITE_LOCK);
203 int UnlockFile(MfLockType l_type = MF_WRITE_LOCK);
204
205
206 void PrintMfRecord(MfRecord &r);
207 void PrintMfHdr(SMfHeader &h);
208 void PrintMfHdr();
209};
210
211
212class CMfIterator
213{
214 const MfFile& m_mf;
215 long cur;
216public:
217 CMfIterator(const MfFile& mf) : m_mf(mf) { }
218
219 bool More() const;
220 void Advance();
221
222 MfRecord Current()
223 {
224 MfRecord mfr(NULL);
225
226 return mfr;
227 }
228};
229
230
231//////////////////////////////
232
233inline void MfFile::LockMfHdr()
234// Locks the master file header record
235{
236 double_t dwPos = 0;
237 double_t dwCount = sizeof(SMfHeader);
238 //CFile::LockRange(dwPos, dwCount);
239}
240
241//////////////////////////////
242
243inline void MfFile::UnlockMfHdr()
244// Unlocks the master file header record
245{
246 double_t dwPos = 0;
247 double_t dwCount = sizeof(SMfHeader);
248 //CFile::UnlockRange(dwPos, dwCount);
249}
250
251//////////////////////////////
252
253inline void MfFile::ReadMfHdr()
254// Reads the master file header record
255{
256 ReadBlk(buf_, 1L);
257 TRACE(_T("\nsizeof(SMfHeader)=%d"), sizeof(SMfHeader));
258 ::MoveMemory(&mfh_, buf_, sizeof(SMfHeader));
259
260 fix_endianness(mfh_.ctlmfn_);
261 fix_endianness(mfh_.nxtmfn_);
262 fix_endianness(mfh_.nxtmfb_);
263 fix_endianness(mfh_.nxtmfp_);
264 fix_endianness(mfh_.mftype_);
265 fix_endianness(mfh_.reccnt_);
266 fix_endianness(mfh_.mfcxx1_);
267 fix_endianness(mfh_.mfcxx2_);
268 fix_endianness(mfh_.mfcxx3_);
269}
270
271//////////////////////////////
272
273inline void MfFile::WriteMfHdr()
274// Updates the master file header record
275{
276 if (hdr_created_)
277 ReadBlk(buf_, 1L);
278 TRACE(_T("\nsizeof(SMfHeader)=%d"), sizeof(SMfHeader));
279 ::MoveMemory(buf_, &mfh_, sizeof(SMfHeader));
280 WriteBlk(buf_, 1L);
281}
282
283
284//////////////////////////////
285
286inline void MfFile::ReadMfHdr(SMfHeader &h)
287// Reads the master file header record
288{
289 ReadBlk(buf_, 1L);
290 ::MoveMemory(&h, buf_, sizeof(SMfHeader));
291
292 fix_endianness(h.ctlmfn_);
293 fix_endianness(h.nxtmfn_);
294 fix_endianness(h.nxtmfb_);
295 fix_endianness(h.nxtmfp_);
296 fix_endianness(h.mftype_);
297 fix_endianness(h.reccnt_);
298 fix_endianness(h.mfcxx1_);
299 fix_endianness(h.mfcxx2_);
300 fix_endianness(h.mfcxx3_);
301}
302
303//////////////////////////////
304
305inline void MfFile::WriteMfHdr(SMfHeader &h)
306// Updates the master file header record
307{
308 if (hdr_created_)
309 ReadBlk(buf_, 1L);
310 ::MoveMemory(buf_, &h, sizeof(SMfHeader));
311 WriteBlk(buf_, 1L);
312}
313
314
315inline void MfFile::PrintMfHdr()
316{
317 PrintMfHdr(mfh_);
318}
319
320//////////////////////////////
321
322inline bool MfFile::ReadMfNext(MfRecord &r)
323// Reads the next physically record
324{
325 if (nextaddr_ >= CFileBase::FileSize(file_name))
326 return false;
327 ReadMfRecord(nextaddr_, r);
328 return true;
329}
330
331//////////////////////////////
332
333inline void MfFile::WriteMfNext(MfRecord &r)
334// Writes physically at next position
335{
336 WriteMfRecord(nextaddr_, r);
337}
338#endif
Note: See TracBrowser for help on using the repository browser.