xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.h (revision 4f0e6a75b3edcd20727a2f2b79a334a7e2dc3380)
1ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
2ead0c3e2STyler Dauwalder // This software is part of the OpenBeOS distribution and is covered
3ead0c3e2STyler Dauwalder //  by the OpenBeOS license.
4ead0c3e2STyler Dauwalder //
5ead0c3e2STyler Dauwalder //  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6ead0c3e2STyler Dauwalder //---------------------------------------------------------------------
7ead0c3e2STyler Dauwalder #ifndef _UDF_DISK_STRUCTURES_H
8ead0c3e2STyler Dauwalder #define _UDF_DISK_STRUCTURES_H
9ead0c3e2STyler Dauwalder 
10ead0c3e2STyler Dauwalder #include <string.h>
11ead0c3e2STyler Dauwalder 
12ead0c3e2STyler Dauwalder #include <ByteOrder.h>
13ead0c3e2STyler Dauwalder #include <SupportDefs.h>
14ead0c3e2STyler Dauwalder 
15ead0c3e2STyler Dauwalder #include "kernel_cpp.h"
16ead0c3e2STyler Dauwalder #include "UdfDebug.h"
17ead0c3e2STyler Dauwalder 
18ead0c3e2STyler Dauwalder #include "Array.h"
19ead0c3e2STyler Dauwalder 
20c21aaa8aSTyler Dauwalder /*! \file UdfStructures.h
21ead0c3e2STyler Dauwalder 
22ead0c3e2STyler Dauwalder 	\brief UDF on-disk data structure declarations
23ead0c3e2STyler Dauwalder 
24ead0c3e2STyler Dauwalder 	UDF is a specialization of the ECMA-167 standard. For the most part,
25ead0c3e2STyler Dauwalder 	ECMA-167 structures are used by UDF with special restrictions. In a
26ead0c3e2STyler Dauwalder 	few instances, UDF introduces its own structures to augment those
27ead0c3e2STyler Dauwalder 	supplied by ECMA-167; those structures are clearly marked.
28ead0c3e2STyler Dauwalder 
29ead0c3e2STyler Dauwalder 	For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a>
30ead0c3e2STyler Dauwalder 	For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a>
31ead0c3e2STyler Dauwalder 
32ead0c3e2STyler Dauwalder 	For lack of a better place to store this info, the structures that
33ead0c3e2STyler Dauwalder 	are allowed to have length greater than the logical block size are
34ead0c3e2STyler Dauwalder 	as follows (other length restrictions may be found in UDF-2.01 5.1):
35ead0c3e2STyler Dauwalder 	- \c logical_volume_descriptor
36ead0c3e2STyler Dauwalder 	- \c unallocated_space_descriptor
37ead0c3e2STyler Dauwalder 	- \c logical_volume_integrity_descriptor
38ead0c3e2STyler Dauwalder 	- \c space_bitmap_descriptor
39ead0c3e2STyler Dauwalder 
40ead0c3e2STyler Dauwalder 	Other links of interest:
41ead0c3e2STyler Dauwalder 	- <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a>
42ead0c3e2STyler Dauwalder 	- <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a>
43ead0c3e2STyler Dauwalder */
44ead0c3e2STyler Dauwalder 
45ead0c3e2STyler Dauwalder namespace Udf {
46ead0c3e2STyler Dauwalder 
47ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
48ead0c3e2STyler Dauwalder // ECMA-167 Part 1
49ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
50ead0c3e2STyler Dauwalder 
51ead0c3e2STyler Dauwalder /*! \brief Character set specifications
52ead0c3e2STyler Dauwalder 
53ead0c3e2STyler Dauwalder 	The character_set_info field shall be set to the ASCII string
54ead0c3e2STyler Dauwalder 	"OSTA Compressed Unicode" (padded right with NULL chars).
55ead0c3e2STyler Dauwalder 
56ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
57ead0c3e2STyler Dauwalder */
58ead0c3e2STyler Dauwalder struct charspec {
59ead0c3e2STyler Dauwalder public:
601801834fSTyler Dauwalder 	charspec(uint8 type = 0, const char *info = NULL);
611801834fSTyler Dauwalder 
62ead0c3e2STyler Dauwalder 	void dump() const;
63ead0c3e2STyler Dauwalder 
64ead0c3e2STyler Dauwalder 	uint8 character_set_type() const { return _character_set_type; }
65ead0c3e2STyler Dauwalder 	const char* character_set_info() const { return _character_set_info; }
66ead0c3e2STyler Dauwalder 	char* character_set_info() { return _character_set_info; }
67ead0c3e2STyler Dauwalder 
68ead0c3e2STyler Dauwalder 	void set_character_set_type(uint8 type) { _character_set_type = type; }
691801834fSTyler Dauwalder 	void set_character_set_info(const char *info);
70ead0c3e2STyler Dauwalder private:
71ead0c3e2STyler Dauwalder 	uint8 _character_set_type;	//!< to be set to 0 to indicate CS0
72ead0c3e2STyler Dauwalder 	char _character_set_info[63];	//!< "OSTA Compressed Unicode"
73ead0c3e2STyler Dauwalder } __attribute__((packed));
74ead0c3e2STyler Dauwalder 
751801834fSTyler Dauwalder extern const charspec kCs0CharacterSet;
76ead0c3e2STyler Dauwalder 
77ead0c3e2STyler Dauwalder /*! \brief Date and time stamp
78ead0c3e2STyler Dauwalder 
79ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
80ead0c3e2STyler Dauwalder */
81ead0c3e2STyler Dauwalder class timestamp {
82ead0c3e2STyler Dauwalder private:
83ead0c3e2STyler Dauwalder 	union type_and_timezone_accessor {
84ead0c3e2STyler Dauwalder 		uint16 type_and_timezone;
85ead0c3e2STyler Dauwalder 		struct {
86ead0c3e2STyler Dauwalder 			uint16 type:4,
87ead0c3e2STyler Dauwalder 			       timezone:12;
88ead0c3e2STyler Dauwalder 		} bits;
89ead0c3e2STyler Dauwalder 	};
90ead0c3e2STyler Dauwalder 
91ead0c3e2STyler Dauwalder public:
929b438e89STyler Dauwalder 	timestamp() { _clear(); }
939b438e89STyler Dauwalder 	timestamp(time_t time);
949b438e89STyler Dauwalder 
95ead0c3e2STyler Dauwalder 	void dump() const;
96ead0c3e2STyler Dauwalder 
97ead0c3e2STyler Dauwalder 	// Get functions
98ead0c3e2STyler Dauwalder 	uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); }
99ead0c3e2STyler Dauwalder 	uint8 type() const {
100ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
101ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
102ead0c3e2STyler Dauwalder 		return t.bits.type;
103ead0c3e2STyler Dauwalder 	}
104ead0c3e2STyler Dauwalder 	int16 timezone() const {
105ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
106ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
1079b438e89STyler Dauwalder 		int16 result = t.bits.timezone;
1089b438e89STyler Dauwalder 		// Fill the lefmost bits with ones if timezone is negative
1099b438e89STyler Dauwalder 		result <<= 4;
1109b438e89STyler Dauwalder 		result >>= 4;
1119b438e89STyler Dauwalder 		return result;
112ead0c3e2STyler Dauwalder 	}
113ead0c3e2STyler Dauwalder 	uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); }
114ead0c3e2STyler Dauwalder 	uint8 month() const { return _month; }
115ead0c3e2STyler Dauwalder 	uint8 day() const { return _day; }
116ead0c3e2STyler Dauwalder 	uint8 hour() const { return _hour; }
117ead0c3e2STyler Dauwalder 	uint8 minute() const { return _minute; }
118ead0c3e2STyler Dauwalder 	uint8 second() const { return _second; }
119ead0c3e2STyler Dauwalder 	uint8 centisecond() const { return _centisecond; }
120ead0c3e2STyler Dauwalder 	uint8 hundred_microsecond() const { return _hundred_microsecond; }
121ead0c3e2STyler Dauwalder 	uint8 microsecond() const { return _microsecond; }
122ead0c3e2STyler Dauwalder 
123ead0c3e2STyler Dauwalder 	// Set functions
124ead0c3e2STyler Dauwalder 	void set_type_and_timezone(uint16 type_and_timezone) { _type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
125ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
126ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
127ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
128ead0c3e2STyler Dauwalder 		t.bits.type = type;
129ead0c3e2STyler Dauwalder 		set_type_and_timezone(t.type_and_timezone);
130ead0c3e2STyler Dauwalder 	}
131003d4e83STyler Dauwalder 	void set_timezone(int16 tz) {
132ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
133ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
134003d4e83STyler Dauwalder 		t.bits.timezone = tz;
135ead0c3e2STyler Dauwalder 		set_type_and_timezone(t.type_and_timezone);
136ead0c3e2STyler Dauwalder 	}
137ead0c3e2STyler Dauwalder 	void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
138ead0c3e2STyler Dauwalder 	void set_month(uint8 month) { _month = month; }
139ead0c3e2STyler Dauwalder 	void set_day(uint8 day) { _day = day; }
140ead0c3e2STyler Dauwalder 	void set_hour(uint8 hour) { _hour = hour; }
141ead0c3e2STyler Dauwalder 	void set_minute(uint8 minute) { _minute = minute; }
142ead0c3e2STyler Dauwalder 	void set_second(uint8 second) { _second = second; }
143ead0c3e2STyler Dauwalder 	void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
144ead0c3e2STyler Dauwalder 	void set_hundred_microsecond(uint8 hundred_microsecond) { _hundred_microsecond = hundred_microsecond; }
145ead0c3e2STyler Dauwalder 	void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
146ead0c3e2STyler Dauwalder private:
1479b438e89STyler Dauwalder 	void _clear();
1489b438e89STyler Dauwalder 
149ead0c3e2STyler Dauwalder 	uint16 _type_and_timezone;
150ead0c3e2STyler Dauwalder 	uint16 _year;
151ead0c3e2STyler Dauwalder 	uint8 _month;
152ead0c3e2STyler Dauwalder 	uint8 _day;
153ead0c3e2STyler Dauwalder 	uint8 _hour;
154ead0c3e2STyler Dauwalder 	uint8 _minute;
155ead0c3e2STyler Dauwalder 	uint8 _second;
156ead0c3e2STyler Dauwalder 	uint8 _centisecond;
157ead0c3e2STyler Dauwalder 	uint8 _hundred_microsecond;
158ead0c3e2STyler Dauwalder 	uint8 _microsecond;
159ead0c3e2STyler Dauwalder 
160ead0c3e2STyler Dauwalder } __attribute__((packed));
161ead0c3e2STyler Dauwalder 
162ead0c3e2STyler Dauwalder 
1639b438e89STyler Dauwalder /*! \brief Implementation ID Identify Suffix
1649b438e89STyler Dauwalder 
1659b438e89STyler Dauwalder 	See also: UDF 2.50 2.1.5.3
1669b438e89STyler Dauwalder */
1679b438e89STyler Dauwalder struct implementation_id_suffix {
1689b438e89STyler Dauwalder public:
1699b438e89STyler Dauwalder 	implementation_id_suffix(uint8 os_class, uint8 os_identifier);
1709b438e89STyler Dauwalder 
1719b438e89STyler Dauwalder 	uint8 os_class() const { return _os_class; }
1729b438e89STyler Dauwalder 	uint8 os_identifier() const { return _os_identifier; }
1739b438e89STyler Dauwalder 
1749b438e89STyler Dauwalder 	void set_os_class(uint8 os_class) { _os_class = os_class; }
1759b438e89STyler Dauwalder 	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
1769b438e89STyler Dauwalder private:
1779b438e89STyler Dauwalder 	uint8 _os_class;
1789b438e89STyler Dauwalder 	uint8 _os_identifier;
1799b438e89STyler Dauwalder 	array<uint8, 6> _implementation_use;
1809b438e89STyler Dauwalder };
1819b438e89STyler Dauwalder 
1829b438e89STyler Dauwalder /*! \brief Operating system classes for implementation_id_suffixes
1839b438e89STyler Dauwalder 
1849b438e89STyler Dauwalder 	See also: Udf 2.50 6.3
1859b438e89STyler Dauwalder */
1869b438e89STyler Dauwalder enum {
1879b438e89STyler Dauwalder 	OS_UNDEFINED = 0,
1889b438e89STyler Dauwalder 	OS_DOS,
1899b438e89STyler Dauwalder 	OS_OS2,
1909b438e89STyler Dauwalder 	OS_MACOS,
1919b438e89STyler Dauwalder 	OS_UNIX,
1929b438e89STyler Dauwalder 	OS_WIN9X,
1939b438e89STyler Dauwalder 	OS_WINNT,
1949b438e89STyler Dauwalder 	OS_OS400,
1959b438e89STyler Dauwalder 	OS_BEOS,
1969b438e89STyler Dauwalder 	OS_WINCE
1979b438e89STyler Dauwalder };
1989b438e89STyler Dauwalder 
1999b438e89STyler Dauwalder /*! \brief BeOS operating system classes identifiers for implementation_id_suffixes
2009b438e89STyler Dauwalder 
2019b438e89STyler Dauwalder 	See also: Udf 2.50 6.3
2029b438e89STyler Dauwalder */
2039b438e89STyler Dauwalder enum {
2049b438e89STyler Dauwalder 	BEOS_GENERIC = 0,
2059b438e89STyler Dauwalder 	BEOS_OPENBEOS = 1	// not part of the standard, but perhaps someday. :-)
2069b438e89STyler Dauwalder };
2079b438e89STyler Dauwalder 
208730ba00aSTyler Dauwalder /*! \brief Domain ID Identify Suffix
209730ba00aSTyler Dauwalder 
210730ba00aSTyler Dauwalder 	See also: UDF 2.50 2.1.5.3
211730ba00aSTyler Dauwalder */
212730ba00aSTyler Dauwalder struct domain_id_suffix {
213730ba00aSTyler Dauwalder public:
214730ba00aSTyler Dauwalder 	domain_id_suffix(uint16 udfRevision, uint8 domainFlags);
215730ba00aSTyler Dauwalder 
216730ba00aSTyler Dauwalder 	//! Note that revision 2.50 is denoted by 0x0250.
217730ba00aSTyler Dauwalder 	uint16 udf_revision() const { return _udf_revision; }
218730ba00aSTyler Dauwalder 	uint8 domain_flags() const { return _domain_flags; }
219730ba00aSTyler Dauwalder 
220730ba00aSTyler Dauwalder 	void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); }
221730ba00aSTyler Dauwalder 	void set_domain_flags(uint8 flags) { _domain_flags = flags; }
222730ba00aSTyler Dauwalder private:
223730ba00aSTyler Dauwalder 	uint8 _udf_revision;
224730ba00aSTyler Dauwalder 	uint8 _domain_flags;
225730ba00aSTyler Dauwalder 	array<uint8, 5> _reserved;
226730ba00aSTyler Dauwalder };
227730ba00aSTyler Dauwalder 
228730ba00aSTyler Dauwalder /*! \brief Domain flags
229730ba00aSTyler Dauwalder 
230730ba00aSTyler Dauwalder 	See also: UDF 2.50 2.1.5.3
231730ba00aSTyler Dauwalder */
232730ba00aSTyler Dauwalder enum {
233730ba00aSTyler Dauwalder 	DF_HARD_WRITE_PROTECT = 0x01,
234730ba00aSTyler Dauwalder 	DF_SOFT_WRITE_PROTECT = 0x02
235730ba00aSTyler Dauwalder };
236730ba00aSTyler Dauwalder 
237ead0c3e2STyler Dauwalder /*! \brief Identifier used to designate the implementation responsible
238ead0c3e2STyler Dauwalder 	for writing associated data structures on the medium.
239ead0c3e2STyler Dauwalder 
240ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.4, UDF 2.01 2.1.5
241ead0c3e2STyler Dauwalder */
242ead0c3e2STyler Dauwalder struct entity_id {
243ead0c3e2STyler Dauwalder public:
2449b438e89STyler Dauwalder 	static const int kIdentifierLength = 23;
2459b438e89STyler Dauwalder 	static const int kIdentifierSuffixLength = 8;
2469b438e89STyler Dauwalder 
247ead0c3e2STyler Dauwalder 	entity_id(uint8 flags = 0, char *identifier = NULL,
2489b438e89STyler Dauwalder 	          uint8 *identifier_suffix = NULL);
2499b438e89STyler Dauwalder 	entity_id(uint8 flags, char *identifier,
2509b438e89STyler Dauwalder 	          const implementation_id_suffix &suffix);
251730ba00aSTyler Dauwalder 	entity_id(uint8 flags, char *identifier,
252730ba00aSTyler Dauwalder 	          const domain_id_suffix &suffix);
253ead0c3e2STyler Dauwalder 
254ead0c3e2STyler Dauwalder 	void dump() const;
255ead0c3e2STyler Dauwalder 	bool matches(const entity_id &id) const;
256ead0c3e2STyler Dauwalder 
257ead0c3e2STyler Dauwalder 	// Get functions
258ead0c3e2STyler Dauwalder 	uint8 flags() const { return _flags; }
259ead0c3e2STyler Dauwalder 	const char* identifier() const { return _identifier; }
260ead0c3e2STyler Dauwalder 	char* identifier() { return _identifier; }
2619b438e89STyler Dauwalder 	const array<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; }
2629b438e89STyler Dauwalder 	array<uint8, kIdentifierSuffixLength>& identifier_suffix() { return _identifier_suffix; }
263ead0c3e2STyler Dauwalder 
264ead0c3e2STyler Dauwalder 	// Set functions
265ead0c3e2STyler Dauwalder 	void set_flags(uint8 flags) { _flags = flags; }
266ead0c3e2STyler Dauwalder private:
267ead0c3e2STyler Dauwalder 	uint8 _flags;
268ead0c3e2STyler Dauwalder 	char _identifier[kIdentifierLength];
2699b438e89STyler Dauwalder 	array<uint8, kIdentifierSuffixLength> _identifier_suffix;
270ead0c3e2STyler Dauwalder } __attribute__((packed));
271ead0c3e2STyler Dauwalder 
272ead0c3e2STyler Dauwalder extern const entity_id kMetadataPartitionMapId;
273ead0c3e2STyler Dauwalder extern const entity_id kSparablePartitionMapId;
274ead0c3e2STyler Dauwalder extern const entity_id kVirtualPartitionMapId;
2759b438e89STyler Dauwalder extern const entity_id kImplementationId;
276003d4e83STyler Dauwalder extern const entity_id kPartitionContentsId;
277730ba00aSTyler Dauwalder extern const entity_id kUdfId;
278ead0c3e2STyler Dauwalder 
279ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
280ead0c3e2STyler Dauwalder // ECMA-167 Part 2
281ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
282ead0c3e2STyler Dauwalder 
283ead0c3e2STyler Dauwalder 
284ead0c3e2STyler Dauwalder /*! \brief Header for volume structure descriptors
285ead0c3e2STyler Dauwalder 
286ead0c3e2STyler Dauwalder 	Each descriptor consumes an entire block. All unused trailing
287ead0c3e2STyler Dauwalder 	bytes in the descriptor should be set to 0.
288ead0c3e2STyler Dauwalder 
289ead0c3e2STyler Dauwalder 	The following descriptors contain no more information than
290ead0c3e2STyler Dauwalder 	that contained in the header:
291ead0c3e2STyler Dauwalder 
292ead0c3e2STyler Dauwalder 	- BEA01:
293ead0c3e2STyler Dauwalder 	  - type: 0
294ead0c3e2STyler Dauwalder 	  - id: "BEA01"
295ead0c3e2STyler Dauwalder 	  - version: 1
296ead0c3e2STyler Dauwalder 
297ead0c3e2STyler Dauwalder 	- TEA01:
298ead0c3e2STyler Dauwalder 	  - type: 0
299ead0c3e2STyler Dauwalder 	  - id: "TEA01"
300ead0c3e2STyler Dauwalder 	  - version: 1
301ead0c3e2STyler Dauwalder 
302ead0c3e2STyler Dauwalder 	- NSR03:
303ead0c3e2STyler Dauwalder 	  - type: 0
304ead0c3e2STyler Dauwalder 	  - id: "NSR03"
305ead0c3e2STyler Dauwalder 	  - version: 1
306ead0c3e2STyler Dauwalder 
307ead0c3e2STyler Dauwalder 	See also: ECMA 167 2/9.1
308ead0c3e2STyler Dauwalder */
309ead0c3e2STyler Dauwalder struct volume_structure_descriptor_header {
3102cc6b97aSTyler Dauwalder public:
3112cc6b97aSTyler Dauwalder 	volume_structure_descriptor_header(uint8 type, const char *id, uint8 version);
3122cc6b97aSTyler Dauwalder 
313ead0c3e2STyler Dauwalder 	uint8 type;
314ead0c3e2STyler Dauwalder 	char id[5];
315ead0c3e2STyler Dauwalder 	uint8 version;
316ead0c3e2STyler Dauwalder 
317ead0c3e2STyler Dauwalder 	bool id_matches(const char *id);
318ead0c3e2STyler Dauwalder } __attribute__((packed));
319ead0c3e2STyler Dauwalder 
320ead0c3e2STyler Dauwalder // Volume structure descriptor ids
321ead0c3e2STyler Dauwalder extern const char* kVSDID_BEA;
322ead0c3e2STyler Dauwalder extern const char* kVSDID_TEA;
323ead0c3e2STyler Dauwalder extern const char* kVSDID_BOOT;
324ead0c3e2STyler Dauwalder extern const char* kVSDID_ISO;
325ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_2;
326ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_3;
327ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA168;
328ead0c3e2STyler Dauwalder 
329ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
330ead0c3e2STyler Dauwalder // ECMA-167 Part 3
331ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
332ead0c3e2STyler Dauwalder 
333ead0c3e2STyler Dauwalder 
334ead0c3e2STyler Dauwalder /*! \brief Location and length of a contiguous chunk of data on the volume.
335ead0c3e2STyler Dauwalder 
336ead0c3e2STyler Dauwalder 	\c _location is an absolute block address.
337ead0c3e2STyler Dauwalder 
338ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/7.1
339ead0c3e2STyler Dauwalder */
340ead0c3e2STyler Dauwalder struct extent_address {
341ead0c3e2STyler Dauwalder public:
342c21aaa8aSTyler Dauwalder 	extent_address(uint32 location = 0, uint32 length = 0);
343c21aaa8aSTyler Dauwalder 
344ead0c3e2STyler Dauwalder 	void dump() const;
345ead0c3e2STyler Dauwalder 
346ead0c3e2STyler Dauwalder 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
347ead0c3e2STyler Dauwalder 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
348ead0c3e2STyler Dauwalder 
349ead0c3e2STyler Dauwalder 	void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
350ead0c3e2STyler Dauwalder 	void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
351ead0c3e2STyler Dauwalder private:
352ead0c3e2STyler Dauwalder 	uint32 _length;
353ead0c3e2STyler Dauwalder 	uint32 _location;
354ead0c3e2STyler Dauwalder } __attribute__((packed));
355ead0c3e2STyler Dauwalder 
356ead0c3e2STyler Dauwalder 
357ead0c3e2STyler Dauwalder /*! \brief Location of a logical block within a logical volume.
358ead0c3e2STyler Dauwalder 
359ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/7.1
360ead0c3e2STyler Dauwalder */
361ead0c3e2STyler Dauwalder struct logical_block_address {
362ead0c3e2STyler Dauwalder public:
363ead0c3e2STyler Dauwalder 	void dump() const;
364e631ed51STyler Dauwalder 	logical_block_address(uint16 partition = 0, uint32 block = 0);
365ead0c3e2STyler Dauwalder 
366ead0c3e2STyler Dauwalder 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
367ead0c3e2STyler Dauwalder 	uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); }
368ead0c3e2STyler Dauwalder 
369ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
370ead0c3e2STyler Dauwalder 	void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); }
371ead0c3e2STyler Dauwalder 
372ead0c3e2STyler Dauwalder private:
373ead0c3e2STyler Dauwalder 	uint32 _block;	//!< Block location relative to start of corresponding partition
374ead0c3e2STyler Dauwalder 	uint16 _partition;	//!< Numeric partition id within logical volume
375ead0c3e2STyler Dauwalder } __attribute__((packed));
376ead0c3e2STyler Dauwalder 
377ead0c3e2STyler Dauwalder /*! \brief Extent types used in short_address, long_address,
378ead0c3e2STyler Dauwalder 	and extended_address.
379ead0c3e2STyler Dauwalder 
380ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.14.1.1
381ead0c3e2STyler Dauwalder */
382ead0c3e2STyler Dauwalder enum extent_type {
383ead0c3e2STyler Dauwalder 	EXTENT_TYPE_RECORDED = 0,	//!< Allocated and recorded
384ead0c3e2STyler Dauwalder 	EXTENT_TYPE_ALLOCATED,		//!< Allocated but unrecorded
385ead0c3e2STyler Dauwalder 	EXTENT_TYPE_UNALLOCATED,	//!< Unallocated and unrecorded
386ead0c3e2STyler Dauwalder 	EXTENT_TYPE_CONTINUATION,	//!< Specifies next extent of descriptors
387ead0c3e2STyler Dauwalder };
388ead0c3e2STyler Dauwalder 
389ead0c3e2STyler Dauwalder 
390ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor.
391ead0c3e2STyler Dauwalder 
392ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/14.14.1
393ead0c3e2STyler Dauwalder */
394ead0c3e2STyler Dauwalder struct short_address {
395ead0c3e2STyler Dauwalder private:
396ead0c3e2STyler Dauwalder 	union type_and_length_accessor {
397ead0c3e2STyler Dauwalder 		uint32 type_and_length;
398ead0c3e2STyler Dauwalder 		struct {
399ead0c3e2STyler Dauwalder 			uint32 length:30,
400ead0c3e2STyler Dauwalder 			       type:2;
401ead0c3e2STyler Dauwalder //			uint32 type:2,
402ead0c3e2STyler Dauwalder //			       length:30;
403ead0c3e2STyler Dauwalder 		} bits;
404ead0c3e2STyler Dauwalder 	};
405ead0c3e2STyler Dauwalder 
406ead0c3e2STyler Dauwalder public:
407ead0c3e2STyler Dauwalder 	void dump() const;
408ead0c3e2STyler Dauwalder 
409ead0c3e2STyler Dauwalder 	uint8 type() const {
410ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
411ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
412ead0c3e2STyler Dauwalder 		return t.bits.type;
413ead0c3e2STyler Dauwalder 	}
414ead0c3e2STyler Dauwalder 	uint32 length() const {
415ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
416ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
417ead0c3e2STyler Dauwalder 		return t.bits.length;
418ead0c3e2STyler Dauwalder 	}
419ead0c3e2STyler Dauwalder 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
420ead0c3e2STyler Dauwalder 
421ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
422ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
423ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
424ead0c3e2STyler Dauwalder 		t.bits.type = type;
425ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
426ead0c3e2STyler Dauwalder 	}
427ead0c3e2STyler Dauwalder 	void set_length(uint32 length) {
428ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
429ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
430ead0c3e2STyler Dauwalder 		t.bits.length = length;
431ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
432ead0c3e2STyler Dauwalder 	}
433ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
434ead0c3e2STyler Dauwalder private:
435ead0c3e2STyler Dauwalder 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
436ead0c3e2STyler Dauwalder 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
437ead0c3e2STyler Dauwalder 
438ead0c3e2STyler Dauwalder 	uint32 _type_and_length;
439ead0c3e2STyler Dauwalder 	uint32 _block;
440ead0c3e2STyler Dauwalder } __attribute__((packed));
441ead0c3e2STyler Dauwalder 
442ead0c3e2STyler Dauwalder 
443ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor w/ 6 byte implementation use field.
444ead0c3e2STyler Dauwalder 
445ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/14.14.2
446ead0c3e2STyler Dauwalder */
447ead0c3e2STyler Dauwalder struct long_address {
448ead0c3e2STyler Dauwalder private:
449ead0c3e2STyler Dauwalder 	union type_and_length_accessor {
450ead0c3e2STyler Dauwalder 		uint32 type_and_length;
451ead0c3e2STyler Dauwalder 		struct {
452ead0c3e2STyler Dauwalder 			uint32 length:30,
453ead0c3e2STyler Dauwalder 			       type:2;
454ead0c3e2STyler Dauwalder 		} bits;
455ead0c3e2STyler Dauwalder 	};
456ead0c3e2STyler Dauwalder 
457ead0c3e2STyler Dauwalder public:
458d1a0387eSTyler Dauwalder 	long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0,
459d1a0387eSTyler Dauwalder 	             uint8 type = 0);
460d1a0387eSTyler Dauwalder 
461ead0c3e2STyler Dauwalder 	void dump() const;
462ead0c3e2STyler Dauwalder 
463ead0c3e2STyler Dauwalder 	uint8 type() const {
464ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
465ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
466ead0c3e2STyler Dauwalder 		return t.bits.type;
467ead0c3e2STyler Dauwalder 	}
468ead0c3e2STyler Dauwalder 	uint32 length() const {
469ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
470ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
471ead0c3e2STyler Dauwalder 		return t.bits.length;
472ead0c3e2STyler Dauwalder 	}
473ead0c3e2STyler Dauwalder 
474ead0c3e2STyler Dauwalder 	uint32 block() const { return _location.block(); }
475ead0c3e2STyler Dauwalder 	uint16 partition() const { return _location.partition(); }
476ead0c3e2STyler Dauwalder 
477ead0c3e2STyler Dauwalder 	const array<uint8, 6>& implementation_use() const { return _implementation_use; }
478ead0c3e2STyler Dauwalder 	array<uint8, 6>& implementation_use() { return _implementation_use; }
479ead0c3e2STyler Dauwalder 
480ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
481ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
482ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
483ead0c3e2STyler Dauwalder 		t.bits.type = type;
484ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
485ead0c3e2STyler Dauwalder 	}
486ead0c3e2STyler Dauwalder 	void set_length(uint32 length) {
487ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
488ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
489ead0c3e2STyler Dauwalder 		t.bits.length = length;
490ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
491ead0c3e2STyler Dauwalder 	}
492ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _location.set_block(block); }
493ead0c3e2STyler Dauwalder 	void set_partition(uint16 partition) { _location.set_partition(partition); }
494ead0c3e2STyler Dauwalder 
495ead0c3e2STyler Dauwalder 	void set_to(uint32 block, uint16 partition, uint32 length = 1,
496ead0c3e2STyler Dauwalder 	       uint8 type = EXTENT_TYPE_RECORDED)
497ead0c3e2STyler Dauwalder 	{
498ead0c3e2STyler Dauwalder 		set_block(block);
499ead0c3e2STyler Dauwalder 		set_partition(partition);
500ead0c3e2STyler Dauwalder 		set_length(length);
501ead0c3e2STyler Dauwalder 		set_type(type);
502ead0c3e2STyler Dauwalder 	}
503ead0c3e2STyler Dauwalder 
504ead0c3e2STyler Dauwalder private:
505ead0c3e2STyler Dauwalder 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
506ead0c3e2STyler Dauwalder 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
507ead0c3e2STyler Dauwalder 
508ead0c3e2STyler Dauwalder 	uint32 _type_and_length;
509ead0c3e2STyler Dauwalder 	logical_block_address _location;
510ead0c3e2STyler Dauwalder 	array<uint8, 6> _implementation_use;
511ead0c3e2STyler Dauwalder } __attribute__((packed));
512ead0c3e2STyler Dauwalder 
513ead0c3e2STyler Dauwalder /*! \brief Common tag found at the beginning of most udf descriptor structures.
514ead0c3e2STyler Dauwalder 
515ead0c3e2STyler Dauwalder 	For error checking, \c descriptor_tag  structures have:
516ead0c3e2STyler Dauwalder 	- The disk location of the tag redundantly stored in the tag itself
517ead0c3e2STyler Dauwalder 	- A checksum value for the tag
518ead0c3e2STyler Dauwalder 	- A CRC value and length
519ead0c3e2STyler Dauwalder 
520ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
521ead0c3e2STyler Dauwalder */
522ead0c3e2STyler Dauwalder struct descriptor_tag  {
523ead0c3e2STyler Dauwalder public:
524ead0c3e2STyler Dauwalder 	void dump() const;
525ead0c3e2STyler Dauwalder 
52604d90c2aSTyler Dauwalder 	status_t init_check(uint32 block, bool calculateCrc = true);
527ead0c3e2STyler Dauwalder 
528ead0c3e2STyler Dauwalder 	uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); }
529ead0c3e2STyler Dauwalder 	uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); }
530ead0c3e2STyler Dauwalder 	uint8 checksum() const { return _checksum; }
531ead0c3e2STyler Dauwalder 	uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); }
532ead0c3e2STyler Dauwalder 	uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); }
533ead0c3e2STyler Dauwalder 	uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); }
534ead0c3e2STyler Dauwalder 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
535ead0c3e2STyler Dauwalder 
536ead0c3e2STyler Dauwalder 	void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); }
537ead0c3e2STyler Dauwalder 	void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); }
538ead0c3e2STyler Dauwalder 	void set_checksum(uint8 checksum) { _checksum = checksum; }
539ead0c3e2STyler Dauwalder 	void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); }
540ead0c3e2STyler Dauwalder 	void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); }
541ead0c3e2STyler Dauwalder 	void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); }
542ead0c3e2STyler Dauwalder 	void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
543ead0c3e2STyler Dauwalder 
5445a97c04eSTyler Dauwalder 	/*! \brief Calculates and sets the crc length, crc checksumm, and
5455a97c04eSTyler Dauwalder 		checksum for the tag.
5465a97c04eSTyler Dauwalder 
5475a97c04eSTyler Dauwalder 		This function should not be called until all member variables in
5485a97c04eSTyler Dauwalder 		the descriptor_tag's enclosing descriptor and all member variables
5495a97c04eSTyler Dauwalder 		in the descriptor_tag itself other than crc_length, crc, and checksum
5505a97c04eSTyler Dauwalder 		have been set (since the checksum is based off of values in the
5515a97c04eSTyler Dauwalder 		descriptor_tag, and the crc is based off the values in and the
5525a97c04eSTyler Dauwalder 		size of the	enclosing descriptor).
5535a97c04eSTyler Dauwalder 
5545a97c04eSTyler Dauwalder 		\param The tag's enclosing descriptor.
5555a97c04eSTyler Dauwalder 		\param The size of the tag's enclosing descriptor (including the
5565a97c04eSTyler Dauwalder 		       tag); only necessary if different from sizeof(Descriptor).
5575a97c04eSTyler Dauwalder 	*/
5585a97c04eSTyler Dauwalder 	template <class Descriptor>
5595a97c04eSTyler Dauwalder 	void
5605a97c04eSTyler Dauwalder 	set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
5615a97c04eSTyler Dauwalder 	{
5625a97c04eSTyler Dauwalder 
5635a97c04eSTyler Dauwalder 		// check that this tag is actually owned by
5645a97c04eSTyler Dauwalder 		// the given descriptor
5655a97c04eSTyler Dauwalder 		if (this == &descriptor.tag())
5665a97c04eSTyler Dauwalder 		{
5675a97c04eSTyler Dauwalder 			// crc_length, based off provided descriptor
5685a97c04eSTyler Dauwalder 			set_crc_length(size - sizeof(descriptor_tag));
5695a97c04eSTyler Dauwalder 			// crc
5705a97c04eSTyler Dauwalder 			uint16 crc = Udf::calculate_crc(reinterpret_cast<uint8*>(this)
5715a97c04eSTyler Dauwalder 			               + sizeof(descriptor_tag), crc_length());
5725a97c04eSTyler Dauwalder 			set_crc(crc);
5735a97c04eSTyler Dauwalder 			// checksum (which depends on the other two values)
5745a97c04eSTyler Dauwalder 			uint32 sum = 0;
5755a97c04eSTyler Dauwalder 			for (int i = 0; i <= 3; i++)
5765a97c04eSTyler Dauwalder 				sum += reinterpret_cast<uint8*>(this)[i];
5775a97c04eSTyler Dauwalder 			for (int i = 5; i <= 15; i++)
5785a97c04eSTyler Dauwalder 				sum += reinterpret_cast<uint8*>(this)[i];
5795a97c04eSTyler Dauwalder 			set_checksum(sum % 256);
5805a97c04eSTyler Dauwalder 		}
5815a97c04eSTyler Dauwalder 	}
582ead0c3e2STyler Dauwalder private:
583ead0c3e2STyler Dauwalder 	uint16 _id;
584ead0c3e2STyler Dauwalder 	uint16 _version;
585ead0c3e2STyler Dauwalder 	uint8 _checksum;			//!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
586ead0c3e2STyler Dauwalder 	uint8 _reserved;			//!< Set to #00.
587ead0c3e2STyler Dauwalder 	uint16 _serial_number;
588ead0c3e2STyler Dauwalder 	uint16 _crc;				//!< May be 0 if \c crc_length field is 0.
589ead0c3e2STyler Dauwalder 	/*! \brief Length of the data chunk used to calculate CRC.
590ead0c3e2STyler Dauwalder 
591ead0c3e2STyler Dauwalder 		If 0, no CRC was calculated, and the \c crc field must be 0.
592ead0c3e2STyler Dauwalder 
593ead0c3e2STyler Dauwalder 		According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors
594ead0c3e2STyler Dauwalder 		unless otherwise noted, and this field shall be set to:
595ead0c3e2STyler Dauwalder 
596ead0c3e2STyler Dauwalder 		<code>(descriptor length) - (descriptor tag length)</code>
597ead0c3e2STyler Dauwalder 	*/
598ead0c3e2STyler Dauwalder 	uint16 _crc_length;
599ead0c3e2STyler Dauwalder 	/*! \brief Address of this tag within its partition (for error checking).
600ead0c3e2STyler Dauwalder 
601ead0c3e2STyler Dauwalder 		For virtually addressed structures (i.e. those accessed thru a VAT), this
602ead0c3e2STyler Dauwalder 		shall be the virtual address, not the physical or logical address.
603ead0c3e2STyler Dauwalder 	*/
604ead0c3e2STyler Dauwalder 	uint32 _location;
605ead0c3e2STyler Dauwalder 
606ead0c3e2STyler Dauwalder } __attribute__((packed));
607ead0c3e2STyler Dauwalder 
608ead0c3e2STyler Dauwalder 
609ead0c3e2STyler Dauwalder /*! \c descriptor_tag ::id values
610ead0c3e2STyler Dauwalder */
611ead0c3e2STyler Dauwalder enum tag_id {
612ead0c3e2STyler Dauwalder 	TAGID_UNDEFINED	= 0,
613ead0c3e2STyler Dauwalder 
614ead0c3e2STyler Dauwalder 	// ECMA 167, PART 3
615ead0c3e2STyler Dauwalder 	TAGID_PRIMARY_VOLUME_DESCRIPTOR,
616ead0c3e2STyler Dauwalder 	TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER,
617ead0c3e2STyler Dauwalder 	TAGID_VOLUME_DESCRIPTOR_POINTER,
618ead0c3e2STyler Dauwalder 	TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR,
619ead0c3e2STyler Dauwalder 	TAGID_PARTITION_DESCRIPTOR,
620ead0c3e2STyler Dauwalder 	TAGID_LOGICAL_VOLUME_DESCRIPTOR,
621ead0c3e2STyler Dauwalder 	TAGID_UNALLOCATED_SPACE_DESCRIPTOR,
622ead0c3e2STyler Dauwalder 	TAGID_TERMINATING_DESCRIPTOR,
623ead0c3e2STyler Dauwalder 	TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR,
624ead0c3e2STyler Dauwalder 
625ead0c3e2STyler Dauwalder 	TAGID_CUSTOM_START = 65280,
626ead0c3e2STyler Dauwalder 	TAGID_CUSTOM_END = 65535,
627ead0c3e2STyler Dauwalder 
628ead0c3e2STyler Dauwalder 	// ECMA 167, PART 4
629ead0c3e2STyler Dauwalder 	TAGID_FILE_SET_DESCRIPTOR = 256,
630*4f0e6a75STyler Dauwalder 	TAGID_FILE_ID_DESCRIPTOR,
631ead0c3e2STyler Dauwalder 	TAGID_ALLOCATION_EXTENT_DESCRIPTOR,
632ead0c3e2STyler Dauwalder 	TAGID_INDIRECT_ENTRY,
633ead0c3e2STyler Dauwalder 	TAGID_TERMINAL_ENTRY,
634ead0c3e2STyler Dauwalder 	TAGID_FILE_ENTRY,
635ead0c3e2STyler Dauwalder 	TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR,
636ead0c3e2STyler Dauwalder 	TAGID_UNALLOCATED_SPACE_ENTRY,
637ead0c3e2STyler Dauwalder 	TAGID_SPACE_BITMAP_DESCRIPTOR,
638ead0c3e2STyler Dauwalder 	TAGID_PARTITION_INTEGRITY_ENTRY,
639ead0c3e2STyler Dauwalder 	TAGID_EXTENDED_FILE_ENTRY,
640ead0c3e2STyler Dauwalder };
641ead0c3e2STyler Dauwalder 
642ead0c3e2STyler Dauwalder const char *tag_id_to_string(tag_id id);
643ead0c3e2STyler Dauwalder 
644e05a3e1eSTyler Dauwalder extern const uint16 kCrcTable[256];
645e05a3e1eSTyler Dauwalder 
646ead0c3e2STyler Dauwalder /*! \brief Primary volume descriptor
647ead0c3e2STyler Dauwalder */
648ead0c3e2STyler Dauwalder struct primary_volume_descriptor {
649ead0c3e2STyler Dauwalder public:
650ead0c3e2STyler Dauwalder 	void dump() const;
651ead0c3e2STyler Dauwalder 
652ead0c3e2STyler Dauwalder 	// Get functions
653ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
654ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
655ead0c3e2STyler Dauwalder 
656ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
657ead0c3e2STyler Dauwalder 	uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); }
658ead0c3e2STyler Dauwalder 
659ead0c3e2STyler Dauwalder 	const array<char, 32>& volume_identifier() const { return _volume_identifier; }
660ead0c3e2STyler Dauwalder 	array<char, 32>& volume_identifier() { return _volume_identifier; }
661ead0c3e2STyler Dauwalder 
662ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
663ead0c3e2STyler Dauwalder 	uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); }
664ead0c3e2STyler Dauwalder 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
665ead0c3e2STyler Dauwalder 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
666ead0c3e2STyler Dauwalder 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
667ead0c3e2STyler Dauwalder 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
668ead0c3e2STyler Dauwalder 
669ead0c3e2STyler Dauwalder 	const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
670ead0c3e2STyler Dauwalder 	array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
671ead0c3e2STyler Dauwalder 
672ead0c3e2STyler Dauwalder 	const charspec& descriptor_character_set() const { return _descriptor_character_set; }
673ead0c3e2STyler Dauwalder 	charspec& descriptor_character_set() { return _descriptor_character_set; }
674ead0c3e2STyler Dauwalder 
675ead0c3e2STyler Dauwalder 	const charspec& explanatory_character_set() const { return _explanatory_character_set; }
676ead0c3e2STyler Dauwalder 	charspec& explanatory_character_set() { return _explanatory_character_set; }
677ead0c3e2STyler Dauwalder 
678ead0c3e2STyler Dauwalder 	const extent_address& volume_abstract() const { return _volume_abstract; }
679ead0c3e2STyler Dauwalder 	extent_address& volume_abstract() { return _volume_abstract; }
680ead0c3e2STyler Dauwalder 	const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; }
681ead0c3e2STyler Dauwalder 	extent_address& volume_copyright_notice() { return _volume_copyright_notice; }
682ead0c3e2STyler Dauwalder 
683ead0c3e2STyler Dauwalder 	const entity_id& application_id() const { return _application_id; }
684ead0c3e2STyler Dauwalder 	entity_id& application_id() { return _application_id; }
685ead0c3e2STyler Dauwalder 
686ead0c3e2STyler Dauwalder 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
687ead0c3e2STyler Dauwalder 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
688ead0c3e2STyler Dauwalder 
689ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
690ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
691ead0c3e2STyler Dauwalder 
692ead0c3e2STyler Dauwalder 	const array<uint8, 64>& implementation_use() const { return _implementation_use; }
693ead0c3e2STyler Dauwalder 	array<uint8, 64>& implementation_use() { return _implementation_use; }
694ead0c3e2STyler Dauwalder 
695ead0c3e2STyler Dauwalder 	uint32 predecessor_volume_descriptor_sequence_location() const
696ead0c3e2STyler Dauwalder 	  { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); }
697ead0c3e2STyler Dauwalder 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
698ead0c3e2STyler Dauwalder 
6999b438e89STyler Dauwalder 	const array<uint8, 22>& reserved() const { return _reserved; }
7009b438e89STyler Dauwalder 	array<uint8, 22>& reserved() { return _reserved; }
7019b438e89STyler Dauwalder 
702ead0c3e2STyler Dauwalder 	// Set functions
703ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number)
704ead0c3e2STyler Dauwalder 	  { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
705ead0c3e2STyler Dauwalder 	void set_primary_volume_descriptor_number(uint32 number)
706ead0c3e2STyler Dauwalder 	  { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
707ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number)
708ead0c3e2STyler Dauwalder 	  { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
709ead0c3e2STyler Dauwalder 	void set_max_volume_sequence_number(uint16 number)
710ead0c3e2STyler Dauwalder 	  { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
711ead0c3e2STyler Dauwalder 	void set_interchange_level(uint16 level)
712ead0c3e2STyler Dauwalder 	  { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
713ead0c3e2STyler Dauwalder 	void set_max_interchange_level(uint16 level)
714ead0c3e2STyler Dauwalder 	  { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
715ead0c3e2STyler Dauwalder 	void set_character_set_list(uint32 list)
716ead0c3e2STyler Dauwalder 	  { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
717ead0c3e2STyler Dauwalder 	void set_max_character_set_list(uint32 list)
718ead0c3e2STyler Dauwalder 	  { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
719ead0c3e2STyler Dauwalder 	void set_predecessor_volume_descriptor_sequence_location(uint32 location)
720ead0c3e2STyler Dauwalder 	  { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); }
721ead0c3e2STyler Dauwalder 	void set_flags(uint16 flags)
722ead0c3e2STyler Dauwalder 	  { _flags = B_HOST_TO_LENDIAN_INT16(flags); }
723ead0c3e2STyler Dauwalder 
724ead0c3e2STyler Dauwalder private:
725ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
726ead0c3e2STyler Dauwalder 	uint32 _vds_number;
727ead0c3e2STyler Dauwalder 	uint32 _primary_volume_descriptor_number;
728ead0c3e2STyler Dauwalder 	array<char, 32> _volume_identifier;
729ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
730ead0c3e2STyler Dauwalder 	uint16 _max_volume_sequence_number;
731ead0c3e2STyler Dauwalder 	uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
732ead0c3e2STyler Dauwalder 	uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
733ead0c3e2STyler Dauwalder 	uint32 _character_set_list;
734ead0c3e2STyler Dauwalder 	uint32 _max_character_set_list;
735ead0c3e2STyler Dauwalder 	array<char, 128> _volume_set_identifier;
736ead0c3e2STyler Dauwalder 
737ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set for the \c volume_identifier
738ead0c3e2STyler Dauwalder 		and \c volume_set_identifier fields.
739ead0c3e2STyler Dauwalder 
740ead0c3e2STyler Dauwalder 		To be set to CS0.
741ead0c3e2STyler Dauwalder 	*/
742ead0c3e2STyler Dauwalder 	charspec _descriptor_character_set;
743ead0c3e2STyler Dauwalder 
744ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set used in the \c volume_abstract
745ead0c3e2STyler Dauwalder 		and \c volume_copyright_notice extents.
746ead0c3e2STyler Dauwalder 
747ead0c3e2STyler Dauwalder 		To be set to CS0.
748ead0c3e2STyler Dauwalder 	*/
749ead0c3e2STyler Dauwalder 	charspec _explanatory_character_set;
750ead0c3e2STyler Dauwalder 
751ead0c3e2STyler Dauwalder 	extent_address _volume_abstract;
752ead0c3e2STyler Dauwalder 	extent_address _volume_copyright_notice;
753ead0c3e2STyler Dauwalder 
754ead0c3e2STyler Dauwalder 	entity_id _application_id;
755ead0c3e2STyler Dauwalder 	timestamp _recording_date_and_time;
756ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
757ead0c3e2STyler Dauwalder 	array<uint8, 64> _implementation_use;
758ead0c3e2STyler Dauwalder 	uint32 _predecessor_volume_descriptor_sequence_location;
759ead0c3e2STyler Dauwalder 	uint16 _flags;
7609b438e89STyler Dauwalder 	array<uint8, 22> _reserved;
761ead0c3e2STyler Dauwalder 
762ead0c3e2STyler Dauwalder } __attribute__((packed));
763ead0c3e2STyler Dauwalder 
764ead0c3e2STyler Dauwalder 
765ead0c3e2STyler Dauwalder /*! \brief Anchor Volume Descriptor Pointer
766ead0c3e2STyler Dauwalder 
767ead0c3e2STyler Dauwalder 	vd recorded at preset locations in the partition, used as a reference
768ead0c3e2STyler Dauwalder 	point to the main vd sequences
769ead0c3e2STyler Dauwalder 
770ead0c3e2STyler Dauwalder 	According to UDF 2.01, an avdp shall be recorded in at least 2 of
771ead0c3e2STyler Dauwalder 	the 3 following locations, where N is the last recordable sector
772ead0c3e2STyler Dauwalder 	of the partition:
773ead0c3e2STyler Dauwalder 	- 256
774ead0c3e2STyler Dauwalder 	- (N - 256)
775ead0c3e2STyler Dauwalder 	- N
776ead0c3e2STyler Dauwalder 
777ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
778ead0c3e2STyler Dauwalder */
779ead0c3e2STyler Dauwalder struct anchor_volume_descriptor {
780ead0c3e2STyler Dauwalder public:
781ead0c3e2STyler Dauwalder 	void dump() const;
782ead0c3e2STyler Dauwalder 
783ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
784ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
785ead0c3e2STyler Dauwalder 
786ead0c3e2STyler Dauwalder 	extent_address& main_vds() { return _main_vds; }
787ead0c3e2STyler Dauwalder 	const extent_address& main_vds() const { return _main_vds; }
788ead0c3e2STyler Dauwalder 
789ead0c3e2STyler Dauwalder 	extent_address& reserve_vds() { return _reserve_vds; }
790ead0c3e2STyler Dauwalder 	const extent_address& reserve_vds() const { return _reserve_vds; }
791ead0c3e2STyler Dauwalder private:
792ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
793ead0c3e2STyler Dauwalder 	extent_address _main_vds;	//!< min length of 16 sectors
794ead0c3e2STyler Dauwalder 	extent_address _reserve_vds;	//!< min length of 16 sectors
795ead0c3e2STyler Dauwalder 	char _reserved[480];
796ead0c3e2STyler Dauwalder } __attribute__((packed));
797ead0c3e2STyler Dauwalder 
798ead0c3e2STyler Dauwalder 
799ead0c3e2STyler Dauwalder /*! \brief Volume Descriptor Pointer
800ead0c3e2STyler Dauwalder 
801ead0c3e2STyler Dauwalder 	Used to chain extents of volume descriptor sequences together.
802ead0c3e2STyler Dauwalder 
803ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.3
804ead0c3e2STyler Dauwalder */
805ead0c3e2STyler Dauwalder struct descriptor_pointer {
806ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
807ead0c3e2STyler Dauwalder 	uint32 vds_number;
808ead0c3e2STyler Dauwalder 	extent_address next;
809ead0c3e2STyler Dauwalder } __attribute__((packed));
810ead0c3e2STyler Dauwalder 
811ead0c3e2STyler Dauwalder 
812ead0c3e2STyler Dauwalder /*! \brief Implementation Use Volume Descriptor
813ead0c3e2STyler Dauwalder 
814ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.4
815ead0c3e2STyler Dauwalder */
816ead0c3e2STyler Dauwalder struct implementation_use_descriptor {
817ead0c3e2STyler Dauwalder public:
818ead0c3e2STyler Dauwalder 	void dump() const;
819ead0c3e2STyler Dauwalder 
820ead0c3e2STyler Dauwalder 	// Get functions
821ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
822ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
823ead0c3e2STyler Dauwalder 
824ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
825ead0c3e2STyler Dauwalder 
826ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
827ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
828ead0c3e2STyler Dauwalder 
829ead0c3e2STyler Dauwalder 	const array<uint8, 460>& implementation_use() const { return _implementation_use; }
830ead0c3e2STyler Dauwalder 	array<uint8, 460>& implementation_use() { return _implementation_use; }
831ead0c3e2STyler Dauwalder 
832ead0c3e2STyler Dauwalder 	// Set functions
833ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
834ead0c3e2STyler Dauwalder private:
835ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
836ead0c3e2STyler Dauwalder 	uint32 _vds_number;
837ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
838ead0c3e2STyler Dauwalder 	array<uint8, 460> _implementation_use;
839ead0c3e2STyler Dauwalder } __attribute__((packed));
840ead0c3e2STyler Dauwalder 
841ead0c3e2STyler Dauwalder 
842ead0c3e2STyler Dauwalder /*! \brief Maximum number of partition descriptors to be found in volume
843ead0c3e2STyler Dauwalder 	descriptor sequence, per UDF-2.50
844ead0c3e2STyler Dauwalder */
845ead0c3e2STyler Dauwalder extern const uint8 kMaxPartitionDescriptors;
846ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAPS 2
847ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAP_SIZE 64
848ead0c3e2STyler Dauwalder 
849ead0c3e2STyler Dauwalder /*! \brief Partition Descriptor
850ead0c3e2STyler Dauwalder 
851ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.5
852ead0c3e2STyler Dauwalder */
853ead0c3e2STyler Dauwalder struct partition_descriptor {
854ead0c3e2STyler Dauwalder private:
855ead0c3e2STyler Dauwalder 	union partition_flags_accessor {
856ead0c3e2STyler Dauwalder 		uint16 partition_flags;
857ead0c3e2STyler Dauwalder 		struct {
858ead0c3e2STyler Dauwalder 			uint16 allocated:1,
859ead0c3e2STyler Dauwalder 			       reserved:15;
860ead0c3e2STyler Dauwalder 		} bits;
861ead0c3e2STyler Dauwalder 	};
862ead0c3e2STyler Dauwalder 
863ead0c3e2STyler Dauwalder public:
864ead0c3e2STyler Dauwalder 	void dump() const;
865ead0c3e2STyler Dauwalder 
866ead0c3e2STyler Dauwalder 	// Get functions
867ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
868ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
869ead0c3e2STyler Dauwalder 
870ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
871ead0c3e2STyler Dauwalder 	uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); }
872ead0c3e2STyler Dauwalder 	bool allocated() const {
873ead0c3e2STyler Dauwalder 		partition_flags_accessor f;
874ead0c3e2STyler Dauwalder 		f.partition_flags = partition_flags();
875ead0c3e2STyler Dauwalder 		return f.bits.allocated;
876ead0c3e2STyler Dauwalder 	}
877ead0c3e2STyler Dauwalder 	uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
878ead0c3e2STyler Dauwalder 
879ead0c3e2STyler Dauwalder 	const entity_id& partition_contents() const { return _partition_contents; }
880ead0c3e2STyler Dauwalder 	entity_id& partition_contents() { return _partition_contents; }
881ead0c3e2STyler Dauwalder 
882ead0c3e2STyler Dauwalder 	const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
883ead0c3e2STyler Dauwalder 	array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
884ead0c3e2STyler Dauwalder 
885ead0c3e2STyler Dauwalder 	uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); }
886ead0c3e2STyler Dauwalder 	uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); }
887ead0c3e2STyler Dauwalder 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
888ead0c3e2STyler Dauwalder 
889ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
890ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
891ead0c3e2STyler Dauwalder 
892ead0c3e2STyler Dauwalder 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
893ead0c3e2STyler Dauwalder 	array<uint8, 128>& implementation_use() { return _implementation_use; }
894ead0c3e2STyler Dauwalder 
895003d4e83STyler Dauwalder 	const array<uint8, 156>& reserved() const { return _reserved; }
896003d4e83STyler Dauwalder 	array<uint8, 156>& reserved() { return _reserved; }
897003d4e83STyler Dauwalder 
898ead0c3e2STyler Dauwalder 	// Set functions
899ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
900ead0c3e2STyler Dauwalder 	void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); }
901ead0c3e2STyler Dauwalder 	void set_allocated(bool allocated) {
902ead0c3e2STyler Dauwalder 		partition_flags_accessor f;
903ead0c3e2STyler Dauwalder 		f.partition_flags = partition_flags();
904ead0c3e2STyler Dauwalder 		f.bits.allocated = allocated;
905ead0c3e2STyler Dauwalder 		set_partition_flags(f.partition_flags);
906ead0c3e2STyler Dauwalder 	}
907003d4e83STyler Dauwalder 	void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
908ead0c3e2STyler Dauwalder 	void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); }
909ead0c3e2STyler Dauwalder 	void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); }
910ead0c3e2STyler Dauwalder 	void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
911ead0c3e2STyler Dauwalder 
912ead0c3e2STyler Dauwalder private:
913ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
914ead0c3e2STyler Dauwalder 	uint32 _vds_number;
915ead0c3e2STyler Dauwalder 	/*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
916ead0c3e2STyler Dauwalder 	    shall mean volume space has been allocated.
917ead0c3e2STyler Dauwalder 	*/
918ead0c3e2STyler Dauwalder 	uint16 _partition_flags;
919ead0c3e2STyler Dauwalder 	uint16 _partition_number;
920ead0c3e2STyler Dauwalder 
921ead0c3e2STyler Dauwalder 	/*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF
922ead0c3e2STyler Dauwalder 		- "+CD001" Volume recorded according to ECMA-119, i.e. iso9660
923ead0c3e2STyler Dauwalder 		- "+FDC01" Volume recorded according to ECMA-107
924ead0c3e2STyler Dauwalder 		- "+CDW02" Volume recorded according to ECMA-168
925ead0c3e2STyler Dauwalder 	*/
926ead0c3e2STyler Dauwalder 	entity_id _partition_contents;
927ead0c3e2STyler Dauwalder 	array<uint8, 128> _partition_contents_use;
928ead0c3e2STyler Dauwalder 
929ead0c3e2STyler Dauwalder 	/*! See \c partition_access_type enum
930ead0c3e2STyler Dauwalder 	*/
931ead0c3e2STyler Dauwalder 	uint32 _access_type;
932ead0c3e2STyler Dauwalder 	uint32 _start;
933ead0c3e2STyler Dauwalder 	uint32 _length;
934ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
935ead0c3e2STyler Dauwalder 	array<uint8, 128> _implementation_use;
936003d4e83STyler Dauwalder 	array<uint8, 156> _reserved;
937ead0c3e2STyler Dauwalder } __attribute__((packed));
938ead0c3e2STyler Dauwalder 
939ead0c3e2STyler Dauwalder 
940ead0c3e2STyler Dauwalder enum partition_access_type {
941003d4e83STyler Dauwalder 	ACCESS_UNSPECIFIED,
942003d4e83STyler Dauwalder 	ACCESS_READ_ONLY,
943003d4e83STyler Dauwalder 	ACCESS_WRITE_ONCE,
944003d4e83STyler Dauwalder 	ACCESS_REWRITABLE,
945003d4e83STyler Dauwalder 	ACCESS_OVERWRITABLE,
946ead0c3e2STyler Dauwalder };
947ead0c3e2STyler Dauwalder 
948ead0c3e2STyler Dauwalder 
949ead0c3e2STyler Dauwalder /*! \brief Logical volume descriptor
950ead0c3e2STyler Dauwalder 
951ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
952ead0c3e2STyler Dauwalder */
953ead0c3e2STyler Dauwalder struct logical_volume_descriptor {
954ead0c3e2STyler Dauwalder 	void dump() const;
955ead0c3e2STyler Dauwalder 
956ead0c3e2STyler Dauwalder 	// Get functions
957ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
958ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
959ead0c3e2STyler Dauwalder 
960ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
961ead0c3e2STyler Dauwalder 
962ead0c3e2STyler Dauwalder 	const charspec& character_set() const { return _character_set; }
963ead0c3e2STyler Dauwalder 	charspec& character_set() { return _character_set; }
964ead0c3e2STyler Dauwalder 
965ead0c3e2STyler Dauwalder 	const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
966ead0c3e2STyler Dauwalder 	array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
967ead0c3e2STyler Dauwalder 
968ead0c3e2STyler Dauwalder 	uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
969ead0c3e2STyler Dauwalder 
970ead0c3e2STyler Dauwalder 	const entity_id& domain_id() const { return _domain_id; }
971ead0c3e2STyler Dauwalder 	entity_id& domain_id() { return _domain_id; }
972ead0c3e2STyler Dauwalder 
973ead0c3e2STyler Dauwalder 	const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
974ead0c3e2STyler Dauwalder 	array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; }
975ead0c3e2STyler Dauwalder 
976d1a0387eSTyler Dauwalder 	const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); }
977d1a0387eSTyler Dauwalder 	long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); }
978ead0c3e2STyler Dauwalder 
979ead0c3e2STyler Dauwalder 	uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); }
980ead0c3e2STyler Dauwalder 	uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); }
981ead0c3e2STyler Dauwalder 
982ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
983ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
984ead0c3e2STyler Dauwalder 
985ead0c3e2STyler Dauwalder 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
986ead0c3e2STyler Dauwalder 	array<uint8, 128>& implementation_use() { return _implementation_use; }
987ead0c3e2STyler Dauwalder 
988ead0c3e2STyler Dauwalder 	const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
989ead0c3e2STyler Dauwalder 	extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
990ead0c3e2STyler Dauwalder 
991ead0c3e2STyler Dauwalder 	const uint8* partition_maps() const { return _partition_maps; }
992ead0c3e2STyler Dauwalder 	uint8* partition_maps() { return _partition_maps; }
993ead0c3e2STyler Dauwalder 
994ead0c3e2STyler Dauwalder 	// Set functions
995ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
996ead0c3e2STyler Dauwalder 	void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); }
997ead0c3e2STyler Dauwalder 
998ead0c3e2STyler Dauwalder 	void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); }
999ead0c3e2STyler Dauwalder 	void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); }
1000ead0c3e2STyler Dauwalder 
1001ead0c3e2STyler Dauwalder 	// Other functions
1002ead0c3e2STyler Dauwalder 	logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
1003ead0c3e2STyler Dauwalder 
1004ead0c3e2STyler Dauwalder private:
1005ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1006ead0c3e2STyler Dauwalder 	uint32 _vds_number;
1007ead0c3e2STyler Dauwalder 
1008ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set for the
1009ead0c3e2STyler Dauwalder 		\c logical_volume_identifier field.
1010ead0c3e2STyler Dauwalder 
1011ead0c3e2STyler Dauwalder 		To be set to CS0.
1012ead0c3e2STyler Dauwalder 	*/
1013ead0c3e2STyler Dauwalder 	charspec _character_set;
1014ead0c3e2STyler Dauwalder 	array<char, 128> _logical_volume_identifier;
1015ead0c3e2STyler Dauwalder 	uint32 _logical_block_size;
1016ead0c3e2STyler Dauwalder 
1017ead0c3e2STyler Dauwalder 	/*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
1018ead0c3e2STyler Dauwalder 	*/
1019ead0c3e2STyler Dauwalder 	entity_id _domain_id;
1020ead0c3e2STyler Dauwalder 
1021ead0c3e2STyler Dauwalder 	/*! \brief For UDF, shall contain a \c long_address which identifies
1022ead0c3e2STyler Dauwalder 		the location of the logical volume's first file set.
1023ead0c3e2STyler Dauwalder 	*/
1024ead0c3e2STyler Dauwalder 	array<uint8, 16> _logical_volume_contents_use;
1025ead0c3e2STyler Dauwalder 
1026ead0c3e2STyler Dauwalder 	uint32 _map_table_length;
1027ead0c3e2STyler Dauwalder 	uint32 _partition_map_count;
1028ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
1029ead0c3e2STyler Dauwalder 	array<uint8, 128> _implementation_use;
1030ead0c3e2STyler Dauwalder 
1031ead0c3e2STyler Dauwalder 	/*! \brief Logical volume integrity sequence location.
1032ead0c3e2STyler Dauwalder 
1033ead0c3e2STyler Dauwalder 		For re/overwritable media, shall be a min of 8KB in length.
1034ead0c3e2STyler Dauwalder 		For WORM media, shall be quite frickin large, as a new volume
1035ead0c3e2STyler Dauwalder 		must be added to the set if the extent fills up (since you
1036ead0c3e2STyler Dauwalder 		can't chain lvis's I guess).
1037ead0c3e2STyler Dauwalder 	*/
1038ead0c3e2STyler Dauwalder 	extent_address _integrity_sequence_extent;
1039ead0c3e2STyler Dauwalder 
1040ead0c3e2STyler Dauwalder 	/*! \brief Restricted to maps of type 1 for normal maps and
1041ead0c3e2STyler Dauwalder 		UDF type 2 for virtual maps or maps on systems not supporting
1042ead0c3e2STyler Dauwalder 		defect management.
1043ead0c3e2STyler Dauwalder 
1044ead0c3e2STyler Dauwalder 		Note that we actually allocate memory for the partition maps
1045ead0c3e2STyler Dauwalder 		here due to the fact that we allocate logical_volume_descriptor
1046ead0c3e2STyler Dauwalder 		objects on the stack sometimes.
1047ead0c3e2STyler Dauwalder 
1048ead0c3e2STyler Dauwalder 		See UDF-2.01 2.2.8, 2.2.9
1049ead0c3e2STyler Dauwalder 	*/
1050ead0c3e2STyler Dauwalder 	uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1051ead0c3e2STyler Dauwalder } __attribute__((packed));
1052ead0c3e2STyler Dauwalder 
1053730ba00aSTyler Dauwalder //! Base size (excluding partition maps) of lvd
1054730ba00aSTyler Dauwalder extern const uint32 kLogicalVolumeDescriptorBaseSize;
1055ead0c3e2STyler Dauwalder 
1056ead0c3e2STyler Dauwalder /*! \brief (Mostly) common portion of various partition maps
1057ead0c3e2STyler Dauwalder 
1058ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.7.1
1059ead0c3e2STyler Dauwalder */
1060ead0c3e2STyler Dauwalder struct partition_map_header {
1061ead0c3e2STyler Dauwalder public:
1062ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
1063ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
1064ead0c3e2STyler Dauwalder 	uint8 *map_data() { return _map_data; }
1065ead0c3e2STyler Dauwalder 	const uint8 *map_data() const { return _map_data; }
1066ead0c3e2STyler Dauwalder 
1067ead0c3e2STyler Dauwalder 	entity_id& partition_type_id()
1068ead0c3e2STyler Dauwalder 		{ return *reinterpret_cast<entity_id*>(&_map_data[2]); }
1069ead0c3e2STyler Dauwalder 	const entity_id& partition_type_id() const
1070ead0c3e2STyler Dauwalder 		{ return *reinterpret_cast<const entity_id*>(&_map_data[2]); }
1071ead0c3e2STyler Dauwalder 
1072ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
1073ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
1074ead0c3e2STyler Dauwalder private:
1075ead0c3e2STyler Dauwalder 	uint8 _type;
1076ead0c3e2STyler Dauwalder 	uint8 _length;
1077ead0c3e2STyler Dauwalder 	uint8 _map_data[0];
1078ead0c3e2STyler Dauwalder };// __attribute__((packed));
1079ead0c3e2STyler Dauwalder 
1080ead0c3e2STyler Dauwalder 
1081ead0c3e2STyler Dauwalder /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
1082ead0c3e2STyler Dauwalder 
1083ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.7.2
1084ead0c3e2STyler Dauwalder */
1085ead0c3e2STyler Dauwalder struct physical_partition_map {
1086ead0c3e2STyler Dauwalder public:
1087ead0c3e2STyler Dauwalder 	void dump();
1088ead0c3e2STyler Dauwalder 
1089ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
1090ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
1091ead0c3e2STyler Dauwalder 
1092ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const {
1093ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1094ead0c3e2STyler Dauwalder 	uint16 partition_number() const {
1095ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1096ead0c3e2STyler Dauwalder 
1097ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
1098ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
1099ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number) {
1100ead0c3e2STyler Dauwalder 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1101ead0c3e2STyler Dauwalder 	void set_partition_number(uint16 number) {
1102ead0c3e2STyler Dauwalder 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1103ead0c3e2STyler Dauwalder private:
1104ead0c3e2STyler Dauwalder 	uint8 _type;
1105ead0c3e2STyler Dauwalder 	uint8 _length;
1106ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
1107ead0c3e2STyler Dauwalder 	uint16 _partition_number;
1108ead0c3e2STyler Dauwalder } __attribute__((packed));
1109ead0c3e2STyler Dauwalder 
1110ead0c3e2STyler Dauwalder 
1111ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1112ead0c3e2STyler Dauwalder /*! \brief Virtual partition map
1113ead0c3e2STyler Dauwalder 
1114ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1115ead0c3e2STyler Dauwalder 	type 2 partition map.
1116ead0c3e2STyler Dauwalder 
1117ead0c3e2STyler Dauwalder 	See also: UDF-2.01 2.2.8
1118ead0c3e2STyler Dauwalder */
1119ead0c3e2STyler Dauwalder struct virtual_partition_map {
1120ead0c3e2STyler Dauwalder 	uint8 type;
1121ead0c3e2STyler Dauwalder 	uint8 length;
1122ead0c3e2STyler Dauwalder 	uint8 reserved1[2];
1123ead0c3e2STyler Dauwalder 
1124ead0c3e2STyler Dauwalder 	/*! - flags: 0
1125ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Virtual Partition"
1126ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1127ead0c3e2STyler Dauwalder 	*/
1128ead0c3e2STyler Dauwalder 	entity_id partition_type_id;
1129ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number;
1130ead0c3e2STyler Dauwalder 
1131ead0c3e2STyler Dauwalder 	/*! corresponding type 1 partition map in same logical volume
1132ead0c3e2STyler Dauwalder 	*/
1133ead0c3e2STyler Dauwalder 	uint16 partition_number;
1134ead0c3e2STyler Dauwalder 	uint8 reserved2[24];
1135ead0c3e2STyler Dauwalder } __attribute__((packed));
1136ead0c3e2STyler Dauwalder 
1137ead0c3e2STyler Dauwalder 
1138ead0c3e2STyler Dauwalder /*! \brief Maximum number of redundant sparing tables found in
1139ead0c3e2STyler Dauwalder 	sparable_partition_map structures.
1140ead0c3e2STyler Dauwalder */
1141ead0c3e2STyler Dauwalder #define UDF_MAX_SPARING_TABLE_COUNT 4
1142ead0c3e2STyler Dauwalder 
1143ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1144ead0c3e2STyler Dauwalder /*! \brief Sparable partition map
1145ead0c3e2STyler Dauwalder 
1146ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1147ead0c3e2STyler Dauwalder 	type 2 partition map.
1148ead0c3e2STyler Dauwalder 
1149ead0c3e2STyler Dauwalder 	See also: UDF-2.01 2.2.9
1150ead0c3e2STyler Dauwalder */
1151ead0c3e2STyler Dauwalder struct sparable_partition_map {
1152ead0c3e2STyler Dauwalder public:
1153ead0c3e2STyler Dauwalder 	void dump();
1154ead0c3e2STyler Dauwalder 
1155ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
1156ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
1157ead0c3e2STyler Dauwalder 
1158ead0c3e2STyler Dauwalder 	entity_id& partition_type_id() { return _partition_type_id; }
1159ead0c3e2STyler Dauwalder 	const entity_id& partition_type_id() const { return _partition_type_id; }
1160ead0c3e2STyler Dauwalder 
1161ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const {
1162ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1163ead0c3e2STyler Dauwalder 	uint16 partition_number() const {
1164ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1165ead0c3e2STyler Dauwalder 	uint16 packet_length() const {
1166ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_packet_length); }
1167ead0c3e2STyler Dauwalder 	uint8 sparing_table_count() const { return _sparing_table_count; }
1168ead0c3e2STyler Dauwalder 	uint32 sparing_table_size() const {
1169ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); }
1170ead0c3e2STyler Dauwalder 	uint32 sparing_table_location(uint8 index) const {
1171ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); }
1172ead0c3e2STyler Dauwalder 
1173ead0c3e2STyler Dauwalder 
1174ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
1175ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
1176ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number) {
1177ead0c3e2STyler Dauwalder 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1178ead0c3e2STyler Dauwalder 	void set_partition_number(uint16 number) {
1179ead0c3e2STyler Dauwalder 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1180ead0c3e2STyler Dauwalder 	void set_packet_length(uint16 length) {
1181ead0c3e2STyler Dauwalder 		_packet_length = B_HOST_TO_LENDIAN_INT16(length); }
1182ead0c3e2STyler Dauwalder 	void set_sparing_table_count(uint8 count) {
1183ead0c3e2STyler Dauwalder 		_sparing_table_count = count; }
1184ead0c3e2STyler Dauwalder 	void set_sparing_table_size(uint32 size) {
1185ead0c3e2STyler Dauwalder 		_sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
1186ead0c3e2STyler Dauwalder 	void set_sparing_table_location(uint8 index, uint32 location) {
1187ead0c3e2STyler Dauwalder 		_sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
1188ead0c3e2STyler Dauwalder private:
1189ead0c3e2STyler Dauwalder 	uint8 _type;
1190ead0c3e2STyler Dauwalder 	uint8 _length;
1191ead0c3e2STyler Dauwalder 	uint8 _reserved1[2];
1192ead0c3e2STyler Dauwalder 
1193ead0c3e2STyler Dauwalder 	/*! - flags: 0
1194ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Sparable Partition"
1195ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1196ead0c3e2STyler Dauwalder 	*/
1197ead0c3e2STyler Dauwalder 	entity_id _partition_type_id;
1198ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
1199ead0c3e2STyler Dauwalder 
1200ead0c3e2STyler Dauwalder 	//! partition number of corresponding partition descriptor
1201ead0c3e2STyler Dauwalder 	uint16 _partition_number;
1202ead0c3e2STyler Dauwalder 	uint16 _packet_length;
1203ead0c3e2STyler Dauwalder 	uint8 _sparing_table_count;
1204ead0c3e2STyler Dauwalder 	uint8 _reserved2;
1205ead0c3e2STyler Dauwalder 	uint32 _sparing_table_size;
1206ead0c3e2STyler Dauwalder 	uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT];
1207ead0c3e2STyler Dauwalder } __attribute__((packed));
1208ead0c3e2STyler Dauwalder 
1209ead0c3e2STyler Dauwalder 
1210ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1211ead0c3e2STyler Dauwalder /*! \brief Metadata partition map
1212ead0c3e2STyler Dauwalder 
1213ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1214ead0c3e2STyler Dauwalder 	type 2 partition map.
1215ead0c3e2STyler Dauwalder 
1216ead0c3e2STyler Dauwalder 	See also: UDF-2.50 2.2.10
1217ead0c3e2STyler Dauwalder */
1218ead0c3e2STyler Dauwalder struct metadata_partition_map {
1219ead0c3e2STyler Dauwalder 	uint8 type;
1220ead0c3e2STyler Dauwalder 	uint8 length;
1221ead0c3e2STyler Dauwalder 	uint8 reserved1[2];
1222ead0c3e2STyler Dauwalder 
1223ead0c3e2STyler Dauwalder 	/*! - flags: 0
1224ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Metadata Partition"
1225ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.50 2.1.5
1226ead0c3e2STyler Dauwalder 	*/
1227ead0c3e2STyler Dauwalder 	entity_id partition_type_id;
1228ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number;
1229ead0c3e2STyler Dauwalder 
1230ead0c3e2STyler Dauwalder 	/*! corresponding type 1 or type 2 sparable partition
1231ead0c3e2STyler Dauwalder 	    map in same logical volume
1232ead0c3e2STyler Dauwalder 	*/
1233ead0c3e2STyler Dauwalder 	uint16 partition_number;
1234ead0c3e2STyler Dauwalder 	uint8 reserved2[24];
1235ead0c3e2STyler Dauwalder } __attribute__((packed));
1236ead0c3e2STyler Dauwalder 
1237ead0c3e2STyler Dauwalder 
1238ead0c3e2STyler Dauwalder /*! \brief Unallocated space descriptor
1239ead0c3e2STyler Dauwalder 
1240ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.8
1241ead0c3e2STyler Dauwalder */
1242ead0c3e2STyler Dauwalder struct unallocated_space_descriptor {
1243ead0c3e2STyler Dauwalder 	void dump() const;
1244ead0c3e2STyler Dauwalder 
1245ead0c3e2STyler Dauwalder 	// Get functions
1246ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1247ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1248ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1249ead0c3e2STyler Dauwalder 	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
1250ead0c3e2STyler Dauwalder 	extent_address* allocation_descriptors() { return _allocation_descriptors; }
1251ead0c3e2STyler Dauwalder 
1252ead0c3e2STyler Dauwalder 	// Set functions
1253ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1254ead0c3e2STyler Dauwalder 	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1255ead0c3e2STyler Dauwalder private:
1256ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1257ead0c3e2STyler Dauwalder 	uint32 _vds_number;
1258ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptor_count;
1259ead0c3e2STyler Dauwalder 	extent_address _allocation_descriptors[0];
1260ead0c3e2STyler Dauwalder } __attribute__((packed));
1261ead0c3e2STyler Dauwalder 
1262ead0c3e2STyler Dauwalder 
1263ead0c3e2STyler Dauwalder /*! \brief Terminating descriptor
1264ead0c3e2STyler Dauwalder 
1265ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.9
1266ead0c3e2STyler Dauwalder */
1267ead0c3e2STyler Dauwalder struct terminating_descriptor {
1268ead0c3e2STyler Dauwalder 	void dump() const;
1269ead0c3e2STyler Dauwalder 
1270ead0c3e2STyler Dauwalder 	// Get functions
1271ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1272ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1273ead0c3e2STyler Dauwalder 
1274ead0c3e2STyler Dauwalder private:
1275ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1276ead0c3e2STyler Dauwalder 	uint8 _reserved[496];
1277ead0c3e2STyler Dauwalder } __attribute__((packed));
1278ead0c3e2STyler Dauwalder 
1279ead0c3e2STyler Dauwalder 
1280ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity descriptor
1281ead0c3e2STyler Dauwalder 
1282ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.10
1283ead0c3e2STyler Dauwalder */
1284ead0c3e2STyler Dauwalder struct logical_volume_integrity_descriptor {
1285ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1286ead0c3e2STyler Dauwalder 	timestamp recording_time;
1287ead0c3e2STyler Dauwalder 	uint32 integrity_type;
1288ead0c3e2STyler Dauwalder 	extent_address next_integrity_extent;
1289ead0c3e2STyler Dauwalder 	array<uint8, 32> logical_volume_contents_use;
1290ead0c3e2STyler Dauwalder 	uint32 partition_count;
1291ead0c3e2STyler Dauwalder 	uint32 implementation_use_length;
1292ead0c3e2STyler Dauwalder 
1293ead0c3e2STyler Dauwalder 	/*! \todo double-check the pointer arithmetic here. */
1294ead0c3e2STyler Dauwalder 	uint32* free_space_table() { return (uint32*)(this+80); }
1295ead0c3e2STyler Dauwalder 	uint32* size_table() { return (uint32*)(free_space_table()+partition_count*sizeof(uint32)); }
1296ead0c3e2STyler Dauwalder 	uint8* implementation_use() { return (uint8*)(size_table()+partition_count*sizeof(uint32)); }
1297ead0c3e2STyler Dauwalder 
1298ead0c3e2STyler Dauwalder } __attribute__((packed));
1299ead0c3e2STyler Dauwalder 
1300ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity types
1301ead0c3e2STyler Dauwalder */
1302ead0c3e2STyler Dauwalder enum {
1303ead0c3e2STyler Dauwalder 	LVIT_OPEN = 1,
1304ead0c3e2STyler Dauwalder 	LVIT_CLOSED,
1305ead0c3e2STyler Dauwalder };
1306ead0c3e2STyler Dauwalder 
1307ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
1308ead0c3e2STyler Dauwalder // ECMA-167 Part 4
1309ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
1310ead0c3e2STyler Dauwalder 
1311ead0c3e2STyler Dauwalder 
1312ead0c3e2STyler Dauwalder 
1313ead0c3e2STyler Dauwalder /*! \brief File set descriptor
1314ead0c3e2STyler Dauwalder 
1315ead0c3e2STyler Dauwalder 	Contains all the pertinent info about a file set (i.e. a hierarchy of files)
1316ead0c3e2STyler Dauwalder 
1317ead0c3e2STyler Dauwalder 	According to UDF-2.01, only one file set descriptor shall be recorded,
1318ead0c3e2STyler Dauwalder 	except on WORM media, where the following rules apply:
1319ead0c3e2STyler Dauwalder 	- Multiple file sets are allowed only on WORM media
1320ead0c3e2STyler Dauwalder 	- The default file set shall be the one with highest value \c file_set_number field.
1321ead0c3e2STyler Dauwalder 	- Only the default file set may be flagged as writeable. All others shall be
1322ead0c3e2STyler Dauwalder 	  flagged as "hard write protect".
1323ead0c3e2STyler Dauwalder 	- No writeable file set may reference metadata structures which are referenced
1324ead0c3e2STyler Dauwalder 	  (directly or indirectly) by any other file set. Writeable file sets may, however,
1325ead0c3e2STyler Dauwalder 	  reference actual file data extents that are also referenced by other file sets.
1326ead0c3e2STyler Dauwalder */
1327ead0c3e2STyler Dauwalder struct file_set_descriptor {
1328ead0c3e2STyler Dauwalder 	void dump() const;
1329ead0c3e2STyler Dauwalder 
1330ead0c3e2STyler Dauwalder 	// Get functions
1331ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1332ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1333ead0c3e2STyler Dauwalder 
1334ead0c3e2STyler Dauwalder 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
1335ead0c3e2STyler Dauwalder 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
1336ead0c3e2STyler Dauwalder 
1337ead0c3e2STyler Dauwalder 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
1338ead0c3e2STyler Dauwalder 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
1339ead0c3e2STyler Dauwalder 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
1340ead0c3e2STyler Dauwalder 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
1341ead0c3e2STyler Dauwalder 	uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); }
1342ead0c3e2STyler Dauwalder 	uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); }
1343ead0c3e2STyler Dauwalder 
1344ead0c3e2STyler Dauwalder 	const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; }
1345ead0c3e2STyler Dauwalder 	charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; }
1346ead0c3e2STyler Dauwalder 
1347ead0c3e2STyler Dauwalder 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
1348ead0c3e2STyler Dauwalder 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
1349ead0c3e2STyler Dauwalder 
1350d1a0387eSTyler Dauwalder 	const charspec& file_set_id_character_set() const { return _file_set_id_character_set; }
1351d1a0387eSTyler Dauwalder 	charspec& file_set_id_character_set() { return _file_set_id_character_set; }
1352d1a0387eSTyler Dauwalder 
1353ead0c3e2STyler Dauwalder 	const array<char, 32>& file_set_id() const { return _file_set_id; }
1354ead0c3e2STyler Dauwalder 	array<char, 32>& file_set_id() { return _file_set_id; }
1355ead0c3e2STyler Dauwalder 
1356ead0c3e2STyler Dauwalder 	const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
1357ead0c3e2STyler Dauwalder 	array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1358ead0c3e2STyler Dauwalder 
1359ead0c3e2STyler Dauwalder 	const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
1360ead0c3e2STyler Dauwalder 	array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1361ead0c3e2STyler Dauwalder 
1362ead0c3e2STyler Dauwalder 	const long_address& root_directory_icb() const { return _root_directory_icb; }
1363ead0c3e2STyler Dauwalder 	long_address& root_directory_icb() { return _root_directory_icb; }
1364ead0c3e2STyler Dauwalder 
1365ead0c3e2STyler Dauwalder 	const entity_id& domain_id() const { return _domain_id; }
1366ead0c3e2STyler Dauwalder 	entity_id& domain_id() { return _domain_id; }
1367ead0c3e2STyler Dauwalder 
1368ead0c3e2STyler Dauwalder 	const long_address& next_extent() const { return _next_extent; }
1369ead0c3e2STyler Dauwalder 	long_address& next_extent() { return _next_extent; }
1370ead0c3e2STyler Dauwalder 
1371ead0c3e2STyler Dauwalder 	const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; }
1372ead0c3e2STyler Dauwalder 	long_address& system_stream_directory_icb() { return _system_stream_directory_icb; }
1373ead0c3e2STyler Dauwalder 
1374d1a0387eSTyler Dauwalder 	const array<uint8, 32>& reserved() const { return _reserved; }
1375d1a0387eSTyler Dauwalder 	array<uint8, 32>& reserved() { return _reserved; }
1376d1a0387eSTyler Dauwalder 
1377ead0c3e2STyler Dauwalder 	// Set functions
1378ead0c3e2STyler Dauwalder 	void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1379ead0c3e2STyler Dauwalder 	void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1380ead0c3e2STyler Dauwalder 	void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1381ead0c3e2STyler Dauwalder 	void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1382ead0c3e2STyler Dauwalder 	void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
1383ead0c3e2STyler Dauwalder 	void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1384ead0c3e2STyler Dauwalder private:
1385ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1386ead0c3e2STyler Dauwalder 	timestamp _recording_date_and_time;
1387ead0c3e2STyler Dauwalder 	uint16 _interchange_level;			//!< To be set to 3 (see UDF-2.01 2.3.2.1)
1388ead0c3e2STyler Dauwalder 	uint16 _max_interchange_level;		//!< To be set to 3 (see UDF-2.01 2.3.2.2)
1389ead0c3e2STyler Dauwalder 	uint32 _character_set_list;
1390ead0c3e2STyler Dauwalder 	uint32 _max_character_set_list;
1391ead0c3e2STyler Dauwalder 	uint32 _file_set_number;
1392ead0c3e2STyler Dauwalder 	uint32 _file_set_descriptor_number;
1393ead0c3e2STyler Dauwalder 	charspec _logical_volume_id_character_set;	//!< To be set to kCSOCharspec
1394ead0c3e2STyler Dauwalder 	array<char, 128> _logical_volume_id;
1395d1a0387eSTyler Dauwalder 	charspec _file_set_id_character_set;
1396ead0c3e2STyler Dauwalder 	array<char, 32> _file_set_id;
1397ead0c3e2STyler Dauwalder 	array<char, 32> _copyright_file_id;
1398ead0c3e2STyler Dauwalder 	array<char, 32> _abstract_file_id;
1399ead0c3e2STyler Dauwalder 	long_address _root_directory_icb;
1400ead0c3e2STyler Dauwalder 	entity_id _domain_id;
1401ead0c3e2STyler Dauwalder 	long_address _next_extent;
1402ead0c3e2STyler Dauwalder 	long_address _system_stream_directory_icb;
1403d1a0387eSTyler Dauwalder 	array<uint8, 32> _reserved;
1404ead0c3e2STyler Dauwalder } __attribute__((packed));
1405ead0c3e2STyler Dauwalder 
1406ead0c3e2STyler Dauwalder 
1407ead0c3e2STyler Dauwalder /*! \brief Partition header descriptor
1408ead0c3e2STyler Dauwalder 
1409ead0c3e2STyler Dauwalder 	Contains references to unallocated and freed space data structures.
1410ead0c3e2STyler Dauwalder 
1411ead0c3e2STyler Dauwalder 	Note that unallocated space is space ready to be written with no
1412ead0c3e2STyler Dauwalder 	preprocessing. Freed space is space needing preprocessing (i.e.
1413ead0c3e2STyler Dauwalder 	a special write pass) before use.
1414ead0c3e2STyler Dauwalder 
1415ead0c3e2STyler Dauwalder 	Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent,
1416ead0c3e2STyler Dauwalder 	i.e. only one type or the other shall be used, not both.
1417ead0c3e2STyler Dauwalder 
1418ead0c3e2STyler Dauwalder 	To indicate disuse of a certain field, the fields of the allocation
1419ead0c3e2STyler Dauwalder 	descriptor shall all be set to 0.
1420ead0c3e2STyler Dauwalder 
1421ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1422ead0c3e2STyler Dauwalder */
1423ead0c3e2STyler Dauwalder struct partition_header_descriptor {
1424ead0c3e2STyler Dauwalder 	long_address unallocated_space_table;
1425ead0c3e2STyler Dauwalder 	long_address unallocated_space_bitmap;
1426ead0c3e2STyler Dauwalder 	/*! Unused, per UDF-2.01 2.2.3 */
1427ead0c3e2STyler Dauwalder 	long_address partition_integrity_table;
1428ead0c3e2STyler Dauwalder 	long_address freed_space_table;
1429ead0c3e2STyler Dauwalder 	long_address freed_space_bitmap;
1430ead0c3e2STyler Dauwalder 	uint8 reserved[88];
1431ead0c3e2STyler Dauwalder } __attribute__((packed));
1432ead0c3e2STyler Dauwalder 
1433ead0c3e2STyler Dauwalder #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1434ead0c3e2STyler Dauwalder 
1435ead0c3e2STyler Dauwalder /*! \brief File identifier descriptor
1436ead0c3e2STyler Dauwalder 
1437ead0c3e2STyler Dauwalder 	Identifies the name of a file entry, and the location of its corresponding
1438ead0c3e2STyler Dauwalder 	ICB.
1439ead0c3e2STyler Dauwalder 
1440ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1441ead0c3e2STyler Dauwalder 
1442ead0c3e2STyler Dauwalder 	\todo Check pointer arithmetic
1443ead0c3e2STyler Dauwalder */
1444ead0c3e2STyler Dauwalder struct file_id_descriptor {
1445ead0c3e2STyler Dauwalder public:
1446ead0c3e2STyler Dauwalder 	void dump() const;
1447ead0c3e2STyler Dauwalder 
1448ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1449ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1450ead0c3e2STyler Dauwalder 
1451ead0c3e2STyler Dauwalder 	uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1452ead0c3e2STyler Dauwalder 
1453ead0c3e2STyler Dauwalder 	uint8 characteristics() const { return _characteristics; }
1454ead0c3e2STyler Dauwalder 
1455ead0c3e2STyler Dauwalder 	bool may_be_hidden() const {
1456ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1457ead0c3e2STyler Dauwalder 		c.all = characteristics();
1458ead0c3e2STyler Dauwalder 		return c.bits.may_be_hidden;
1459ead0c3e2STyler Dauwalder 	}
1460ead0c3e2STyler Dauwalder 
1461ead0c3e2STyler Dauwalder 	bool is_directory() const {
1462ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1463ead0c3e2STyler Dauwalder 		c.all = characteristics();
1464ead0c3e2STyler Dauwalder 		return c.bits.is_directory;
1465ead0c3e2STyler Dauwalder 	}
1466ead0c3e2STyler Dauwalder 
1467ead0c3e2STyler Dauwalder 	bool is_deleted() const {
1468ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1469ead0c3e2STyler Dauwalder 		c.all = characteristics();
1470ead0c3e2STyler Dauwalder 		return c.bits.is_deleted;
1471ead0c3e2STyler Dauwalder 	}
1472ead0c3e2STyler Dauwalder 
1473ead0c3e2STyler Dauwalder 	bool is_parent() const {
1474ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1475ead0c3e2STyler Dauwalder 		c.all = characteristics();
1476ead0c3e2STyler Dauwalder 		return c.bits.is_parent;
1477ead0c3e2STyler Dauwalder 	}
1478ead0c3e2STyler Dauwalder 
1479ead0c3e2STyler Dauwalder 	bool is_metadata_stream() const {
1480ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1481ead0c3e2STyler Dauwalder 		c.all = characteristics();
1482ead0c3e2STyler Dauwalder 		return c.bits.is_metadata_stream;
1483ead0c3e2STyler Dauwalder 	}
1484ead0c3e2STyler Dauwalder 
1485ead0c3e2STyler Dauwalder 	uint8 id_length() const { return _id_length; }
1486ead0c3e2STyler Dauwalder 
1487ead0c3e2STyler Dauwalder 	long_address& icb() { return _icb; }
1488ead0c3e2STyler Dauwalder 	const long_address& icb() const { return _icb; }
1489ead0c3e2STyler Dauwalder 
1490ead0c3e2STyler Dauwalder 	uint8 implementation_use_length() const { return _implementation_use_length; }
1491ead0c3e2STyler Dauwalder 
1492ead0c3e2STyler Dauwalder 	/*! If implementation_use_length is greater than 0, the first 32
1493ead0c3e2STyler Dauwalder 		bytes of implementation_use() shall be an entity_id identifying
1494ead0c3e2STyler Dauwalder 		the implementation that generated the rest of the data in the
1495ead0c3e2STyler Dauwalder 		implementation_use() field.
1496ead0c3e2STyler Dauwalder 	*/
1497*4f0e6a75STyler Dauwalder 	uint8* implementation_use() { return ((uint8*)this)+(38); }
1498*4f0e6a75STyler Dauwalder 	char* id() { return ((char*)this)+(38)+implementation_use_length(); }
1499*4f0e6a75STyler Dauwalder 	const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); }
1500ead0c3e2STyler Dauwalder 
1501*4f0e6a75STyler Dauwalder 	uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); }
1502ead0c3e2STyler Dauwalder 	uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); }
1503ead0c3e2STyler Dauwalder 	uint16 total_length() const { return structure_length() + padding_length(); }
1504ead0c3e2STyler Dauwalder 
1505ead0c3e2STyler Dauwalder 	// Set functions
1506ead0c3e2STyler Dauwalder 	void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1507ead0c3e2STyler Dauwalder 
1508ead0c3e2STyler Dauwalder 	void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
1509ead0c3e2STyler Dauwalder 
1510ead0c3e2STyler Dauwalder 	void set_may_be_hidden(bool how) {
1511ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1512ead0c3e2STyler Dauwalder 		c.all = characteristics();
1513ead0c3e2STyler Dauwalder 		c.bits.may_be_hidden = how;
1514ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1515ead0c3e2STyler Dauwalder 	}
1516ead0c3e2STyler Dauwalder 
1517ead0c3e2STyler Dauwalder 	void set_is_directory(bool how) {
1518ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1519ead0c3e2STyler Dauwalder 		c.all = characteristics();
1520ead0c3e2STyler Dauwalder 		c.bits.is_directory = how;
1521ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1522ead0c3e2STyler Dauwalder 	}
1523ead0c3e2STyler Dauwalder 
1524ead0c3e2STyler Dauwalder 	void set_is_deleted(bool how) {
1525ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1526ead0c3e2STyler Dauwalder 		c.all = characteristics();
1527ead0c3e2STyler Dauwalder 		c.bits.is_deleted = how;
1528ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1529ead0c3e2STyler Dauwalder 	}
1530ead0c3e2STyler Dauwalder 
1531ead0c3e2STyler Dauwalder 	void set_is_parent(bool how) {
1532ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1533ead0c3e2STyler Dauwalder 		c.all = characteristics();
1534ead0c3e2STyler Dauwalder 		c.bits.is_parent = how;
1535ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1536ead0c3e2STyler Dauwalder 	}
1537ead0c3e2STyler Dauwalder 
1538ead0c3e2STyler Dauwalder 	void set_is_metadata_stream(bool how) {
1539ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1540ead0c3e2STyler Dauwalder 		c.all = characteristics();
1541ead0c3e2STyler Dauwalder 		c.bits.is_metadata_stream = how;
1542ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1543ead0c3e2STyler Dauwalder 	}
1544ead0c3e2STyler Dauwalder 
1545ead0c3e2STyler Dauwalder 
1546ead0c3e2STyler Dauwalder 	void set_id_length(uint8 id_length) { _id_length = id_length; }
1547ead0c3e2STyler Dauwalder 	void set_implementation_use_length(uint8 implementation_use_length) { _implementation_use_length = implementation_use_length; }
1548ead0c3e2STyler Dauwalder 
1549ead0c3e2STyler Dauwalder 
1550ead0c3e2STyler Dauwalder 
1551ead0c3e2STyler Dauwalder private:
1552ead0c3e2STyler Dauwalder 	union characteristics_accessor {
1553ead0c3e2STyler Dauwalder 		uint8 all;
1554ead0c3e2STyler Dauwalder 		struct {
1555ead0c3e2STyler Dauwalder 			uint8	may_be_hidden:1,
1556ead0c3e2STyler Dauwalder 					is_directory:1,
1557ead0c3e2STyler Dauwalder 					is_deleted:1,
1558ead0c3e2STyler Dauwalder 					is_parent:1,
1559ead0c3e2STyler Dauwalder 					is_metadata_stream:1,
1560ead0c3e2STyler Dauwalder 					reserved_characteristics:3;
1561ead0c3e2STyler Dauwalder 		} bits;
1562ead0c3e2STyler Dauwalder 	};
1563ead0c3e2STyler Dauwalder 
1564ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1565ead0c3e2STyler Dauwalder 	/*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1566ead0c3e2STyler Dauwalder 
1567ead0c3e2STyler Dauwalder 		However, according to UDF-2.01, there shall be exactly one version of
1568ead0c3e2STyler Dauwalder 		a file, and it shall be 1.
1569ead0c3e2STyler Dauwalder 	 */
1570ead0c3e2STyler Dauwalder 	uint16 _version_number;
1571ead0c3e2STyler Dauwalder 	/*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */
1572ead0c3e2STyler Dauwalder 	uint8 _characteristics;
1573ead0c3e2STyler Dauwalder 	uint8 _id_length;
1574ead0c3e2STyler Dauwalder 	long_address _icb;
1575ead0c3e2STyler Dauwalder 	uint8 _implementation_use_length;
1576ead0c3e2STyler Dauwalder } __attribute__((packed));
1577ead0c3e2STyler Dauwalder 
1578ead0c3e2STyler Dauwalder 
1579ead0c3e2STyler Dauwalder /*! \brief Allocation extent descriptor
1580ead0c3e2STyler Dauwalder 
1581ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.5
1582ead0c3e2STyler Dauwalder */
1583ead0c3e2STyler Dauwalder struct allocation_extent_descriptor {
1584ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1585ead0c3e2STyler Dauwalder 	uint32 previous_allocation_extent_location;
1586ead0c3e2STyler Dauwalder 	uint32 length_of_allocation_descriptors;
1587ead0c3e2STyler Dauwalder 
1588ead0c3e2STyler Dauwalder 	/*! \todo Check that this is really how things work: */
1589ead0c3e2STyler Dauwalder 	uint8* allocation_descriptors() { return (uint8*)(this+sizeof(allocation_extent_descriptor)); }
1590ead0c3e2STyler Dauwalder } __attribute__((packed));
1591ead0c3e2STyler Dauwalder 
1592ead0c3e2STyler Dauwalder 
1593ead0c3e2STyler Dauwalder /*! \brief icb_tag::file_type values
1594ead0c3e2STyler Dauwalder 
1595ead0c3e2STyler Dauwalder 	See also ECMA-167 4/14.6.6
1596ead0c3e2STyler Dauwalder */
1597ead0c3e2STyler Dauwalder enum icb_file_types {
1598ead0c3e2STyler Dauwalder 	ICB_TYPE_UNSPECIFIED = 0,
1599ead0c3e2STyler Dauwalder 	ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1600ead0c3e2STyler Dauwalder 	ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1601ead0c3e2STyler Dauwalder 	ICB_TYPE_INDIRECT_ENTRY,
1602ead0c3e2STyler Dauwalder 	ICB_TYPE_DIRECTORY,
1603ead0c3e2STyler Dauwalder 	ICB_TYPE_REGULAR_FILE,
1604ead0c3e2STyler Dauwalder 	ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1605ead0c3e2STyler Dauwalder 	ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1606ead0c3e2STyler Dauwalder 	ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1607ead0c3e2STyler Dauwalder 	ICB_TYPE_FIFO,
1608ead0c3e2STyler Dauwalder 	ICB_TYPE_ISSOCK,
1609ead0c3e2STyler Dauwalder 	ICB_TYPE_TERMINAL,
1610ead0c3e2STyler Dauwalder 	ICB_TYPE_SYMLINK,
1611ead0c3e2STyler Dauwalder 	ICB_TYPE_STREAM_DIRECTORY,
1612ead0c3e2STyler Dauwalder 
1613ead0c3e2STyler Dauwalder 	ICB_TYPE_RESERVED_START = 14,
1614ead0c3e2STyler Dauwalder 	ICB_TYPE_RESERVED_END = 247,
1615ead0c3e2STyler Dauwalder 
1616ead0c3e2STyler Dauwalder 	ICB_TYPE_CUSTOM_START = 248,
1617ead0c3e2STyler Dauwalder 	ICB_TYPE_CUSTOM_END = 255,
1618ead0c3e2STyler Dauwalder };
1619ead0c3e2STyler Dauwalder 
1620ead0c3e2STyler Dauwalder /*!	\brief idb_entry_tag::_flags::descriptor_flags() values
1621ead0c3e2STyler Dauwalder 
1622ead0c3e2STyler Dauwalder 	See also ECMA-167 4/14.6.8
1623ead0c3e2STyler Dauwalder */
1624ead0c3e2STyler Dauwalder enum icb_descriptor_types {
1625ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_SHORT = 0,
1626ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_LONG,
1627ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_EXTENDED,
1628ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_EMBEDDED,
1629ead0c3e2STyler Dauwalder };
1630ead0c3e2STyler Dauwalder 
1631e631ed51STyler Dauwalder /*!	\brief idb_entry_tag::strategy_type() values
1632e631ed51STyler Dauwalder 
1633e631ed51STyler Dauwalder 	See also UDF-2.50 2.3.5.1
1634e631ed51STyler Dauwalder */
1635e631ed51STyler Dauwalder enum icb_strategy_types {
1636e631ed51STyler Dauwalder 	ICB_STRATEGY_SINGLE = 4,
1637e631ed51STyler Dauwalder 	ICB_STRATEGY_LINKED_LIST = 4096
1638e631ed51STyler Dauwalder };
1639e631ed51STyler Dauwalder 
1640ead0c3e2STyler Dauwalder /*! \brief ICB entry tag
1641ead0c3e2STyler Dauwalder 
1642ead0c3e2STyler Dauwalder 	Common tag found in all ICB entries (in addition to, and immediately following,
1643ead0c3e2STyler Dauwalder 	the descriptor tag).
1644ead0c3e2STyler Dauwalder 
1645ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1646ead0c3e2STyler Dauwalder */
1647ead0c3e2STyler Dauwalder struct icb_entry_tag {
1648e631ed51STyler Dauwalder public:
1649ead0c3e2STyler Dauwalder 	union flags_accessor {
1650ead0c3e2STyler Dauwalder 		uint16 all_flags;
1651ead0c3e2STyler Dauwalder 		struct {
1652ead0c3e2STyler Dauwalder 			uint16	descriptor_flags:3,
1653ead0c3e2STyler Dauwalder 					if_directory_then_sort:1,	//!< To be set to 0 per UDF-2.01 2.3.5.4
1654ead0c3e2STyler Dauwalder 					non_relocatable:1,
1655ead0c3e2STyler Dauwalder 					archive:1,
1656ead0c3e2STyler Dauwalder 					setuid:1,
1657ead0c3e2STyler Dauwalder 					setgid:1,
1658ead0c3e2STyler Dauwalder 					sticky:1,
1659ead0c3e2STyler Dauwalder 					contiguous:1,
1660ead0c3e2STyler Dauwalder 					system:1,
1661ead0c3e2STyler Dauwalder 					transformed:1,
1662ead0c3e2STyler Dauwalder 					multi_version:1,			//!< To be set to 0 per UDF-2.01 2.3.5.4
1663ead0c3e2STyler Dauwalder 					is_stream:1,
1664ead0c3e2STyler Dauwalder 					reserved_icb_entry_flags:2;
1665ead0c3e2STyler Dauwalder 		} flags;
1666ead0c3e2STyler Dauwalder 	};
1667ead0c3e2STyler Dauwalder 
1668ead0c3e2STyler Dauwalder public:
1669ead0c3e2STyler Dauwalder 	void dump() const;
1670ead0c3e2STyler Dauwalder 
1671ead0c3e2STyler Dauwalder 	uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); }
1672ead0c3e2STyler Dauwalder 	uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); }
1673ead0c3e2STyler Dauwalder 
1674ead0c3e2STyler Dauwalder 	array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
1675ead0c3e2STyler Dauwalder 	const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
1676ead0c3e2STyler Dauwalder 
1677ead0c3e2STyler Dauwalder 	uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); }
1678e631ed51STyler Dauwalder 	uint8& reserved() { return _reserved; }
1679ead0c3e2STyler Dauwalder 	uint8 file_type() const { return _file_type; }
1680ead0c3e2STyler Dauwalder 	logical_block_address& parent_icb_location() { return _parent_icb_location; }
1681ead0c3e2STyler Dauwalder 	const logical_block_address& parent_icb_location() const { return _parent_icb_location; }
1682ead0c3e2STyler Dauwalder 
1683ead0c3e2STyler Dauwalder 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
1684e631ed51STyler Dauwalder 	flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); }
1685ead0c3e2STyler Dauwalder 
1686ead0c3e2STyler Dauwalder 	// flags accessor functions
1687ead0c3e2STyler Dauwalder 	uint8 descriptor_flags() const {
1688ead0c3e2STyler Dauwalder 		flags_accessor f;
1689ead0c3e2STyler Dauwalder 		f.all_flags = flags();
1690ead0c3e2STyler Dauwalder 		return f.flags.descriptor_flags;
1691ead0c3e2STyler Dauwalder 	}
1692e631ed51STyler Dauwalder /*	void set_descriptor_flags(uint8 value) {
1693e631ed51STyler Dauwalder 		flags_accessor f;
1694e631ed51STyler Dauwalder 		f.all_flags = flags();
1695e631ed51STyler Dauwalder 		f.flags.descriptor_flags = value;
1696e631ed51STyler Dauwalder 		set_flags
1697e631ed51STyler Dauwalder */
1698ead0c3e2STyler Dauwalder 
1699ead0c3e2STyler Dauwalder 	void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); }
1700ead0c3e2STyler Dauwalder 	void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); }
1701ead0c3e2STyler Dauwalder 
1702ead0c3e2STyler Dauwalder 	void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); }
1703ead0c3e2STyler Dauwalder 	void set_file_type(uint8 type) { _file_type = type; }
1704ead0c3e2STyler Dauwalder 
1705ead0c3e2STyler Dauwalder 	void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1706ead0c3e2STyler Dauwalder 
1707ead0c3e2STyler Dauwalder private:
1708ead0c3e2STyler Dauwalder 	uint32 _prior_recorded_number_of_direct_entries;
1709ead0c3e2STyler Dauwalder 	/*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1710ead0c3e2STyler Dauwalder 
1711ead0c3e2STyler Dauwalder 		\todo Describe strategy types here.
1712ead0c3e2STyler Dauwalder 	*/
1713ead0c3e2STyler Dauwalder 	uint16 _strategy_type;
1714ead0c3e2STyler Dauwalder 	array<uint8, 2> _strategy_parameters;
1715ead0c3e2STyler Dauwalder 	uint16 _entry_count;
1716ead0c3e2STyler Dauwalder 	uint8 _reserved;
1717ead0c3e2STyler Dauwalder 	/*! \brief icb_file_type value identifying the type of this icb entry */
1718ead0c3e2STyler Dauwalder 	uint8 _file_type;
1719ead0c3e2STyler Dauwalder 	logical_block_address _parent_icb_location;
1720ead0c3e2STyler Dauwalder 	uint16 _flags;
1721ead0c3e2STyler Dauwalder } __attribute__((packed));
1722ead0c3e2STyler Dauwalder 
1723ead0c3e2STyler Dauwalder /*! \brief Header portion of an ICB entry.
1724ead0c3e2STyler Dauwalder */
1725ead0c3e2STyler Dauwalder struct icb_header {
1726ead0c3e2STyler Dauwalder public:
1727ead0c3e2STyler Dauwalder 	void dump() const;
1728ead0c3e2STyler Dauwalder 
1729ead0c3e2STyler Dauwalder 	descriptor_tag  &tag() { return _tag; }
1730ead0c3e2STyler Dauwalder 	const descriptor_tag  &tag() const { return _tag; }
1731ead0c3e2STyler Dauwalder 
1732ead0c3e2STyler Dauwalder 	icb_entry_tag &icb_tag() { return _icb_tag; }
1733ead0c3e2STyler Dauwalder 	const icb_entry_tag &icb_tag() const { return _icb_tag; }
1734ead0c3e2STyler Dauwalder private:
1735ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1736ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
1737ead0c3e2STyler Dauwalder };
1738ead0c3e2STyler Dauwalder 
1739ead0c3e2STyler Dauwalder /*! \brief Indirect ICB entry
1740ead0c3e2STyler Dauwalder */
1741ead0c3e2STyler Dauwalder struct indirect_icb_entry {
1742ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1743ead0c3e2STyler Dauwalder 	icb_entry_tag icb_tag;
1744ead0c3e2STyler Dauwalder 	long_address indirect_icb;
1745ead0c3e2STyler Dauwalder } __attribute__((packed));
1746ead0c3e2STyler Dauwalder 
1747ead0c3e2STyler Dauwalder 
1748ead0c3e2STyler Dauwalder /*! \brief Terminal ICB entry
1749ead0c3e2STyler Dauwalder */
1750ead0c3e2STyler Dauwalder struct terminal_icb_entry {
1751ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1752ead0c3e2STyler Dauwalder 	icb_entry_tag icb_tag;
1753ead0c3e2STyler Dauwalder } __attribute__((packed));
1754ead0c3e2STyler Dauwalder 
1755e631ed51STyler Dauwalder enum permissions {
1756e631ed51STyler Dauwalder 	OTHER_EXECUTE	 	= 0x0001,
1757e631ed51STyler Dauwalder 	OTHER_WRITE			= 0x0002,
1758e631ed51STyler Dauwalder 	OTHER_READ			= 0x0004,
1759e631ed51STyler Dauwalder 	OTHER_ATTRIBUTES	= 0x0008,
1760e631ed51STyler Dauwalder 	OTHER_DELETE		= 0x0010,
1761e631ed51STyler Dauwalder 	GROUP_EXECUTE	 	= 0x0020,
1762e631ed51STyler Dauwalder 	GROUP_WRITE			= 0x0040,
1763e631ed51STyler Dauwalder 	GROUP_READ			= 0x0080,
1764e631ed51STyler Dauwalder 	GROUP_ATTRIBUTES	= 0x0100,
1765e631ed51STyler Dauwalder 	GROUP_DELETE		= 0x0200,
1766e631ed51STyler Dauwalder 	USER_EXECUTE	 	= 0x0400,
1767e631ed51STyler Dauwalder 	USER_WRITE			= 0x0800,
1768e631ed51STyler Dauwalder 	USER_READ			= 0x1000,
1769e631ed51STyler Dauwalder 	USER_ATTRIBUTES		= 0x2000,
1770e631ed51STyler Dauwalder 	USER_DELETE			= 0x4000,
1771e631ed51STyler Dauwalder };
1772ead0c3e2STyler Dauwalder 
1773ead0c3e2STyler Dauwalder /*! \brief File ICB entry
1774ead0c3e2STyler Dauwalder 
1775ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.9
1776ead0c3e2STyler Dauwalder 
1777ead0c3e2STyler Dauwalder 	\todo Check pointer math.
1778ead0c3e2STyler Dauwalder */
1779ead0c3e2STyler Dauwalder struct file_icb_entry {
1780e631ed51STyler Dauwalder 	void dump() const;
1781e631ed51STyler Dauwalder 
1782ead0c3e2STyler Dauwalder 	// get functions
1783ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1784ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1785ead0c3e2STyler Dauwalder 
1786ead0c3e2STyler Dauwalder 	icb_entry_tag& icb_tag() { return _icb_tag; }
1787ead0c3e2STyler Dauwalder 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
1788ead0c3e2STyler Dauwalder 
1789e631ed51STyler Dauwalder 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
1790e631ed51STyler Dauwalder 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
1791e631ed51STyler Dauwalder 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
1792e631ed51STyler Dauwalder 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
1793e631ed51STyler Dauwalder 	uint8 record_format() const { return _record_format; }
1794e631ed51STyler Dauwalder 	uint8 record_display_attributes() const { return _record_display_attributes; }
1795e631ed51STyler Dauwalder 	uint8 record_length() const { return _record_length; }
1796e631ed51STyler Dauwalder 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
1797e631ed51STyler Dauwalder 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
1798ead0c3e2STyler Dauwalder 
1799ead0c3e2STyler Dauwalder 	timestamp& access_date_and_time() { return _access_date_and_time; }
1800ead0c3e2STyler Dauwalder 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
1801ead0c3e2STyler Dauwalder 
1802ead0c3e2STyler Dauwalder 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
1803ead0c3e2STyler Dauwalder 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
1804ead0c3e2STyler Dauwalder 
1805ead0c3e2STyler Dauwalder 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
1806ead0c3e2STyler Dauwalder 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
1807ead0c3e2STyler Dauwalder 
1808e631ed51STyler Dauwalder 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
1809ead0c3e2STyler Dauwalder 
1810ead0c3e2STyler Dauwalder 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
1811ead0c3e2STyler Dauwalder 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
1812ead0c3e2STyler Dauwalder 
1813ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
1814ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
1815ead0c3e2STyler Dauwalder 
1816e631ed51STyler Dauwalder 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
1817e631ed51STyler Dauwalder 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
1818e631ed51STyler Dauwalder 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
1819ead0c3e2STyler Dauwalder 
1820*4f0e6a75STyler Dauwalder 	uint8* extended_attributes() const { return ((uint8*)(this))+sizeof(file_icb_entry); }
1821*4f0e6a75STyler Dauwalder 	uint8* allocation_descriptors() const { return ((uint8*)(this))+sizeof(file_icb_entry)+extended_attributes_length(); }
1822ead0c3e2STyler Dauwalder 
1823ead0c3e2STyler Dauwalder 	// set functions
1824ead0c3e2STyler Dauwalder 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
1825ead0c3e2STyler Dauwalder 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
1826ead0c3e2STyler Dauwalder 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
1827ead0c3e2STyler Dauwalder 
1828ead0c3e2STyler Dauwalder 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
1829ead0c3e2STyler Dauwalder 	void set_record_format(uint8 format) { _record_format = format; }
1830ead0c3e2STyler Dauwalder 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
1831ead0c3e2STyler Dauwalder 	void set_record_length(uint8 length) { _record_length = length; }
1832ead0c3e2STyler Dauwalder 
1833ead0c3e2STyler Dauwalder 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
1834ead0c3e2STyler Dauwalder 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
1835ead0c3e2STyler Dauwalder 
1836ead0c3e2STyler Dauwalder 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
1837ead0c3e2STyler Dauwalder 
1838ead0c3e2STyler Dauwalder 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
1839ead0c3e2STyler Dauwalder 
1840ead0c3e2STyler Dauwalder 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
1841ead0c3e2STyler Dauwalder 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
1842ead0c3e2STyler Dauwalder 
1843ead0c3e2STyler Dauwalder private:
1844ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1845ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
1846ead0c3e2STyler Dauwalder 	uint32 _uid;
1847ead0c3e2STyler Dauwalder 	uint32 _gid;
1848ead0c3e2STyler Dauwalder 	/*! \todo List perms in comment and add handy union thingy */
1849ead0c3e2STyler Dauwalder 	uint32 _permissions;
1850ead0c3e2STyler Dauwalder 	/*! Identifies the number of file identifier descriptors referencing
1851ead0c3e2STyler Dauwalder 		this icb.
1852ead0c3e2STyler Dauwalder 	*/
1853ead0c3e2STyler Dauwalder 	uint16 _file_link_count;
1854ead0c3e2STyler Dauwalder 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
1855ead0c3e2STyler Dauwalder 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
1856ead0c3e2STyler Dauwalder 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
1857ead0c3e2STyler Dauwalder 	uint64 _information_length;
1858ead0c3e2STyler Dauwalder 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
1859ead0c3e2STyler Dauwalder 	timestamp _access_date_and_time;
1860ead0c3e2STyler Dauwalder 	timestamp _modification_date_and_time;
1861ead0c3e2STyler Dauwalder 
1862ead0c3e2STyler Dauwalder 	// NOTE: data members following this point in the descriptor are in
1863ead0c3e2STyler Dauwalder 	// different locations in extended file entries
1864ead0c3e2STyler Dauwalder 
1865ead0c3e2STyler Dauwalder 	timestamp _attribute_date_and_time;
1866ead0c3e2STyler Dauwalder 	/*! \brief Initially 1, may be incremented upon user request. */
1867ead0c3e2STyler Dauwalder 	uint32 _checkpoint;
1868ead0c3e2STyler Dauwalder 	long_address _extended_attribute_icb;
1869ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
1870ead0c3e2STyler Dauwalder 	/*! \brief The unique id identifying this file entry
1871ead0c3e2STyler Dauwalder 
1872ead0c3e2STyler Dauwalder 		The id of the root directory of a file set shall be 0.
1873ead0c3e2STyler Dauwalder 
1874ead0c3e2STyler Dauwalder 		\todo Detail the system specific requirements for unique ids from UDF-2.01
1875ead0c3e2STyler Dauwalder 	*/
1876ead0c3e2STyler Dauwalder 	uint64 _unique_id;
1877ead0c3e2STyler Dauwalder 	uint32 _extended_attributes_length;
1878ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptors_length;
1879ead0c3e2STyler Dauwalder 
1880ead0c3e2STyler Dauwalder };
1881ead0c3e2STyler Dauwalder 
1882ead0c3e2STyler Dauwalder 
1883ead0c3e2STyler Dauwalder /*! \brief Extended file ICB entry
1884ead0c3e2STyler Dauwalder 
1885ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.17
1886ead0c3e2STyler Dauwalder 
1887ead0c3e2STyler Dauwalder 	\todo Check pointer math.
1888ead0c3e2STyler Dauwalder */
1889ead0c3e2STyler Dauwalder struct extended_file_icb_entry {
1890e631ed51STyler Dauwalder 	void dump() const;
1891e631ed51STyler Dauwalder 
1892ead0c3e2STyler Dauwalder 	// get functions
1893ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1894ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1895ead0c3e2STyler Dauwalder 
1896ead0c3e2STyler Dauwalder 	icb_entry_tag& icb_tag() { return _icb_tag; }
1897ead0c3e2STyler Dauwalder 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
1898ead0c3e2STyler Dauwalder 
1899e631ed51STyler Dauwalder 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
1900e631ed51STyler Dauwalder 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
1901e631ed51STyler Dauwalder 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
1902e631ed51STyler Dauwalder 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
1903e631ed51STyler Dauwalder 	uint8 record_format() const { return _record_format; }
1904e631ed51STyler Dauwalder 	uint8 record_display_attributes() const { return _record_display_attributes; }
1905e631ed51STyler Dauwalder 	uint8 record_length() const { return _record_length; }
1906e631ed51STyler Dauwalder 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
1907e631ed51STyler Dauwalder 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
1908ead0c3e2STyler Dauwalder 
1909ead0c3e2STyler Dauwalder 	timestamp& access_date_and_time() { return _access_date_and_time; }
1910ead0c3e2STyler Dauwalder 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
1911ead0c3e2STyler Dauwalder 
1912ead0c3e2STyler Dauwalder 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
1913ead0c3e2STyler Dauwalder 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
1914ead0c3e2STyler Dauwalder 
1915e631ed51STyler Dauwalder 	timestamp& creation_date_and_time() { return _creation_date_and_time; }
1916e631ed51STyler Dauwalder 	const timestamp& creation_date_and_time() const { return _creation_date_and_time; }
1917e631ed51STyler Dauwalder 
1918ead0c3e2STyler Dauwalder 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
1919ead0c3e2STyler Dauwalder 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
1920ead0c3e2STyler Dauwalder 
1921e631ed51STyler Dauwalder 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
1922ead0c3e2STyler Dauwalder 
1923ead0c3e2STyler Dauwalder 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
1924ead0c3e2STyler Dauwalder 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
1925ead0c3e2STyler Dauwalder 
1926e631ed51STyler Dauwalder 	long_address& stream_directory_icb() { return _stream_directory_icb; }
1927e631ed51STyler Dauwalder 	const long_address& stream_directory_icb() const { return _stream_directory_icb; }
1928e631ed51STyler Dauwalder 
1929ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
1930ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
1931ead0c3e2STyler Dauwalder 
1932e631ed51STyler Dauwalder 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
1933e631ed51STyler Dauwalder 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
1934e631ed51STyler Dauwalder 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
1935ead0c3e2STyler Dauwalder 
1936*4f0e6a75STyler Dauwalder 	uint8* extended_attributes() const { return (uint8*)(this+sizeof(extended_file_icb_entry)); }
1937*4f0e6a75STyler Dauwalder 	uint8* allocation_descriptors() const { return (uint8*)(this+sizeof(sizeof(extended_file_icb_entry))+extended_attributes_length()); }
1938ead0c3e2STyler Dauwalder 
1939ead0c3e2STyler Dauwalder 	// set functions
1940ead0c3e2STyler Dauwalder 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
1941ead0c3e2STyler Dauwalder 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
1942ead0c3e2STyler Dauwalder 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
1943ead0c3e2STyler Dauwalder 
1944ead0c3e2STyler Dauwalder 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
1945ead0c3e2STyler Dauwalder 	void set_record_format(uint8 format) { _record_format = format; }
1946ead0c3e2STyler Dauwalder 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
1947ead0c3e2STyler Dauwalder 	void set_record_length(uint8 length) { _record_length = length; }
1948ead0c3e2STyler Dauwalder 
1949ead0c3e2STyler Dauwalder 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
1950ead0c3e2STyler Dauwalder 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
1951ead0c3e2STyler Dauwalder 
1952ead0c3e2STyler Dauwalder 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
1953e631ed51STyler Dauwalder 	void set_reserved(uint32 reserved) { _reserved = B_HOST_TO_LENDIAN_INT32(reserved); }
1954ead0c3e2STyler Dauwalder 
1955ead0c3e2STyler Dauwalder 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
1956ead0c3e2STyler Dauwalder 
1957ead0c3e2STyler Dauwalder 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
1958ead0c3e2STyler Dauwalder 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
1959ead0c3e2STyler Dauwalder 
1960ead0c3e2STyler Dauwalder private:
1961ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1962ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
1963ead0c3e2STyler Dauwalder 	uint32 _uid;
1964ead0c3e2STyler Dauwalder 	uint32 _gid;
1965ead0c3e2STyler Dauwalder 	/*! \todo List perms in comment and add handy union thingy */
1966ead0c3e2STyler Dauwalder 	uint32 _permissions;
1967ead0c3e2STyler Dauwalder 	/*! Identifies the number of file identifier descriptors referencing
1968ead0c3e2STyler Dauwalder 		this icb.
1969ead0c3e2STyler Dauwalder 	*/
1970ead0c3e2STyler Dauwalder 	uint16 _file_link_count;
1971ead0c3e2STyler Dauwalder 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
1972ead0c3e2STyler Dauwalder 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
1973ead0c3e2STyler Dauwalder 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
1974ead0c3e2STyler Dauwalder 	uint64 _information_length;
1975ead0c3e2STyler Dauwalder 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
1976ead0c3e2STyler Dauwalder 	timestamp _access_date_and_time;
1977ead0c3e2STyler Dauwalder 	timestamp _modification_date_and_time;
1978ead0c3e2STyler Dauwalder 	timestamp _creation_date_and_time;	// <== EXTENDED FILE ENTRY ONLY
1979ead0c3e2STyler Dauwalder 	timestamp _attribute_date_and_time;
1980ead0c3e2STyler Dauwalder 	/*! \brief Initially 1, may be incremented upon user request. */
1981ead0c3e2STyler Dauwalder 	uint32 _checkpoint;
1982ead0c3e2STyler Dauwalder 	uint32 _reserved;	// <== EXTENDED FILE ENTRY ONLY
1983ead0c3e2STyler Dauwalder 	long_address _extended_attribute_icb;
1984ead0c3e2STyler Dauwalder 	long_address _stream_directory_icb;	// <== EXTENDED FILE ENTRY ONLY
1985ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
1986ead0c3e2STyler Dauwalder 	/*! \brief The unique id identifying this file entry
1987ead0c3e2STyler Dauwalder 
1988ead0c3e2STyler Dauwalder 		The id of the root directory of a file set shall be 0.
1989ead0c3e2STyler Dauwalder 
1990ead0c3e2STyler Dauwalder 		\todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
1991ead0c3e2STyler Dauwalder 	*/
1992ead0c3e2STyler Dauwalder 	uint64 _unique_id;
1993ead0c3e2STyler Dauwalder 	uint32 _extended_attributes_length;
1994ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptors_length;
1995ead0c3e2STyler Dauwalder 
1996ead0c3e2STyler Dauwalder };
1997ead0c3e2STyler Dauwalder 
1998ead0c3e2STyler Dauwalder 
1999ead0c3e2STyler Dauwalder };	// namespace Udf
2000ead0c3e2STyler Dauwalder 
2001ead0c3e2STyler Dauwalder #endif	// _UDF_DISK_STRUCTURES_H
2002ead0c3e2STyler Dauwalder 
2003