1 // Program name: cfheader.cpp
2 // Programmed by: Anthony Barbachan
3 // Programmed in: C++ (Turbo C++ 3.0 Compatable)
4 // Purpose: Source file for a cabinet file header object.
5 // Version: 1.00
6 // Last modified on: 11/5/1998
7 // Version: 1.00a
8 // Last modified on: 11/29/1998
9 // Changes: Added code to check for errors while reading a string from stream.
10 // Version: 1.00b
11 // Last modified on: 12/6/1998
12 // Changes: Modified error checking code to check for short reads as well.
13 // Version: 2.00
14 // Last modification date: 10-18-1999
15 // Changes: Replaced code with new classes' code.
16 
17 #ifndef __CFHEADER_CPP__
18 #define __CFHEADER_CPP__
19 
20 #include <string.h>
21 #include <fstream>
22 #include "bstring.h"
23 #include "cftypes.h"
24 #include "cfheader.h"
25 
26 #ifdef unix
27 #include <strstream>
28 #else
29 #include <strstrea.h>
30 #endif
31 
32 using std::ios;
33 using std::ifstream;
34 using std::ofstream;
35 using std::ostrstream;
36 using std::ends;
37 
38 ////////////////////////////////////////****************************************
39 
40 // Initializes a valid fixed cabinet header
41 
init()42 void cabinet_fixed_header::init()
43 {
44 	clear();							// Everything set to zeros
45 	memcpy(signature, "MSCF", 4);			// Set signature
46 	size = sizeof(*this);				// Set cabinet size to header size
47 	files_offset = sizeof(*this);			// Sets files offset after header
48 	version_minor = 3;					// Version set to 1.3
49 	version_minor = 1;
50 }
51 
52 ////////////////////////////////////////****************************************
53 
54 // Read the cabinet fixed header information from a input stream
55 
read(istream & in)56 Error cabinet_fixed_header::read(istream& in)
57 {
58 	return  (in.read((char *) this, sizeof(*this)).bad())
59 			? ((in.fail()) ? READ_ERROR : UNEXPECTED_EOF) : OK;
60 }
61 
62 ////////////////////////////////////////****************************************
63 
64 // Write the cabinet fixed header information to a output stream
65 
write(ostream & out)66 Error cabinet_fixed_header::write(ostream& out)
67 {
68 	return (out.write((char *) this, sizeof(*this)).fail()) ? WRITE_ERROR : OK;
69 }
70 
71 ////////////////////////////////////////****************************************
72 
73 // Returns: OK, READ_ERROR, UNEXPECTED_EOF.
74 //			OK - operation completed normally
75 //			READ_ERROR - An error occured while read the data
76 //			UNEXPECTED_EOF - The EOF was occured before the end of the string
77 
read_string(b_string & str,istream & in)78 Error cabinet_header::read_string(b_string& str, istream& in)
79 {
80 	char ch = '\0';
81 	char* temp = NULL;
82 	ostrstream buf;
83 
84 	if(in.get(ch).bad())
85 	{
86 		return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF;
87 	}
88 
89 	while(ch != '\0')
90 	{
91 		buf << ch;
92 
93 		if(in.get(ch).bad())
94 		{
95 			return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF;
96 		}
97 	}
98 
99 	buf << ends;
100 	temp = buf.str();
101 	str = temp;
102 	delete[] temp;
103 	return OK;
104 }
105 
106 ////////////////////////////////////////****************************************
107 
read(istream & in)108 Error cabinet_header::read(istream& in)
109 {
110 	Error err = OK;
111 	struct
112 	{
113 		word cabinet_ra;
114 		byte folder_ra;
115 		byte datablock_ra;
116 	} size = { (word) 0u, (byte) 0u, (byte) 0u };
117 
118 	clear_class_variables();
119 	if((err = cabinet_fixed_header::read(in)) != OK) return err;
120 
121 	if(has_reserved_area())			// If cab has a reserved area
122 	{
123 		if(in.read((char *) &size, sizeof(size)).bad())
124 		{
125 			return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF;
126 		}
127 
128 		cabinet_ra_size = size.cabinet_ra;
129 		folder_ra_size = size.folder_ra;
130 		datablock_ra_size = size.datablock_ra;
131 
132 		if(cabinet_ra_size > 0)			// If has cabinet reserved area
133 		{
134 			reserved_area = new byte[cabinet_ra_size];
135 
136 			if(in.read((char*)reserved_area, cabinet_ra_size).bad())
137 			{
138 				return (in.fail()) ? READ_ERROR : UNEXPECTED_EOF;
139 			}
140 		}
141 	}
142 
143 	if(has_prev())
144 	{
145 		if((err = read_string(prev_cabinet, in)) != OK) { return err; }
146 		if((err = read_string(prev_disk, in)) != OK) { return err; }
147 	}
148 
149 	if(has_next())
150 	{
151 		if((err = read_string(next_cabinet, in)) != OK) { return err; }
152 		if((err = read_string(next_disk, in)) != OK) { return err; }
153 	}
154 
155 	return OK;
156 }
157 
158 ////////////////////////////////////////****************************************
159 
write(ostream & out)160 Error cabinet_header::write(ostream& out)
161 {
162 	Error err = OK;
163 	struct
164 	{
165 		word cabinet_ra;
166 		byte folder_ra;
167 		byte datablock_ra;
168 	} size = { cabinet_ra_size, folder_ra_size, datablock_ra_size };
169 
170 	if((err = cabinet_fixed_header::write(out)) != OK) return err;
171 
172 	if(has_reserved_area())			// If cab has a reserved area
173 	{
174 		if(out.write((char *) &size, sizeof(size)).fail())
175 		{
176 			return WRITE_ERROR;
177 		}
178 
179 		if(cabinet_ra_size > 0)			// If has cabinet reserved area
180 		{
181 			if(out.write((char*)reserved_area, cabinet_ra_size).fail())
182 			{
183 				return WRITE_ERROR;
184 			}
185 		}
186 	}
187 
188 	if(has_prev())
189 	{
190 		if(out.write(prev_cabinet, prev_cabinet.length() + 1u).fail())
191 		{
192 			return WRITE_ERROR;
193 		}
194 
195 		if(out.write(prev_disk, prev_disk.length() + 1u).fail())
196 		{
197 			return WRITE_ERROR;
198 		}
199 	}
200 
201 	if(has_next())
202 	{
203 		if(out.write(next_cabinet, next_cabinet.length() + 1u).fail())
204 		{
205 			return WRITE_ERROR;
206 		}
207 
208 		if(out.write(next_disk, next_disk.length() + 1u).fail())
209 		{
210 			return WRITE_ERROR;
211 		}
212 	}
213 
214 	return OK;
215 }
216 
217 ////////////////////////////////////////****************************************
218 
219 #endif
220