// Program name: cfheader.cpp // Programmed by: Anthony Barbachan // Programmed in: C++ (Turbo C++ 3.0 Compatable) // Purpose: Source file for a cabinet file header object. // Version: 1.00 // Last modified on: 11/5/1998 // Version: 1.00a // Last modified on: 11/29/1998 // Changes: Added code to check for errors while reading a string from stream. // Version: 1.00b // Last modified on: 12/6/1998 // Changes: Modified error checking code to check for short reads as well. // Version: 2.00 // Last modification date: 10-18-1999 // Changes: Replaced code with new classes' code. #ifndef __CFHEADER_CPP__ #define __CFHEADER_CPP__ #include #include #include "bstring.h" #include "cftypes.h" #include "cfheader.h" #ifdef unix #include #else #include #endif using std::ostrstream; using std::ends; ////////////////////////////////////////**************************************** // Initializes a valid fixed cabinet header void cabinet_fixed_header::init() { clear(); // Everything set to zeros memcpy(signature, "MSCF", 4); // Set signature size = sizeof(*this); // Set cabinet size to header size files_offset = sizeof(*this); // Sets files offset after header version_minor = 3; // Version set to 1.3 version_minor = 1; } ////////////////////////////////////////**************************************** // Read the cabinet fixed header information from a input stream Error cabinet_fixed_header::read(istream& in) { return (in.read((char *) this, sizeof(*this)).bad()) ? ((in.fail()) ? READ_ERROR : UNEXPECTED_EOF) : OK; } ////////////////////////////////////////**************************************** // Write the cabinet fixed header information to a output stream Error cabinet_fixed_header::write(ostream& out) { return (out.write((char *) this, sizeof(*this)).fail()) ? WRITE_ERROR : OK; } ////////////////////////////////////////**************************************** // Returns: OK, READ_ERROR, UNEXPECTED_EOF. // OK - operation completed normally // READ_ERROR - An error occured while read the data // UNEXPECTED_EOF - The EOF was occured before the end of the string Error cabinet_header::read_string(b_string& str, istream& in) { char ch = '\0'; char* temp = NULL; ostrstream buf; if(in.get(ch).bad()) { return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF; } while(ch != '\0') { buf << ch; if(in.get(ch).bad()) { return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF; } } buf << ends; temp = buf.str(); str = temp; delete[] temp; return OK; } ////////////////////////////////////////**************************************** Error cabinet_header::read(istream& in) { Error err = OK; struct { word cabinet_ra; byte folder_ra; byte datablock_ra; } size = { (word) 0u, (byte) 0u, (byte) 0u }; clear_class_variables(); if((err = cabinet_fixed_header::read(in)) != OK) return err; if(has_reserved_area()) // If cab has a reserved area { if(in.read((char *) &size, sizeof(size)).bad()) { return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF; } cabinet_ra_size = size.cabinet_ra; folder_ra_size = size.folder_ra; datablock_ra_size = size.datablock_ra; if(cabinet_ra_size > 0) // If has cabinet reserved area { reserved_area = new byte[cabinet_ra_size]; if(in.read((char*)reserved_area, cabinet_ra_size).bad()) { return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF; } } } if(has_prev()) { if((err = read_string(prev_cabinet, in)) != OK) { return err; } if((err = read_string(prev_disk, in)) != OK) { return err; } } if(has_next()) { if((err = read_string(next_cabinet, in)) != OK) { return err; } if((err = read_string(next_disk, in)) != OK) { return err; } } return OK; } ////////////////////////////////////////**************************************** Error cabinet_header::write(ostream& out) { Error err = OK; struct { word cabinet_ra; byte folder_ra; byte datablock_ra; } size = { cabinet_ra_size, folder_ra_size, datablock_ra_size }; if((err = cabinet_fixed_header::write(out)) != OK) return err; if(has_reserved_area()) // If cab has a reserved area { if(out.write((char *) &size, sizeof(size)).fail()) { return WRITE_ERROR; } if(cabinet_ra_size > 0) // If has cabinet reserved area { if(out.write((char*)reserved_area, cabinet_ra_size).fail()) { return WRITE_ERROR; } } } if(has_prev()) { if(out.write(prev_cabinet, prev_cabinet.length() + 1u).fail()) { return WRITE_ERROR; } if(out.write(prev_disk, prev_disk.length() + 1u).fail()) { return WRITE_ERROR; } } if(has_next()) { if(out.write(next_cabinet, next_cabinet.length() + 1u).fail()) { return WRITE_ERROR; } if(out.write(next_disk, next_disk.length() + 1u).fail()) { return WRITE_ERROR; } } return OK; } ////////////////////////////////////////**************************************** #endif