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