/* * CSI2131 Winter 2005 * * Assignment#2 Solution : Implementation of The Record class * * Shantanu Das */ #include "Record.h" Record::Record() //Constructor { year = term = key = 0; // initialize fields to default values. section=' '; code = new char[8]; strcpy(code,"0000000"); cname=pname=clink=plink=NULL; s5 = s6 = s7 = s8 = 0; size = 8; } Record::~Record() // Destructor { delete[] code; if(cname!=NULL) delete[] cname; if(pname!=NULL) delete[] pname; if(clink!=NULL) delete[] clink; if(plink!=NULL) delete[] plink; } long Record::getkey() // return the key { if(key==0) makekey(); return key; } int Record::getsize() { return size; } long Record::makekey() // construct the key { unsigned char byte1,kfield[4]; unsigned short int byte23; char byte4; int code1=0,code2=0; // code1 is first part(CSI) and code2 is second part(2131) if(strncmp(code,"CEG",3)==0) code1=0; // encode the initial part of code else if(strncmp(code,"CSI",3)==0) code1=1; else if(strncmp(code,"ELG",3)==0) code1=2; else if(strncmp(code,"GNG",3)==0) code1=3; else if(strncmp(code,"SEG",3)==0) code1=4; code2 = atoi(&(code[3])); // encode the numeric part of code byte1 = year*3+term; // byte-1 contains year and term byte23 = (code2*5)+code1; // byte-2 & 3 contains code byte4 = section; // byte-4 contains section unsigned short int *kfield12 = (unsigned short int *)&(kfield[1]); //interpret part of the kfield array, as short int kfield[0] = byte1; // write the key part into a char array (*kfield12) = byte23; kfield[3] = byte4; key = *((long*)kfield); // convert the array containing the key, into a long integer return key; } void Record::setyear(int yr) // yr = 1997-2081 { if (yr < START || yr > (START+84)) { // check for valid year value cerr << "\nError: year out of range :" << yr << endl; exit(1); } year = yr - START; } void Record::setterm(int t) { if (t >= 0 && t < 3) term = t; else { cerr << "\nError: Invalid Semester " << t << endl; exit(1); } } void Record::setcode(const char* cd) { strncpy(code,cd,7); } void Record::setsec(char s) { if((s < 'A' || s > 'Z') && s!=' ' ) // check for invalid section return; section = s; } void Record::setcname(const char* str, int n) // set field-5 (Course Name) { if(cname!=NULL) delete[] cname; cname = new char[n+1]; // allocate memory for storing the field size += (n - s5); // update size s5 = n; strncpy(cname,str,n); } void Record::setpname(const char* str, int n) // set field-6 (Prof's Name) { if(pname!=NULL) delete[] pname; pname = new char[n+1]; // allocate memory for storing the field size += (n - s6); // update size s6 = n; strncpy(pname,str,n); } void Record::setclink(const char* str, int n) // set field-7 (Course webpage) { if(clink!=NULL) delete[] clink; clink = new char[n+1]; // allocate memory for storing the field size += (n - s7); // update size s7 = n; strncpy(clink,str,n); } void Record::setplink(const char* str, int n) // set field-8 (Prof's webpage) { if(plink!=NULL) delete[] plink; plink = new char[n+1]; // allocate memory for storing the field size += (n - s8); // update size s8 = n; strncpy(plink,str,n); } int Record::read(istream& fs) { unsigned char byte1,byte4; short int numcode = 0; fs.read((char*)&byte1,1); // read the first byte fs.read((char*)&numcode,2); // read the next two bytes fs.read((char*)&byte4,1); // read the fourth byte if(fs.fail()) return false; year = (byte1)/3; // extract and set year field term = (byte1 % 3); // extract and set term field switch(numcode % 5){ case 0:sprintf(code,"CEG%04d",(numcode)/5);break; case 1:sprintf(code,"CSI%04d",(numcode)/5);break; case 2:sprintf(code,"ELG%04d",(numcode)/5);break; case 3:sprintf(code,"GNG%04d",(numcode)/5);break; case 4:sprintf(code,"SEG%04d",(numcode)/5);break; } section = byte4; //set the section makekey(); // set the key string str; getline(fs,str,'|'); // read field-5 if(fs.fail()) return -1; setcname(str.c_str(),str.length()); getline(fs,str,'|'); // read field-6 if(fs.fail()) return -1; setpname(str.c_str(),str.length()); getline(fs,str,'|'); // read field-7 if(fs.fail()) return -1; setclink(str.c_str(),str.length()); getline(fs,str,'|'); // read field-8 if(fs.fail()) return -1; setplink(str.c_str(),str.length()); return size; // return number of bytes read } int Record::write(ostream& fs) { if(key==0) makekey(); //construct key if not already done fs.write((char*)&key,4); fs.write(cname,s5);fs.write("|",1); fs.write(pname,s6);fs.write("|",1); fs.write(clink,s7);fs.write("|",1); fs.write(plink,s8);fs.write("|",1); if(fs.good()) return size; // successfully written size bytes else return -1; // error in writing the record } void Record::printkey(ostream& fs) // print only the key part { fs << "\nYear: "<< START+year; switch(term){ case 0: fs << "\nTerm: Fall"; break; case 1: fs << "\nTerm: Winter"; break; case 2: fs << "\nTerm: Summer"; break; } fs << "\nCode: "; fs.write(code,7); fs << "\nSection: "<< section <