source: main/trunk/greenstone2/build-src/packages/isis-gdl/Master.h

Last change on this file was 34961, checked in by anupama, 3 years ago

Merging Dr Bainbridge's mg-long related updates for IsisGdl that got IsisGdl working on 64 bit linux, and on new Macs that were no longer backwards compatible with 32 bit. Tested only to compile and run (CDS-ISIS tutorial) on 64 bit linux. Merged version of code untested on Mac, though it was used to generate the static 64 bit Mac IsisGdl before. Also untested on 32 bit linux, but Dr Bainbridge had earlier indicated it was backwards. At present the release kit code is still grabbing the statically built IsisGdl (for 32 and nowadayas also 64 bit Mac/Linux) as before and including in binaries. This can be changed later. These code changes are for locally compiling up GS from SVN with an IsisGdl built on the local machine meant to work on that local machine.

  • Property svn:keywords set to Author Date Id Revision
File size: 15.9 KB
Line 
1/**********************************************************************
2 *
3 * Master.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// Master.h: Master File Record object
28/////////////////////////////////////// */
29
30#ifndef __MASTER_RECORD_H__
31#define __MASTER_RECORD_H__
32
33
34#include "BlkFile.h"
35#include <vector>
36#include <map>
37#include <sstream>
38
39
40
41// Length in bytes of master file header
42#define MFCTLLEN sizeof(SMfHeader)+sizeof(SMfHeader) // Length in bytes of master file header
43
44const int MFALIGN = 2; // Master file record alignment
45const int MFBLKSIZE = 512; // Master file block size
46
47typedef int16_t ISIS_INT; // used to be defined as 'short int' which worked for 32-bit Unix, but not 64-bit
48typedef mg_s_long ISIS_LONG; // used to be defined as 'long int' which worked for 32-bit Unix, but not 64-bit
49
50#ifdef UNIX_BIREME
51 //Length of Leader in master record
52 inline int GetLeaderSize()
53 {
54 return (2*sizeof(ISIS_LONG)+6*sizeof(ISIS_INT));
55 }
56 // Mini Leader length guaranteed to be in same block
57 inline int GetMinLeaderSize()
58 {
59 return (2*sizeof(ISIS_LONG)+4*sizeof(ISIS_INT));
60 }
61#else
62 //Length of Leader in master record
63 inline int GetLeaderSize()
64 {
65 return (2*sizeof(ISIS_LONG)+5*sizeof(ISIS_INT));
66 }
67 // Mini Leader length guaranteed to be in same block
68 inline int GetMinLeaderSize()
69 {
70 return (2*sizeof(ISIS_LONG)+3*sizeof(ISIS_INT));
71 }
72#endif
73
74// Size of Mfn and Mfrl in the leader part
75inline int GetSubLeaderSize() { return sizeof(ISIS_LONG)+sizeof(ISIS_INT); }
76
77inline int GetDirEntrySize() { return (3*sizeof(ISIS_INT)); }
78
79
80const TCHAR SYSRSEP = TCHAR('%'); // Repeatable field separator
81const TCHAR SUBFIELD_SEP = TCHAR('^'); // Subfield separator
82
83////////////////////////////////////////
84// Directory entry aggregate structure
85//
86struct DirEntry
87{
88 ISIS_INT tag_;
89 ISIS_INT pos_;
90 ISIS_INT len_;
91 DirEntry()
92 : tag_(0), pos_(0), len_ (0) { }
93
94 DirEntry(ISIS_INT tag, ISIS_INT pos, ISIS_INT len)
95 : tag_(tag), pos_(pos), len_ (len) { }
96 bool operator==(const DirEntry& rhs) const
97 {
98 if (tag_!=rhs.tag_ || pos_!=rhs.pos_ || len_!=rhs.len_)
99 return false;
100 return true;
101 }
102 bool operator!=(const DirEntry& rhs) const
103 {
104 if (tag_!=rhs.tag_ || pos_!=rhs.pos_ || len_!=rhs.len_)
105 return true;
106 return false;
107 }
108
109};
110
111
112//////////////////////////////////////////////////////////////////////////
113// Data Master record aggregate structure
114//
115struct LeaderAndDirectory
116{
117 ISIS_LONG mfn_; // Master file number
118 ISIS_INT mfrl_; // Record length
119 ISIS_LONG mfbwb_; // Backward pointer block number
120 ISIS_INT mfbwp_; // Backward pointer offset
121 ISIS_INT base_; // Offset to begining of variable fields
122 ISIS_INT nvf_; // Number of directory entries
123 ISIS_INT status_; // 1 = DELETED
124 std::vector<DirEntry> dir_; // Directory
125
126 LeaderAndDirectory()
127 {
128 Clear();
129 }
130 LeaderAndDirectory(const LeaderAndDirectory& src)
131 {
132 Copy(src);
133 }
134
135 LeaderAndDirectory& operator=(const LeaderAndDirectory& rhs)
136 {
137 if (&mfn_ != &rhs.mfn_)
138 {
139 Copy(rhs);
140 }
141 return *this;
142 }
143
144 void Copy(const LeaderAndDirectory& rhs)
145 {
146 mfn_ = rhs.mfn_;
147 mfrl_ = rhs.mfrl_;
148 mfbwb_ = rhs.mfbwb_;
149 mfbwp_ = rhs.mfbwp_;
150 base_ = rhs.base_;
151 nvf_ = rhs.nvf_;
152 status_ = rhs.status_;
153 dir_ = rhs.dir_;
154 }
155 void Clear()
156 {
157 mfn_ = mfrl_ = mfbwb_ = mfbwp_ = base_ = nvf_ = status_ = 0;
158 dir_.clear();
159 }
160
161 bool operator==(const LeaderAndDirectory& rhs) const;
162 bool operator!=(const LeaderAndDirectory& rhs) const;
163 int GetFieldSize();
164};
165
166cstringstream& operator<<(cstringstream& s, const LeaderAndDirectory& leader);
167cstringstream& operator>>(cstringstream& s, LeaderAndDirectory& leader);
168
169////////////////////////////////////////////////////////////
170//
171
172/////////////////////////////////
173// Data master file record class
174//
175
176typedef std::map<int, ustring> TAG2FIELD;
177class MfFile;
178class MstFile;
179class IsisDb;
180class ACE_InputCDR;
181class ACE_OutputCDR;
182class UMfRecord;
183
184
185class MfRecord
186{
187 friend class MfFile;
188 friend class MstFile;
189 friend class IsisDb;
190 friend class UMfRecord;
191 friend int operator>>(ACE_InputCDR& cdr, MfRecord& mfr);
192 friend int operator<<(ACE_OutputCDR& cdr, MfRecord& mfr);
193protected:
194
195 CFdt* pFdt_; // Use a copy of the FDT
196 cstring record_; // Record in continuous storage
197 // always as ANSI!
198
199 LeaderAndDirectory leader_directory_;
200
201 TAG2FIELD fields_;
202 std::vector<int> tags_;
203 static char m_buf[MFBLKSIZE]; // Buffer to hold 1 File block
204
205protected: // Additional data
206 short int state_; // Record state in memory
207 mg_s_long mfb_read_; // Record was read at Block number [1...]
208 int mfp_read_; // Record was read at position in block
209 int mflen_read_; // Record length was when record read
210
211protected:
212 void Copy(const MfRecord& rhs);
213
214 void AddToRecord(const char* p, int len);
215 int AddDirEntry(const DirEntry& d);
216 int AddDirEntry(int tag, int pos, int len);
217 int DelDirEntry(int i);
218 void SetMfrl(int mfrl);
219 void SetMfbwb(mg_s_long mfbwb);
220 void SetMfbwp(int mfbwp);
221 void SetBase(int base);
222 void SetNvf(int nvf);
223 void SetStatus(int s);
224 int SetDirEntry(int i, int tag, int pos, int len);
225 int SetDirEntry(int i, const DirEntry& d);
226 void SetMfbRead(mg_s_long b);
227 void SetMfpRead(int pos);
228 void SetMflenRead(int len);
229
230
231 void SetSubLeaderAndDirectory(const char* p, int len);
232
233
234 void MakeTagToFieldMap();
235 void MakeTagVector();
236
237 mg_s_long ComputeMfrl();
238
239 void Copy(UMfRecord& rhs);
240public:
241 enum { Record_Empty, Record_Read, Record_Changed, Record_Created };
242
243public:
244 //-----------------
245 // Public Interface
246 //-----------------
247 MfRecord(CFdt* pFdt=NULL); // Default constructor
248 virtual ~MfRecord(); // Destructor
249
250 MfRecord(const MfRecord& rhs); // Copy constructor
251 MfRecord& operator=(const MfRecord& rhs); // Assignment
252
253 MfRecord(const UMfRecord& umfr);
254 MfRecord& operator=(const UMfRecord& rhs);
255
256 void Clear();
257 void ClearData();
258
259
260 void ReadLeader(MfFile& f, mg_s_long daddr);
261 bool Read (MfFile& f, mg_s_long mfb, int mfp);
262 void Write(MfFile& f, mg_s_long mfb, int mfp);
263
264 void MakeISORecord(std::string& s);
265
266 mg_s_long GetMfn() const; // Get MFN
267 int GetMfrl() const; // Get Master File Record Length
268 mg_s_long GetMfbwb() const; // Get Master File Backward Block number
269 int GetMfbwp() const; // Get Master File Backward block position
270 int GetBase() const; // Get Variable fields starting byte
271 int GetNvf() const; // Get Number of entries in the directory
272 int GetStatus() const; // Get Record Status
273 DirEntry GetDirEntry(int i) const; // Get a reference to the ieme directory entry
274 int GetState() const; // Get record state in memory
275 mg_s_long GetMfbRead() const;
276 int GetMfpRead() const;
277 int GetMflenRead() const;
278
279 ustring GetAllFields(); // ANSI or UNICODE
280 cstring GetRecordAsString() { return record_; }
281 const char* GetRecord() { return record_.c_str(); }
282 int GetRecordLength() { return record_.length(); }
283
284 void ConvertToAnsi();
285
286
287 bool GetField(int tag, std::string& s); // Get field content for field with tag "tag"
288 bool AddField(int tag, std::string& s);
289 bool DeleteField(int tag);
290 bool ReplaceField(int tag, std::string& s);
291 bool AddOccurence(int tag, std::string& o);
292
293 int GetFieldTag(int i);
294 int GetFieldPos(int i);
295 int GetFieldLen(int i);
296
297 void SetMfn(mg_s_long mfn);
298 void SetState(int s);
299
300 mg_s_long GetDirectorySize();
301 int GetFieldSize() { return leader_directory_.GetFieldSize(); }
302
303 std::vector<int> GetFieldTags(); // Get tags of fields in increasing order,
304 // Occurences made only 1 field
305 void ExtractSubLeader();
306 void ExtractLeader();
307 bool CheckIntegrity();
308 bool CheckLeader();
309 bool CheckLeaderAndDirectory();
310
311 bool operator==(const MfRecord& rhs) const
312 {
313 return (record_ == rhs.record_);
314 }
315 bool operator!=(const MfRecord& rhs) const
316 {
317 return (record_ != rhs.record_);
318 }
319
320 void SetRecord(const char *s) { record_ = s; DecomposeRecord();}
321 void SetRecord(const cstring &s)
322 { record_ = s; DecomposeRecord();}
323 void ComposeRecord();
324 bool DecomposeRecord();
325
326 bool CheckRecord();
327 void Dump();
328} ;
329
330//////////////////////////////
331
332
333
334
335inline void MfRecord::AddToRecord(const char* p, int len)
336{
337 record_ += cstring(p,len);
338}
339
340/////////////////////////////
341
342inline MfRecord::MfRecord(CFdt* pFdt)
343// Makes a Master file Record object
344{
345 Clear();
346 pFdt_ = pFdt;
347 // Nothing more to do
348}
349
350inline void MfRecord::Copy(const MfRecord& rhs)
351{
352 record_ = rhs.record_;
353 leader_directory_ = rhs.leader_directory_;
354 fields_ = rhs.fields_;
355 state_ = rhs.state_;
356 mfb_read_ = rhs.mfb_read_;
357 mfp_read_ = rhs.mfp_read_;
358 mflen_read_ = rhs.mflen_read_;
359 tags_ = rhs.tags_;
360 pFdt_ = rhs.pFdt_;
361}
362
363inline MfRecord::MfRecord(const MfRecord& rhs) // Copy constructor
364{
365 Copy(rhs);
366}
367
368inline MfRecord& MfRecord::operator=(const MfRecord& rhs) // Assignment
369{
370 if (&leader_directory_ != &rhs.leader_directory_)
371 {
372 Copy(rhs);
373 }
374 return *this;
375}
376
377inline void MfRecord::Clear()
378{
379 tags_.clear();
380 record_.erase();
381 leader_directory_.Clear();
382 fields_.clear();
383 SetBase(GetLeaderSize());
384 SetMfrl(GetLeaderSize());
385 state_ = Record_Empty;
386 mfb_read_ = mfp_read_ = mflen_read_ = 0;
387 pFdt_ = NULL;
388}
389
390// Clear the data part but keep other info intact so that
391// it appears as an empty record
392inline void MfRecord::ClearData()
393{
394 tags_.clear();
395 record_.erase();
396 leader_directory_.Clear();
397 fields_.clear();
398 SetBase(GetLeaderSize());
399 SetMfrl(GetLeaderSize());
400}
401
402
403//////////////////////////////
404
405inline MfRecord::~MfRecord()
406{
407}
408
409//////////////////////////////
410
411inline mg_s_long MfRecord::GetMfn() const
412// Returns Master file number
413{
414 return leader_directory_.mfn_;
415}
416
417//////////////////////////////
418
419inline int MfRecord::GetMfrl() const
420// Returns Master file record length
421{
422 return leader_directory_.mfrl_;
423}
424
425//////////////////////////////
426
427inline mg_s_long MfRecord::GetMfbwb() const
428// Returns backward pointer block number
429{
430 return leader_directory_.mfbwb_;
431}
432
433//////////////////////////////
434
435inline int MfRecord::GetMfbwp() const
436// Returns backward pointer offset
437{
438 return leader_directory_.mfbwp_;
439}
440
441//////////////////////////////
442
443inline int MfRecord::GetBase() const
444// Returns base value to field data
445{
446 return leader_directory_.base_;
447}
448
449//////////////////////////////
450
451inline int MfRecord::GetNvf() const
452// Returns the number of directory entries
453// in the master file record
454{
455 return leader_directory_.nvf_;
456}
457
458//////////////////////////////
459
460inline int MfRecord::GetStatus() const
461// Returns the status of the record
462{
463 return leader_directory_.status_;
464}
465
466//////////////////////////////
467
468
469//////////////////////////////
470
471inline DirEntry MfRecord::GetDirEntry(int i) const
472// Returns the ith dir entry
473{
474 return leader_directory_.dir_[i];
475}
476
477//////////////////////////////
478
479inline int MfRecord::GetState() const
480{
481 return state_;
482}
483
484//////////////////////////////
485
486inline mg_s_long MfRecord::GetMfbRead() const
487{
488 return mfb_read_;
489}
490//////////////////////////////
491
492inline int MfRecord::GetMfpRead() const
493{
494 return mfp_read_;
495}
496
497//////////////////////////////
498
499// Get tags of fields in increasing order,
500inline std::vector<int> MfRecord::GetFieldTags()
501{
502 PRECONDITION(tags_.size() == fields_.size());
503 return tags_;
504}
505//////////////////////////////
506
507inline int MfRecord::GetMflenRead() const
508{
509 return mflen_read_;
510}
511
512///////////////////////////////////////////////////////////////////////////////
513
514inline void MfRecord::SetMfn(mg_s_long mfn)
515// Set Master file number
516{
517 assert(mfn>0);
518 leader_directory_.mfn_ = mfn;
519}
520//////////////////////////////
521
522inline void MfRecord::SetMfrl(int mfrl)
523// Set Master file record length
524{
525 assert(mfrl>0);
526 leader_directory_.mfrl_ = mfrl;
527}
528//////////////////////////////
529
530inline void MfRecord::SetMfbwb(mg_s_long mfbwb)
531// Sets backward pointer block number to mfbwb
532{
533 assert(mfbwb>=0);
534 leader_directory_.mfbwb_ = mfbwb;
535}
536
537//////////////////////////////
538
539inline void MfRecord::SetMfbwp(int mfbwp)
540// Sets backward pointer block offset to mfbwp
541{
542 assert(mfbwp>=0);
543 leader_directory_.mfbwp_ = mfbwp;
544}
545//////////////////////////////
546
547inline void MfRecord::SetBase(int base)
548// Sets the base value in the record aggregate
549{
550 assert(base>=0);
551 leader_directory_.base_ = base;
552}
553
554//////////////////////////////
555
556inline void MfRecord::SetNvf(int nvf)
557// Sets the number of entries in the directory part
558{
559 assert(nvf>=0);
560 leader_directory_.nvf_ = nvf;
561}
562
563//////////////////////////////
564
565inline void MfRecord::SetStatus(int s)
566// Sets the status of the record
567{
568 leader_directory_.status_ = s;
569}
570
571//////////////////////////////
572
573inline void MfRecord::SetState(int s)
574// Sets the status of the record
575{
576 assert(s==MfRecord::Record_Empty || s==MfRecord::Record_Read
577 || s==MfRecord::Record_Changed || s==MfRecord::Record_Created);
578 state_ = s;
579}
580
581inline void MfRecord::SetMfbRead(mg_s_long b)
582{
583 mfb_read_ = b;
584}
585
586inline void MfRecord::SetMfpRead(int pos)
587{
588 mfp_read_ = pos;
589}
590
591inline void MfRecord::SetMflenRead(int len)
592{
593 mflen_read_ = len;
594}
595
596inline int MfRecord::GetFieldTag(int i)
597{
598 return leader_directory_.dir_[i].tag_;
599}
600inline int MfRecord::GetFieldPos(int i)
601{
602 return leader_directory_.dir_[i].pos_;
603}
604
605inline int MfRecord::GetFieldLen(int i)
606{
607 return leader_directory_.dir_[i].len_;
608}
609
610#endif
Note: See TracBrowser for help on using the repository browser.