1 // Program name: cffile.h
2 // Programmed by: Anthony Barbachan
3 // Programmed in: C++ (Turbo C++ 3.0 Compatable)
4 // Purpose: Header file for a cabinet file folder 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 support for directory and volume attributes. Fixed memset use.
10 // Version: 2.00
11 // Last modification date: 10-18-1999
12 // Changes: Replaced code with new classes' code.
13 
14 #ifndef __CFFILE_H__
15 #define __CFFILE_H__
16 
17 #include <string.h>
18 #include <fstream>
19 #include "bstring.h"
20 #include "cftypes.h"
21 
22 ////////////////////////////////////////////////////////////////////////////////
23 
24 class cabinet_file_fixed_header
25 {
26 	public:
27 		enum
28 		{
29 			CONTINUED_FROM_PREV = 0xFFFDU,
30 			CONTINUED_TO_NEXT = 0xFFFEU,
31 			CONTINUED_PREV_AND_NEXT = 0xFFFFU
32 		};
33 		enum
34 		{
35 			A_RDONLY = 0x01,
36 			A_HIDDEN = 0x02,
37 			A_SYSTEM = 0x04,
38 			A_VOLUME = 0x08,			// Gotten from Dr. Dobbs CABLIB
39 			A_DIRECTORY = 0x10,			// Gotten from Dr. Dobbs CABLIB
40 			A_ARCHIVE = 0x20,
41 			A_EXECUTE = 0x40,
42 			A_NAME_IS_UTF = 0x80
43 		};
44 		struct Date
45 		{
46 			unsigned day: 5;
47 			unsigned month: 4;
48 			unsigned year: 7;
49 		};
50 		struct Time
51 		{
52 			unsigned second: 5;
53 			unsigned minute: 6;
54 			unsigned hour: 5;
55 		};
56 	protected:
57 		dword size;	    	// uncompressed size of this file in bytes
58 		dword offset;		// uncompressed offset of this file in the folder
59 		word folder;	    	// index into the CFFOLDER area
60 		word date;	    	// date stamp for this file
61 		word time;	    	// time stamp for this file
62 		word attribs;	    	// attribute flags for this file
63 	private:
clear_variables()64 		void clear_variables() { memset(this, 0, sizeof(*this)); }
65 	public:
cabinet_file_fixed_header()66 		cabinet_file_fixed_header() { clear_variables(); }
~cabinet_file_fixed_header()67 		~cabinet_file_fixed_header() {}
68 
clear()69 		void clear() { clear_variables(); }
70 		Error read(istream& in);
71 		Error write(ostream& out);
72 
get_size()73 		dword get_size() { return size; }
set_size(dword len)74 		void set_size(dword len) { size = len; }
get_offset()75 		dword get_offset() { return offset; }
set_offset(dword off)76 		void set_offset(dword off) { offset = off; }
get_folder()77 		word get_folder() { return folder; }
set_folder(word f)78 		void set_folder(word f) { folder = f; }
get_date()79 		word get_date() { return date; }
set_date(word d)80 		void set_date(word d) { date = d; }
set_date(word m,word d,word y)81 		void set_date(word m, word d, word y)
82 			{ date = ((y - 1980) << 9) + (m << 5) + d; }
get_time()83 		word get_time() { return time; }
set_time(word t)84 		void set_time(word t) { time = t; }
set_time(word h,word m,word s)85 		void set_time(word h, word m, word s)
86 			{ time = (h << 11) + (m << 5) + (s / 2); }
get_attribs()87 		word get_attribs() { return attribs; }
set_attribs(word a)88 		void set_attribs(word a) { attribs = a; }
89 
continued_from_prev()90 		int continued_from_prev() { return folder == (unsigned) CONTINUED_FROM_PREV; }
continues_in_next()91 		int continues_in_next() { return folder == (unsigned) CONTINUED_TO_NEXT; }
continued_from_prev_and_in_next()92 		int continued_from_prev_and_in_next()
93 			{ return folder == (unsigned) CONTINUED_PREV_AND_NEXT; }
compeletely_within_cabinet()94 		int compeletely_within_cabinet()
95 		{
96 			return (folder != (unsigned) CONTINUED_FROM_PREV) &&
97 				  (folder != (unsigned) CONTINUED_TO_NEXT) &&
98 				  (folder != (unsigned) CONTINUED_PREV_AND_NEXT);
99 		}
not_compeletely_within_cabinet()100 		int not_compeletely_within_cabinet()
101 		{
102 			return (folder == (unsigned) CONTINUED_FROM_PREV) ||
103 				  (folder == (unsigned) CONTINUED_TO_NEXT) ||
104 				  (folder == (unsigned) CONTINUED_PREV_AND_NEXT);
105 		}
is_readonly()106 		int is_readonly() { return attribs & A_RDONLY; }
is_hidden()107 		int is_hidden() { return attribs & A_HIDDEN; }
is_system()108 		int is_system() { return attribs & A_SYSTEM; }
is_directory()109 		int is_directory() { return attribs & A_DIRECTORY; }
is_volume()110 		int is_volume() { return attribs & A_VOLUME; }
is_archive()111 		int is_archive() { return attribs & A_ARCHIVE; }
must_execute()112 		int must_execute() { return attribs & A_EXECUTE; }
name_is_utf()113 		int name_is_utf() { return attribs & A_NAME_IS_UTF; }
114 		// ((Year - 1980) << 9) + (Month << 5) + Day;
year()115 		unsigned year() { return ((Date *) &date)->year + 1980; }
month()116 		unsigned month() { return ((Date *) &date)->month; }
day()117 		unsigned day() { return ((Date *) &date)->day; }
118 		// (Hour << 11) + (Minutes << 5) + (Seconds / 2)
hour()119 		unsigned hour() { return ((Time *) &time)->hour; }
minute()120 		unsigned minute() { return ((Time *) &time)->minute; }
second()121 		unsigned second() { return ((Time *) &time)->second * 2; }
122 
has_special_folder_number()123 		int has_special_folder_number()
124 		{
125 			return (folder == (unsigned) CONTINUED_FROM_PREV) ||
126 				  (folder == (unsigned) CONTINUED_TO_NEXT) ||
127 				  (folder == (unsigned) CONTINUED_PREV_AND_NEXT);
128 		}
hasnt_special_folder_number()129 		int hasnt_special_folder_number()
130 		{
131 			return (folder != (unsigned) CONTINUED_FROM_PREV) &&
132 				  (folder != (unsigned) CONTINUED_TO_NEXT) &&
133 				  (folder != (unsigned) CONTINUED_PREV_AND_NEXT);
134 		}
135 };
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 
139 class cabinet_file_header : public cabinet_file_fixed_header
140 {
141 	protected:
142 		b_string name;			// name of this file
143 	private:
clear_local_variables()144 		void clear_local_variables() { name.clear(); }
145 	public:
cabinet_file_header()146 		cabinet_file_header() {}
~cabinet_file_header()147 		~cabinet_file_header() {}
148 
clear()149 		void clear()
150 		{
151 			clear_local_variables();
152 			cabinet_file_fixed_header::clear();
153 		}
154 		Error read(istream& in);
155 		Error write(ostream& out);
156 
get_name()157 		const char* get_name() { return (const char *) name; }
set_name(const char * n)158 		void set_name(const char* n) { name = n; }
set_name(b_string & n)159 		void set_name(b_string& n) { name = n; }
160 };
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 
164 #endif
165