/********************************************************************** * * Unimarc.h * Copyright (C) 2003 UNESCO * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #ifndef MARC_RECORD #define MARC_RECORD #define SUBFDELIM '\037' // % #define FIELDTERM '\036' // $ #define RECTERM '\035' // # sharp #define MARC_LEADER_LEN 24 #define MARC_DIRENT_LEN 12 #define MARC_FMT_BRIEF 0 #define MARC_FMT_FULL 1 //--------------------- // UNIMARC Record Label //--------------------- struct MarcLeader { char lreclen_[5]; /* logical record length */ char status_; /* record status_ */ char type_; /* type_ of record */ char bibLevel_; /* bibliographic level */ char ctrlType_; /* type_ of control */ char undPos_; /* undefined character position */ char indCount_; /* indicator count */ char scd_; /* subfield code count */ char base_[5]; /* base_ address of data */ char encLevel_; /* encoding level */ char dcf_; /* descriptive cataloging form */ char lrr_; /* linked record requirement */ char llof_; /* length of the length-of-field portion */ char lscp_; /* length of starting-character-position portion */ char lidp_; /* length of implementation-defined portion */ char uep_; /* undefined entry map character position */ MarcLeader() { lreclen_[0]=' '; lreclen_[1]=' '; lreclen_[2]=' '; lreclen_[3]=' '; lreclen_[4]=' '; status_ = '0'; // New record type_ = '0'; // Language materials, printed bibLevel_ = '0'; // Monographic ctrlType_ = '0'; // Hierarchical relationship undefined undPos_ = '0'; // Undefined, contains a blank indCount_ = '0'; // Invariably 2 in UNIMARC scd_ = '0'; // Invariably 2 in UNIMARC base_[0] = ' '; // Base_ address of data base_[1] = ' '; base_[2] = ' '; base_[3] = ' '; base_[4] = ' '; encLevel_ = '0'; // (Blank) full level dcf_ = '0'; // (Blank) record is in full ISBD form lrr_ = '0'; // Undefined, contains a blank llof_ = '4'; // Length of the length-of-field portion lscp_ = '5'; // Length of starting-character-position portion lidp_ = '0'; // Length of implementation-defined portion uep_ = '0'; // Undefined, contains a blank } friend std::ostream& operator<<(std::ostream& s, const MarcLeader& leader); friend std::istream& operator>>(std::istream& s, MarcLeader& leader); }; //---------------- // Directory entry //---------------- struct DirectoryEntry { char tag_[3]; /* tag */ char len_[4]; /* field length */ char scp_[5]; /* starting character position */ friend std::ostream& operator<<(std::ostream& s, const DirectoryEntry& de); friend std::istream& operator>>(std::istream& s, DirectoryEntry& leader); }; inline std::istream& operator>>(std::istream& s, DirectoryEntry& de) { s.read(de.tag_, 3); s.read(de.len_, 4); s.read(de.scp_, 5); return s; } inline std::ostream& operator<<(std::ostream& s, const DirectoryEntry& de) { s.write(de.tag_, 3); s.write(de.len_, 4); s.write(de.scp_, 5); return s; } //------------------ // Subfield item //------------------ struct MarcField { int len_; char* data_; }; //------------------- // Directory entry //------------------- struct MarcDirectoryEntry { char* tag_; std::vector field_; }; //--------------------------- // UNIMARC record structure //--------------------------- class MarcRecord { protected: MarcLeader leader_; char* data_; int length_; int dirCount_; int encapsulated_; std::vector directory_; int ParseMarcRecord(); int AddSubFields(MarcDirectoryEntry& d, char* b); public: MarcRecord(char* data, int length, int copyData); ~MarcRecord(); void PrintDetailed(FILE* fp); void Get(char* buf,int maxlen,int format); int GetSubField(char* tag, char subtag, char* buf, int maxlen); int GetField(char* tag, char* buf, int maxlen); int GetSubFields(char* tag, char subtag, char* buf, int maxlen); int HasField(char* tag); int HasSubField(char* tag, char subtag); void Format(char* buf, int maxlen, int format); int RecordLength(); int PrettyFormat(char* format, char* buf, int maxlen); void Dump (); }; #endif