xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.h (revision 49a6a0ebf3eb74e92ea0b1155c8bef5d507b246d)
1c530d46cSJérôme Duval /*
2c530d46cSJérôme Duval  * Copyright 2012, Jérôme Duval, korli@users.berlios.de.
3c530d46cSJérôme Duval  * Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
4c530d46cSJérôme Duval  * This file may be used under the terms of the MIT License.
5c530d46cSJérôme Duval  */
6ead0c3e2STyler Dauwalder #ifndef _UDF_DISK_STRUCTURES_H
7ead0c3e2STyler Dauwalder #define _UDF_DISK_STRUCTURES_H
8ead0c3e2STyler Dauwalder 
9ead0c3e2STyler Dauwalder #include <string.h>
10ead0c3e2STyler Dauwalder 
11ead0c3e2STyler Dauwalder #include <ByteOrder.h>
12ead0c3e2STyler Dauwalder #include <SupportDefs.h>
13ead0c3e2STyler Dauwalder 
14ead0c3e2STyler Dauwalder #include "UdfDebug.h"
1520d84995SRene Gollent #include "Utils.h"
16ead0c3e2STyler Dauwalder 
17ead0c3e2STyler Dauwalder #include "Array.h"
18ead0c3e2STyler Dauwalder 
19c21aaa8aSTyler Dauwalder /*! \file UdfStructures.h
20ead0c3e2STyler Dauwalder 
21ead0c3e2STyler Dauwalder 	\brief UDF on-disk data structure declarations
22ead0c3e2STyler Dauwalder 
23ead0c3e2STyler Dauwalder 	UDF is a specialization of the ECMA-167 standard. For the most part,
24ead0c3e2STyler Dauwalder 	ECMA-167 structures are used by UDF with special restrictions. In a
25ead0c3e2STyler Dauwalder 	few instances, UDF introduces its own structures to augment those
26ead0c3e2STyler Dauwalder 	supplied by ECMA-167; those structures are clearly marked.
27ead0c3e2STyler Dauwalder 
28ead0c3e2STyler Dauwalder 	For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a>
29ead0c3e2STyler Dauwalder 	For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a>
30ead0c3e2STyler Dauwalder 
31ead0c3e2STyler Dauwalder 	For lack of a better place to store this info, the structures that
32ead0c3e2STyler Dauwalder 	are allowed to have length greater than the logical block size are
33ead0c3e2STyler Dauwalder 	as follows (other length restrictions may be found in UDF-2.01 5.1):
34ead0c3e2STyler Dauwalder 	- \c logical_volume_descriptor
35ead0c3e2STyler Dauwalder 	- \c unallocated_space_descriptor
36ead0c3e2STyler Dauwalder 	- \c logical_volume_integrity_descriptor
37ead0c3e2STyler Dauwalder 	- \c space_bitmap_descriptor
38ead0c3e2STyler Dauwalder 
39ead0c3e2STyler Dauwalder 	Other links of interest:
40ead0c3e2STyler Dauwalder 	- <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a>
41ead0c3e2STyler Dauwalder 	- <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a>
42ead0c3e2STyler Dauwalder */
43ead0c3e2STyler Dauwalder 
44ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
45ead0c3e2STyler Dauwalder // ECMA-167 Part 1
46ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
47ead0c3e2STyler Dauwalder 
48ead0c3e2STyler Dauwalder /*! \brief Character set specifications
49ead0c3e2STyler Dauwalder 
50ead0c3e2STyler Dauwalder 	The character_set_info field shall be set to the ASCII string
51ead0c3e2STyler Dauwalder 	"OSTA Compressed Unicode" (padded right with NULL chars).
52ead0c3e2STyler Dauwalder 
53ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
54ead0c3e2STyler Dauwalder */
55ead0c3e2STyler Dauwalder struct charspec {
56ead0c3e2STyler Dauwalder public:
571801834fSTyler Dauwalder 	charspec(uint8 type = 0, const char *info = NULL);
581801834fSTyler Dauwalder 
59ead0c3e2STyler Dauwalder 	void dump() const;
60ead0c3e2STyler Dauwalder 
character_set_typecharspec61ead0c3e2STyler Dauwalder 	uint8 character_set_type() const { return _character_set_type; }
character_set_infocharspec62ead0c3e2STyler Dauwalder 	const char* character_set_info() const { return _character_set_info; }
character_set_infocharspec63ead0c3e2STyler Dauwalder 	char* character_set_info() { return _character_set_info; }
64ead0c3e2STyler Dauwalder 
set_character_set_typecharspec65ead0c3e2STyler Dauwalder 	void set_character_set_type(uint8 type) { _character_set_type = type; }
661801834fSTyler Dauwalder 	void set_character_set_info(const char *info);
67ead0c3e2STyler Dauwalder private:
68ead0c3e2STyler Dauwalder 	uint8 _character_set_type;	//!< to be set to 0 to indicate CS0
69ead0c3e2STyler Dauwalder 	char _character_set_info[63];	//!< "OSTA Compressed Unicode"
70ead0c3e2STyler Dauwalder } __attribute__((packed));
71ead0c3e2STyler Dauwalder 
721801834fSTyler Dauwalder extern const charspec kCs0CharacterSet;
73ead0c3e2STyler Dauwalder 
74ead0c3e2STyler Dauwalder /*! \brief Date and time stamp
75ead0c3e2STyler Dauwalder 
76ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
77ead0c3e2STyler Dauwalder */
78ead0c3e2STyler Dauwalder class timestamp {
79ead0c3e2STyler Dauwalder private:
80ead0c3e2STyler Dauwalder 	union type_and_timezone_accessor {
81ead0c3e2STyler Dauwalder 		uint16 type_and_timezone;
82ead0c3e2STyler Dauwalder 		struct {
8310186d5dSTyler Dauwalder 			uint16 timezone:12,
8410186d5dSTyler Dauwalder 			       type:4;
85ead0c3e2STyler Dauwalder 		} bits;
86ead0c3e2STyler Dauwalder 	};
87ead0c3e2STyler Dauwalder 
88ead0c3e2STyler Dauwalder public:
timestamp()899b438e89STyler Dauwalder 	timestamp() { _clear(); }
909b438e89STyler Dauwalder 	timestamp(time_t time);
919b438e89STyler Dauwalder 
92ead0c3e2STyler Dauwalder 	void dump() const;
93ead0c3e2STyler Dauwalder 
94ead0c3e2STyler Dauwalder 	// Get functions
type_and_timezone()95ead0c3e2STyler Dauwalder 	uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); }
type()96ead0c3e2STyler Dauwalder 	uint8 type() const {
97ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
98ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
99ead0c3e2STyler Dauwalder 		return t.bits.type;
100ead0c3e2STyler Dauwalder 	}
timezone()101ead0c3e2STyler Dauwalder 	int16 timezone() const {
102ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
103ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
1049b438e89STyler Dauwalder 		int16 result = t.bits.timezone;
1059b438e89STyler Dauwalder 		// Fill the lefmost bits with ones if timezone is negative
1069b438e89STyler Dauwalder 		result <<= 4;
1079b438e89STyler Dauwalder 		result >>= 4;
1089b438e89STyler Dauwalder 		return result;
109ead0c3e2STyler Dauwalder 	}
year()110ead0c3e2STyler Dauwalder 	uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); }
month()111ead0c3e2STyler Dauwalder 	uint8 month() const { return _month; }
day()112ead0c3e2STyler Dauwalder 	uint8 day() const { return _day; }
hour()113ead0c3e2STyler Dauwalder 	uint8 hour() const { return _hour; }
minute()114ead0c3e2STyler Dauwalder 	uint8 minute() const { return _minute; }
second()115ead0c3e2STyler Dauwalder 	uint8 second() const { return _second; }
centisecond()116ead0c3e2STyler Dauwalder 	uint8 centisecond() const { return _centisecond; }
hundred_microsecond()117ead0c3e2STyler Dauwalder 	uint8 hundred_microsecond() const { return _hundred_microsecond; }
microsecond()118ead0c3e2STyler Dauwalder 	uint8 microsecond() const { return _microsecond; }
119ead0c3e2STyler Dauwalder 
120ead0c3e2STyler Dauwalder 	// Set functions
set_type_and_timezone(uint16 type_and_timezone)121c530d46cSJérôme Duval 	void set_type_and_timezone(uint16 type_and_timezone) {
122c530d46cSJérôme Duval 		_type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
set_type(uint8 type)123ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
124ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
125ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
126ead0c3e2STyler Dauwalder 		t.bits.type = type;
127ead0c3e2STyler Dauwalder 		set_type_and_timezone(t.type_and_timezone);
128ead0c3e2STyler Dauwalder 	}
set_timezone(int16 tz)129003d4e83STyler Dauwalder 	void set_timezone(int16 tz) {
130ead0c3e2STyler Dauwalder 		type_and_timezone_accessor t;
131ead0c3e2STyler Dauwalder 		t.type_and_timezone = type_and_timezone();
132003d4e83STyler Dauwalder 		t.bits.timezone = tz;
133ead0c3e2STyler Dauwalder 		set_type_and_timezone(t.type_and_timezone);
134ead0c3e2STyler Dauwalder 	}
set_year(uint16 year)135ead0c3e2STyler Dauwalder 	void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
set_month(uint8 month)136ead0c3e2STyler Dauwalder 	void set_month(uint8 month) { _month = month; }
set_day(uint8 day)137ead0c3e2STyler Dauwalder 	void set_day(uint8 day) { _day = day; }
set_hour(uint8 hour)138ead0c3e2STyler Dauwalder 	void set_hour(uint8 hour) { _hour = hour; }
set_minute(uint8 minute)139ead0c3e2STyler Dauwalder 	void set_minute(uint8 minute) { _minute = minute; }
set_second(uint8 second)140ead0c3e2STyler Dauwalder 	void set_second(uint8 second) { _second = second; }
set_centisecond(uint8 centisecond)141ead0c3e2STyler Dauwalder 	void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
set_hundred_microsecond(uint8 hundred_microsecond)142c530d46cSJérôme Duval 	void set_hundred_microsecond(uint8 hundred_microsecond) {
143c530d46cSJérôme Duval 		_hundred_microsecond = hundred_microsecond; }
set_microsecond(uint8 microsecond)144ead0c3e2STyler Dauwalder 	void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
145ead0c3e2STyler Dauwalder private:
1469b438e89STyler Dauwalder 	void _clear();
1479b438e89STyler Dauwalder 
148ead0c3e2STyler Dauwalder 	uint16 _type_and_timezone;
149ead0c3e2STyler Dauwalder 	uint16 _year;
150ead0c3e2STyler Dauwalder 	uint8 _month;
151ead0c3e2STyler Dauwalder 	uint8 _day;
152ead0c3e2STyler Dauwalder 	uint8 _hour;
153ead0c3e2STyler Dauwalder 	uint8 _minute;
154ead0c3e2STyler Dauwalder 	uint8 _second;
155ead0c3e2STyler Dauwalder 	uint8 _centisecond;
156ead0c3e2STyler Dauwalder 	uint8 _hundred_microsecond;
157ead0c3e2STyler Dauwalder 	uint8 _microsecond;
158ead0c3e2STyler Dauwalder 
159ead0c3e2STyler Dauwalder } __attribute__((packed));
160ead0c3e2STyler Dauwalder 
161ead0c3e2STyler Dauwalder 
1629a043bf9STyler Dauwalder /*! \brief UDF ID Identify Suffix
1639a043bf9STyler Dauwalder 
1649a043bf9STyler Dauwalder 	See also: UDF 2.50 2.1.5.3
1659a043bf9STyler Dauwalder */
1669a043bf9STyler Dauwalder struct udf_id_suffix {
1679a043bf9STyler Dauwalder public:
1689a043bf9STyler Dauwalder 	udf_id_suffix(uint16 udfRevision, uint8 os_class, uint8 os_identifier);
1699a043bf9STyler Dauwalder 
1709a043bf9STyler Dauwalder 	//! Note that revision 2.50 is denoted by 0x0250.
udf_revisionudf_id_suffix1719a043bf9STyler Dauwalder 	uint16 udf_revision() const { return _udf_revision; }
os_classudf_id_suffix1729a043bf9STyler Dauwalder 	uint8 os_class() const { return _os_class; }
os_identifierudf_id_suffix1739a043bf9STyler Dauwalder 	uint8 os_identifier() const { return _os_identifier; }
1749a043bf9STyler Dauwalder 
set_os_classudf_id_suffix1759a043bf9STyler Dauwalder 	void set_os_class(uint8 os_class) { _os_class = os_class; }
set_os_identifierudf_id_suffix1769a043bf9STyler Dauwalder 	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
1779a043bf9STyler Dauwalder private:
1789a043bf9STyler Dauwalder 	uint16 _udf_revision;
1799a043bf9STyler Dauwalder 	uint8 _os_class;
1809a043bf9STyler Dauwalder 	uint8 _os_identifier;
1819a043bf9STyler Dauwalder 	array<uint8, 4> _reserved;
1829a043bf9STyler Dauwalder };
1839a043bf9STyler Dauwalder 
1849b438e89STyler Dauwalder /*! \brief Implementation ID Identify Suffix
1859b438e89STyler Dauwalder 
1869b438e89STyler Dauwalder 	See also: UDF 2.50 2.1.5.3
1879b438e89STyler Dauwalder */
1889b438e89STyler Dauwalder struct implementation_id_suffix {
1899b438e89STyler Dauwalder public:
1909b438e89STyler Dauwalder 	implementation_id_suffix(uint8 os_class, uint8 os_identifier);
1919b438e89STyler Dauwalder 
os_classimplementation_id_suffix1929b438e89STyler Dauwalder 	uint8 os_class() const { return _os_class; }
os_identifierimplementation_id_suffix1939b438e89STyler Dauwalder 	uint8 os_identifier() const { return _os_identifier; }
1949b438e89STyler Dauwalder 
set_os_classimplementation_id_suffix1959b438e89STyler Dauwalder 	void set_os_class(uint8 os_class) { _os_class = os_class; }
set_os_identifierimplementation_id_suffix1969b438e89STyler Dauwalder 	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
1979b438e89STyler Dauwalder private:
1989b438e89STyler Dauwalder 	uint8 _os_class;
1999b438e89STyler Dauwalder 	uint8 _os_identifier;
2009b438e89STyler Dauwalder 	array<uint8, 6> _implementation_use;
2019b438e89STyler Dauwalder };
2029b438e89STyler Dauwalder 
2039b438e89STyler Dauwalder /*! \brief Operating system classes for implementation_id_suffixes
2049b438e89STyler Dauwalder 
2059b438e89STyler Dauwalder 	See also: Udf 2.50 6.3
2069b438e89STyler Dauwalder */
2079b438e89STyler Dauwalder enum {
2089b438e89STyler Dauwalder 	OS_UNDEFINED = 0,
2099b438e89STyler Dauwalder 	OS_DOS,
2109b438e89STyler Dauwalder 	OS_OS2,
2119b438e89STyler Dauwalder 	OS_MACOS,
2129b438e89STyler Dauwalder 	OS_UNIX,
2139b438e89STyler Dauwalder 	OS_WIN9X,
2149b438e89STyler Dauwalder 	OS_WINNT,
2159b438e89STyler Dauwalder 	OS_OS400,
2169b438e89STyler Dauwalder 	OS_BEOS,
2179b438e89STyler Dauwalder 	OS_WINCE
2189b438e89STyler Dauwalder };
2199b438e89STyler Dauwalder 
2209b438e89STyler Dauwalder /*! \brief BeOS operating system classes identifiers for implementation_id_suffixes
2219b438e89STyler Dauwalder 
2229b438e89STyler Dauwalder 	See also: Udf 2.50 6.3
2239b438e89STyler Dauwalder */
2249b438e89STyler Dauwalder enum {
2259b438e89STyler Dauwalder 	BEOS_GENERIC = 0,
2269b438e89STyler Dauwalder 	BEOS_OPENBEOS = 1	// not part of the standard, but perhaps someday. :-)
2279b438e89STyler Dauwalder };
2289b438e89STyler Dauwalder 
229730ba00aSTyler Dauwalder /*! \brief Domain ID Identify Suffix
230730ba00aSTyler Dauwalder 
231730ba00aSTyler Dauwalder 	See also: UDF 2.50 2.1.5.3
232730ba00aSTyler Dauwalder */
233730ba00aSTyler Dauwalder struct domain_id_suffix {
234730ba00aSTyler Dauwalder public:
235730ba00aSTyler Dauwalder 	domain_id_suffix(uint16 udfRevision, uint8 domainFlags);
236730ba00aSTyler Dauwalder 
237730ba00aSTyler Dauwalder 	//! Note that revision 2.50 is denoted by 0x0250.
udf_revisiondomain_id_suffix238730ba00aSTyler Dauwalder 	uint16 udf_revision() const { return _udf_revision; }
domain_flagsdomain_id_suffix239730ba00aSTyler Dauwalder 	uint8 domain_flags() const { return _domain_flags; }
240730ba00aSTyler Dauwalder 
set_udf_revisiondomain_id_suffix241730ba00aSTyler Dauwalder 	void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); }
set_domain_flagsdomain_id_suffix242730ba00aSTyler Dauwalder 	void set_domain_flags(uint8 flags) { _domain_flags = flags; }
243730ba00aSTyler Dauwalder private:
24410186d5dSTyler Dauwalder 	uint16 _udf_revision;
245730ba00aSTyler Dauwalder 	uint8 _domain_flags;
246730ba00aSTyler Dauwalder 	array<uint8, 5> _reserved;
247730ba00aSTyler Dauwalder };
248730ba00aSTyler Dauwalder 
249730ba00aSTyler Dauwalder /*! \brief Domain flags
250730ba00aSTyler Dauwalder 
251730ba00aSTyler Dauwalder 	See also: UDF 2.50 2.1.5.3
252730ba00aSTyler Dauwalder */
253730ba00aSTyler Dauwalder enum {
254730ba00aSTyler Dauwalder 	DF_HARD_WRITE_PROTECT = 0x01,
255730ba00aSTyler Dauwalder 	DF_SOFT_WRITE_PROTECT = 0x02
256730ba00aSTyler Dauwalder };
257730ba00aSTyler Dauwalder 
258ead0c3e2STyler Dauwalder /*! \brief Identifier used to designate the implementation responsible
259ead0c3e2STyler Dauwalder 	for writing associated data structures on the medium.
260ead0c3e2STyler Dauwalder 
261ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.4, UDF 2.01 2.1.5
262ead0c3e2STyler Dauwalder */
263ead0c3e2STyler Dauwalder struct entity_id {
264ead0c3e2STyler Dauwalder public:
2659b438e89STyler Dauwalder 	static const int kIdentifierLength = 23;
2669b438e89STyler Dauwalder 	static const int kIdentifierSuffixLength = 8;
2679b438e89STyler Dauwalder 
26820d84995SRene Gollent 	entity_id(uint8 flags = 0, const char *identifier = NULL,
2699b438e89STyler Dauwalder 	          uint8 *identifier_suffix = NULL);
27020d84995SRene Gollent 	entity_id(uint8 flags, const char *identifier,
2719a043bf9STyler Dauwalder 	          const udf_id_suffix &suffix);
27220d84995SRene Gollent 	entity_id(uint8 flags, const char *identifier,
2739b438e89STyler Dauwalder 	          const implementation_id_suffix &suffix);
27420d84995SRene Gollent 	entity_id(uint8 flags, const char *identifier,
275730ba00aSTyler Dauwalder 	          const domain_id_suffix &suffix);
276ead0c3e2STyler Dauwalder 
277ead0c3e2STyler Dauwalder 	void dump() const;
278ead0c3e2STyler Dauwalder 	bool matches(const entity_id &id) const;
279ead0c3e2STyler Dauwalder 
280ead0c3e2STyler Dauwalder 	// Get functions
flagsentity_id281ead0c3e2STyler Dauwalder 	uint8 flags() const { return _flags; }
identifierentity_id282ead0c3e2STyler Dauwalder 	const char* identifier() const { return _identifier; }
identifierentity_id283ead0c3e2STyler Dauwalder 	char* identifier() { return _identifier; }
identifier_suffixentity_id2849b438e89STyler Dauwalder 	const array<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; }
identifier_suffixentity_id2859b438e89STyler Dauwalder 	array<uint8, kIdentifierSuffixLength>& identifier_suffix() { return _identifier_suffix; }
286ead0c3e2STyler Dauwalder 
287ead0c3e2STyler Dauwalder 	// Set functions
set_flagsentity_id288ead0c3e2STyler Dauwalder 	void set_flags(uint8 flags) { _flags = flags; }
289ead0c3e2STyler Dauwalder private:
290ead0c3e2STyler Dauwalder 	uint8 _flags;
291ead0c3e2STyler Dauwalder 	char _identifier[kIdentifierLength];
2929b438e89STyler Dauwalder 	array<uint8, kIdentifierSuffixLength> _identifier_suffix;
293ead0c3e2STyler Dauwalder } __attribute__((packed));
294ead0c3e2STyler Dauwalder 
295c530d46cSJérôme Duval extern entity_id kMetadataPartitionMapId;
296c530d46cSJérôme Duval extern entity_id kSparablePartitionMapId;
297c530d46cSJérôme Duval extern entity_id kVirtualPartitionMapId;
298c530d46cSJérôme Duval extern entity_id kImplementationId;
299c530d46cSJérôme Duval extern entity_id kPartitionContentsId1xx;
300c530d46cSJérôme Duval extern entity_id kPartitionContentsId2xx;
301c530d46cSJérôme Duval extern entity_id kUdfId;
302c530d46cSJérôme Duval extern entity_id kLogicalVolumeInfoId150;
303c530d46cSJérôme Duval extern entity_id kLogicalVolumeInfoId201;
304c530d46cSJérôme Duval extern entity_id kDomainId150;
305c530d46cSJérôme Duval extern entity_id kDomainId201;
306c530d46cSJérôme Duval extern void init_entities(void);
307ead0c3e2STyler Dauwalder 
308ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
309ead0c3e2STyler Dauwalder // ECMA-167 Part 2
310ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
311ead0c3e2STyler Dauwalder 
312ead0c3e2STyler Dauwalder 
313ead0c3e2STyler Dauwalder /*! \brief Header for volume structure descriptors
314ead0c3e2STyler Dauwalder 
315ead0c3e2STyler Dauwalder 	Each descriptor consumes an entire block. All unused trailing
316ead0c3e2STyler Dauwalder 	bytes in the descriptor should be set to 0.
317ead0c3e2STyler Dauwalder 
318ead0c3e2STyler Dauwalder 	The following descriptors contain no more information than
319ead0c3e2STyler Dauwalder 	that contained in the header:
320ead0c3e2STyler Dauwalder 
321ead0c3e2STyler Dauwalder 	- BEA01:
322ead0c3e2STyler Dauwalder 	  - type: 0
323ead0c3e2STyler Dauwalder 	  - id: "BEA01"
324ead0c3e2STyler Dauwalder 	  - version: 1
325ead0c3e2STyler Dauwalder 
326ead0c3e2STyler Dauwalder 	- TEA01:
327ead0c3e2STyler Dauwalder 	  - type: 0
328ead0c3e2STyler Dauwalder 	  - id: "TEA01"
329ead0c3e2STyler Dauwalder 	  - version: 1
330ead0c3e2STyler Dauwalder 
331ead0c3e2STyler Dauwalder 	- NSR03:
332ead0c3e2STyler Dauwalder 	  - type: 0
333ead0c3e2STyler Dauwalder 	  - id: "NSR03"
334ead0c3e2STyler Dauwalder 	  - version: 1
335ead0c3e2STyler Dauwalder 
336ead0c3e2STyler Dauwalder 	See also: ECMA 167 2/9.1
337ead0c3e2STyler Dauwalder */
338ead0c3e2STyler Dauwalder struct volume_structure_descriptor_header {
3392cc6b97aSTyler Dauwalder public:
3402cc6b97aSTyler Dauwalder 	volume_structure_descriptor_header(uint8 type, const char *id, uint8 version);
3412cc6b97aSTyler Dauwalder 
342ead0c3e2STyler Dauwalder 	uint8 type;
343ead0c3e2STyler Dauwalder 	char id[5];
344ead0c3e2STyler Dauwalder 	uint8 version;
345ead0c3e2STyler Dauwalder 
346ead0c3e2STyler Dauwalder 	bool id_matches(const char *id);
347ead0c3e2STyler Dauwalder } __attribute__((packed));
348ead0c3e2STyler Dauwalder 
349ead0c3e2STyler Dauwalder // Volume structure descriptor ids
350ead0c3e2STyler Dauwalder extern const char* kVSDID_BEA;
351ead0c3e2STyler Dauwalder extern const char* kVSDID_TEA;
352ead0c3e2STyler Dauwalder extern const char* kVSDID_BOOT;
353ead0c3e2STyler Dauwalder extern const char* kVSDID_ISO;
354ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_2;
355ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_3;
356ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA168;
357ead0c3e2STyler Dauwalder 
358ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
359ead0c3e2STyler Dauwalder // ECMA-167 Part 3
360ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
361ead0c3e2STyler Dauwalder 
362ead0c3e2STyler Dauwalder 
363ead0c3e2STyler Dauwalder /*! \brief Location and length of a contiguous chunk of data on the volume.
364ead0c3e2STyler Dauwalder 
365ead0c3e2STyler Dauwalder 	\c _location is an absolute block address.
366ead0c3e2STyler Dauwalder 
367ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/7.1
368ead0c3e2STyler Dauwalder */
369ead0c3e2STyler Dauwalder struct extent_address {
370ead0c3e2STyler Dauwalder public:
371c21aaa8aSTyler Dauwalder 	extent_address(uint32 location = 0, uint32 length = 0);
372c21aaa8aSTyler Dauwalder 
373ead0c3e2STyler Dauwalder 	void dump() const;
374ead0c3e2STyler Dauwalder 
lengthextent_address375ead0c3e2STyler Dauwalder 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
locationextent_address376ead0c3e2STyler Dauwalder 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
377ead0c3e2STyler Dauwalder 
set_lengthextent_address378ead0c3e2STyler Dauwalder 	void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
set_locationextent_address379ead0c3e2STyler Dauwalder 	void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
380ead0c3e2STyler Dauwalder private:
381ead0c3e2STyler Dauwalder 	uint32 _length;
382ead0c3e2STyler Dauwalder 	uint32 _location;
383ead0c3e2STyler Dauwalder } __attribute__((packed));
384ead0c3e2STyler Dauwalder 
385ead0c3e2STyler Dauwalder 
386ead0c3e2STyler Dauwalder /*! \brief Location of a logical block within a logical volume.
387ead0c3e2STyler Dauwalder 
388ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/7.1
389ead0c3e2STyler Dauwalder */
390ead0c3e2STyler Dauwalder struct logical_block_address {
391ead0c3e2STyler Dauwalder public:
392ead0c3e2STyler Dauwalder 	void dump() const;
393e631ed51STyler Dauwalder 	logical_block_address(uint16 partition = 0, uint32 block = 0);
394ead0c3e2STyler Dauwalder 
blocklogical_block_address395ead0c3e2STyler Dauwalder 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
partitionlogical_block_address396ead0c3e2STyler Dauwalder 	uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); }
397ead0c3e2STyler Dauwalder 
set_blocklogical_block_address398ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
set_partitionlogical_block_address399ead0c3e2STyler Dauwalder 	void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); }
400ead0c3e2STyler Dauwalder 
401ead0c3e2STyler Dauwalder private:
402ead0c3e2STyler Dauwalder 	uint32 _block;	//!< Block location relative to start of corresponding partition
403ead0c3e2STyler Dauwalder 	uint16 _partition;	//!< Numeric partition id within logical volume
404ead0c3e2STyler Dauwalder } __attribute__((packed));
405ead0c3e2STyler Dauwalder 
406ead0c3e2STyler Dauwalder /*! \brief Extent types used in short_address, long_address,
407ead0c3e2STyler Dauwalder 	and extended_address.
408ead0c3e2STyler Dauwalder 
409ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.14.1.1
410ead0c3e2STyler Dauwalder */
411ead0c3e2STyler Dauwalder enum extent_type {
412ead0c3e2STyler Dauwalder 	EXTENT_TYPE_RECORDED = 0,	//!< Allocated and recorded
413ead0c3e2STyler Dauwalder 	EXTENT_TYPE_ALLOCATED,		//!< Allocated but unrecorded
414ead0c3e2STyler Dauwalder 	EXTENT_TYPE_UNALLOCATED,	//!< Unallocated and unrecorded
415ead0c3e2STyler Dauwalder 	EXTENT_TYPE_CONTINUATION,	//!< Specifies next extent of descriptors
416ead0c3e2STyler Dauwalder };
417ead0c3e2STyler Dauwalder 
418ead0c3e2STyler Dauwalder 
419ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor.
420ead0c3e2STyler Dauwalder 
421ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/14.14.1
422ead0c3e2STyler Dauwalder */
423ead0c3e2STyler Dauwalder struct short_address {
424ead0c3e2STyler Dauwalder private:
425ead0c3e2STyler Dauwalder 	union type_and_length_accessor {
426ead0c3e2STyler Dauwalder 		uint32 type_and_length;
427ead0c3e2STyler Dauwalder 		struct {
428ead0c3e2STyler Dauwalder 			uint32 length:30,
429ead0c3e2STyler Dauwalder 			       type:2;
430ead0c3e2STyler Dauwalder //			uint32 type:2,
431ead0c3e2STyler Dauwalder //			       length:30;
432ead0c3e2STyler Dauwalder 		} bits;
433ead0c3e2STyler Dauwalder 	};
434ead0c3e2STyler Dauwalder 
435ead0c3e2STyler Dauwalder public:
436ead0c3e2STyler Dauwalder 	void dump() const;
437ead0c3e2STyler Dauwalder 
typeshort_address438ead0c3e2STyler Dauwalder 	uint8 type() const {
439ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
440ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
441ead0c3e2STyler Dauwalder 		return t.bits.type;
442ead0c3e2STyler Dauwalder 	}
lengthshort_address443ead0c3e2STyler Dauwalder 	uint32 length() const {
444ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
445ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
446ead0c3e2STyler Dauwalder 		return t.bits.length;
447ead0c3e2STyler Dauwalder 	}
blockshort_address448ead0c3e2STyler Dauwalder 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
449ead0c3e2STyler Dauwalder 
set_typeshort_address450ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
451ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
452ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
453ead0c3e2STyler Dauwalder 		t.bits.type = type;
454ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
455ead0c3e2STyler Dauwalder 	}
set_lengthshort_address456ead0c3e2STyler Dauwalder 	void set_length(uint32 length) {
457ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
458ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
459ead0c3e2STyler Dauwalder 		t.bits.length = length;
460ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
461ead0c3e2STyler Dauwalder 	}
set_blockshort_address462ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
463ead0c3e2STyler Dauwalder private:
type_and_lengthshort_address464ead0c3e2STyler Dauwalder 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
set_type_and_lengthshort_address465ead0c3e2STyler Dauwalder 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
466ead0c3e2STyler Dauwalder 
467ead0c3e2STyler Dauwalder 	uint32 _type_and_length;
468ead0c3e2STyler Dauwalder 	uint32 _block;
469ead0c3e2STyler Dauwalder } __attribute__((packed));
470ead0c3e2STyler Dauwalder 
471ead0c3e2STyler Dauwalder 
472ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor w/ 6 byte implementation use field.
473ead0c3e2STyler Dauwalder 
474ead0c3e2STyler Dauwalder 	See also: ECMA 167 4/14.14.2
475ead0c3e2STyler Dauwalder */
476ead0c3e2STyler Dauwalder struct long_address {
477ead0c3e2STyler Dauwalder private:
478ead0c3e2STyler Dauwalder 	union type_and_length_accessor {
479ead0c3e2STyler Dauwalder 		uint32 type_and_length;
480ead0c3e2STyler Dauwalder 		struct {
481ead0c3e2STyler Dauwalder 			uint32 length:30,
482ead0c3e2STyler Dauwalder 			       type:2;
483ead0c3e2STyler Dauwalder 		} bits;
484ead0c3e2STyler Dauwalder 	};
485ead0c3e2STyler Dauwalder 
486ead0c3e2STyler Dauwalder public:
487d1a0387eSTyler Dauwalder 	long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0,
488d1a0387eSTyler Dauwalder 	             uint8 type = 0);
489d1a0387eSTyler Dauwalder 
490ead0c3e2STyler Dauwalder 	void dump() const;
491ead0c3e2STyler Dauwalder 
typelong_address492ead0c3e2STyler Dauwalder 	uint8 type() const {
493ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
494ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
495ead0c3e2STyler Dauwalder 		return t.bits.type;
496ead0c3e2STyler Dauwalder 	}
lengthlong_address497ead0c3e2STyler Dauwalder 	uint32 length() const {
498ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
499ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
500ead0c3e2STyler Dauwalder 		return t.bits.length;
501ead0c3e2STyler Dauwalder 	}
502ead0c3e2STyler Dauwalder 
blocklong_address503ead0c3e2STyler Dauwalder 	uint32 block() const { return _location.block(); }
partitionlong_address504ead0c3e2STyler Dauwalder 	uint16 partition() const { return _location.partition(); }
505ead0c3e2STyler Dauwalder 
implementation_uselong_address506ead0c3e2STyler Dauwalder 	const array<uint8, 6>& implementation_use() const { return _implementation_use; }
implementation_uselong_address507ead0c3e2STyler Dauwalder 	array<uint8, 6>& implementation_use() { return _implementation_use; }
508ead0c3e2STyler Dauwalder 
flagslong_address50980b849abSTyler Dauwalder 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_accessor().flags); }
unique_idlong_address51080b849abSTyler Dauwalder 	uint32 unique_id() const { return B_LENDIAN_TO_HOST_INT32(_accessor().unique_id); }
51180b849abSTyler Dauwalder 
set_typelong_address512ead0c3e2STyler Dauwalder 	void set_type(uint8 type) {
513ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
514ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
515ead0c3e2STyler Dauwalder 		t.bits.type = type;
516ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
517ead0c3e2STyler Dauwalder 	}
set_lengthlong_address518ead0c3e2STyler Dauwalder 	void set_length(uint32 length) {
519ead0c3e2STyler Dauwalder 		type_and_length_accessor t;
520ead0c3e2STyler Dauwalder 		t.type_and_length = type_and_length();
521ead0c3e2STyler Dauwalder 		t.bits.length = length;
522ead0c3e2STyler Dauwalder 		set_type_and_length(t.type_and_length);
523ead0c3e2STyler Dauwalder 	}
set_blocklong_address524ead0c3e2STyler Dauwalder 	void set_block(uint32 block) { _location.set_block(block); }
set_partitionlong_address525ead0c3e2STyler Dauwalder 	void set_partition(uint16 partition) { _location.set_partition(partition); }
526ead0c3e2STyler Dauwalder 
set_flagslong_address52780b849abSTyler Dauwalder 	void set_flags(uint16 flags) { _accessor().flags = B_HOST_TO_LENDIAN_INT16(flags); }
set_unique_idlong_address52880b849abSTyler Dauwalder 	void set_unique_id(uint32 id) { _accessor().unique_id = B_HOST_TO_LENDIAN_INT32(id); }
52980b849abSTyler Dauwalder 
530ead0c3e2STyler Dauwalder 	void set_to(uint32 block, uint16 partition, uint32 length = 1,
53180b849abSTyler Dauwalder 	       uint8 type = EXTENT_TYPE_RECORDED, uint16 flags = 0, uint32 unique_id = 0)
532ead0c3e2STyler Dauwalder 	{
533ead0c3e2STyler Dauwalder 		set_block(block);
534ead0c3e2STyler Dauwalder 		set_partition(partition);
535ead0c3e2STyler Dauwalder 		set_length(length);
536ead0c3e2STyler Dauwalder 		set_type(type);
53780b849abSTyler Dauwalder 		set_flags(flags);
53880b849abSTyler Dauwalder 		set_unique_id(unique_id);
539ead0c3e2STyler Dauwalder 	}
540ead0c3e2STyler Dauwalder 
541ead0c3e2STyler Dauwalder private:
54280b849abSTyler Dauwalder 	//! See UDF-2.50 2.3.4.3
54380b849abSTyler Dauwalder 	struct _implementation_use_accessor {
54480b849abSTyler Dauwalder 		uint16 flags;
54580b849abSTyler Dauwalder 		uint32 unique_id;
54680b849abSTyler Dauwalder 	} __attribute__((packed));
54780b849abSTyler Dauwalder 
_accessorlong_address54880b849abSTyler Dauwalder 	_implementation_use_accessor& _accessor() { return
54980b849abSTyler Dauwalder 		*reinterpret_cast<_implementation_use_accessor*>(implementation_use().data); }
_accessorlong_address55080b849abSTyler Dauwalder 	const _implementation_use_accessor& _accessor() const { return
55180b849abSTyler Dauwalder 		*reinterpret_cast<const _implementation_use_accessor*>(implementation_use().data); }
55280b849abSTyler Dauwalder 
type_and_lengthlong_address553ead0c3e2STyler Dauwalder 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
set_type_and_lengthlong_address554ead0c3e2STyler Dauwalder 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
555ead0c3e2STyler Dauwalder 
556ead0c3e2STyler Dauwalder 	uint32 _type_and_length;
557ead0c3e2STyler Dauwalder 	logical_block_address _location;
558ead0c3e2STyler Dauwalder 	array<uint8, 6> _implementation_use;
559ead0c3e2STyler Dauwalder } __attribute__((packed));
560ead0c3e2STyler Dauwalder 
561ead0c3e2STyler Dauwalder /*! \brief Common tag found at the beginning of most udf descriptor structures.
562ead0c3e2STyler Dauwalder 
563ead0c3e2STyler Dauwalder 	For error checking, \c descriptor_tag  structures have:
564ead0c3e2STyler Dauwalder 	- The disk location of the tag redundantly stored in the tag itself
565ead0c3e2STyler Dauwalder 	- A checksum value for the tag
566ead0c3e2STyler Dauwalder 	- A CRC value and length
567ead0c3e2STyler Dauwalder 
568ead0c3e2STyler Dauwalder 	See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
569ead0c3e2STyler Dauwalder */
570ead0c3e2STyler Dauwalder struct descriptor_tag {
571ead0c3e2STyler Dauwalder public:
572ead0c3e2STyler Dauwalder 	void dump() const;
573ead0c3e2STyler Dauwalder 
57404d90c2aSTyler Dauwalder 	status_t init_check(uint32 block, bool calculateCrc = true);
575ead0c3e2STyler Dauwalder 
iddescriptor_tag576ead0c3e2STyler Dauwalder 	uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); }
versiondescriptor_tag577ead0c3e2STyler Dauwalder 	uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); }
checksumdescriptor_tag578ead0c3e2STyler Dauwalder 	uint8 checksum() const { return _checksum; }
serial_numberdescriptor_tag579ead0c3e2STyler Dauwalder 	uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); }
crcdescriptor_tag580ead0c3e2STyler Dauwalder 	uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); }
crc_lengthdescriptor_tag581ead0c3e2STyler Dauwalder 	uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); }
locationdescriptor_tag582ead0c3e2STyler Dauwalder 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
583ead0c3e2STyler Dauwalder 
set_iddescriptor_tag584ead0c3e2STyler Dauwalder 	void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); }
set_versiondescriptor_tag585ead0c3e2STyler Dauwalder 	void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); }
set_checksumdescriptor_tag586ead0c3e2STyler Dauwalder 	void set_checksum(uint8 checksum) { _checksum = checksum; }
set_serial_numberdescriptor_tag587ead0c3e2STyler Dauwalder 	void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); }
set_crcdescriptor_tag588ead0c3e2STyler Dauwalder 	void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); }
set_crc_lengthdescriptor_tag589ead0c3e2STyler Dauwalder 	void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); }
set_locationdescriptor_tag590ead0c3e2STyler Dauwalder 	void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
591ead0c3e2STyler Dauwalder 
5925a97c04eSTyler Dauwalder 	/*! \brief Calculates and sets the crc length, crc checksumm, and
5935a97c04eSTyler Dauwalder 		checksum for the tag.
5945a97c04eSTyler Dauwalder 
5955a97c04eSTyler Dauwalder 		This function should not be called until all member variables in
5965a97c04eSTyler Dauwalder 		the descriptor_tag's enclosing descriptor and all member variables
5975a97c04eSTyler Dauwalder 		in the descriptor_tag itself other than crc_length, crc, and checksum
5985a97c04eSTyler Dauwalder 		have been set (since the checksum is based off of values in the
5995a97c04eSTyler Dauwalder 		descriptor_tag, and the crc is based off the values in and the
6005a97c04eSTyler Dauwalder 		size of the	enclosing descriptor).
6015a97c04eSTyler Dauwalder 
6025a97c04eSTyler Dauwalder 		\param The tag's enclosing descriptor.
6035a97c04eSTyler Dauwalder 		\param The size of the tag's enclosing descriptor (including the
6045a97c04eSTyler Dauwalder 		       tag); only necessary if different from sizeof(Descriptor).
6055a97c04eSTyler Dauwalder 	*/
6065a97c04eSTyler Dauwalder 	template <class Descriptor>
6075a97c04eSTyler Dauwalder 	void
6085a97c04eSTyler Dauwalder 	set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
6095a97c04eSTyler Dauwalder 	{
6105a97c04eSTyler Dauwalder 
6115a97c04eSTyler Dauwalder 		// check that this tag is actually owned by
6125a97c04eSTyler Dauwalder 		// the given descriptor
6135a97c04eSTyler Dauwalder 		if (this == &descriptor.tag())
6145a97c04eSTyler Dauwalder 		{
6155a97c04eSTyler Dauwalder 			// crc_length, based off provided descriptor
6165a97c04eSTyler Dauwalder 			set_crc_length(size - sizeof(descriptor_tag));
6175a97c04eSTyler Dauwalder 			// crc
618c49d6efcSSalvatore Benedetto 			uint16 crc = calculate_crc(reinterpret_cast<uint8*>(this)
6195a97c04eSTyler Dauwalder 			               + sizeof(descriptor_tag), crc_length());
6205a97c04eSTyler Dauwalder 			set_crc(crc);
6215a97c04eSTyler Dauwalder 			// checksum (which depends on the other two values)
6225a97c04eSTyler Dauwalder 			uint32 sum = 0;
6235a97c04eSTyler Dauwalder 			for (int i = 0; i <= 3; i++)
6245a97c04eSTyler Dauwalder 				sum += reinterpret_cast<uint8*>(this)[i];
6255a97c04eSTyler Dauwalder 			for (int i = 5; i <= 15; i++)
6265a97c04eSTyler Dauwalder 				sum += reinterpret_cast<uint8*>(this)[i];
6275a97c04eSTyler Dauwalder 			set_checksum(sum % 256);
6285a97c04eSTyler Dauwalder 		}
6295a97c04eSTyler Dauwalder 	}
630ead0c3e2STyler Dauwalder private:
631ead0c3e2STyler Dauwalder 	uint16 _id;
632ead0c3e2STyler Dauwalder 	uint16 _version;
633ead0c3e2STyler Dauwalder 	uint8 _checksum;			//!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
634ead0c3e2STyler Dauwalder 	uint8 _reserved;			//!< Set to #00.
635ead0c3e2STyler Dauwalder 	uint16 _serial_number;
636ead0c3e2STyler Dauwalder 	uint16 _crc;				//!< May be 0 if \c crc_length field is 0.
637ead0c3e2STyler Dauwalder 	/*! \brief Length of the data chunk used to calculate CRC.
638ead0c3e2STyler Dauwalder 
639ead0c3e2STyler Dauwalder 		If 0, no CRC was calculated, and the \c crc field must be 0.
640ead0c3e2STyler Dauwalder 
641ead0c3e2STyler Dauwalder 		According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors
642ead0c3e2STyler Dauwalder 		unless otherwise noted, and this field shall be set to:
643ead0c3e2STyler Dauwalder 
644ead0c3e2STyler Dauwalder 		<code>(descriptor length) - (descriptor tag length)</code>
645ead0c3e2STyler Dauwalder 	*/
646ead0c3e2STyler Dauwalder 	uint16 _crc_length;
647ead0c3e2STyler Dauwalder 	/*! \brief Address of this tag within its partition (for error checking).
648ead0c3e2STyler Dauwalder 
649ead0c3e2STyler Dauwalder 		For virtually addressed structures (i.e. those accessed thru a VAT), this
650ead0c3e2STyler Dauwalder 		shall be the virtual address, not the physical or logical address.
651ead0c3e2STyler Dauwalder 	*/
652ead0c3e2STyler Dauwalder 	uint32 _location;
653ead0c3e2STyler Dauwalder 
654ead0c3e2STyler Dauwalder } __attribute__((packed));
655ead0c3e2STyler Dauwalder 
656ead0c3e2STyler Dauwalder 
657ead0c3e2STyler Dauwalder /*! \c descriptor_tag ::id values
658ead0c3e2STyler Dauwalder */
659ead0c3e2STyler Dauwalder enum tag_id {
660ead0c3e2STyler Dauwalder 	TAGID_UNDEFINED	= 0,
661ead0c3e2STyler Dauwalder 
662ead0c3e2STyler Dauwalder 	// ECMA 167, PART 3
663ead0c3e2STyler Dauwalder 	TAGID_PRIMARY_VOLUME_DESCRIPTOR,
664ead0c3e2STyler Dauwalder 	TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER,
665ead0c3e2STyler Dauwalder 	TAGID_VOLUME_DESCRIPTOR_POINTER,
666ead0c3e2STyler Dauwalder 	TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR,
667ead0c3e2STyler Dauwalder 	TAGID_PARTITION_DESCRIPTOR,
668ead0c3e2STyler Dauwalder 	TAGID_LOGICAL_VOLUME_DESCRIPTOR,
669ead0c3e2STyler Dauwalder 	TAGID_UNALLOCATED_SPACE_DESCRIPTOR,
670ead0c3e2STyler Dauwalder 	TAGID_TERMINATING_DESCRIPTOR,
671ead0c3e2STyler Dauwalder 	TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR,
672ead0c3e2STyler Dauwalder 
673ead0c3e2STyler Dauwalder 	TAGID_CUSTOM_START = 65280,
674ead0c3e2STyler Dauwalder 	TAGID_CUSTOM_END = 65535,
675ead0c3e2STyler Dauwalder 
676ead0c3e2STyler Dauwalder 	// ECMA 167, PART 4
677ead0c3e2STyler Dauwalder 	TAGID_FILE_SET_DESCRIPTOR = 256,
6784f0e6a75STyler Dauwalder 	TAGID_FILE_ID_DESCRIPTOR,
679ead0c3e2STyler Dauwalder 	TAGID_ALLOCATION_EXTENT_DESCRIPTOR,
680ead0c3e2STyler Dauwalder 	TAGID_INDIRECT_ENTRY,
681ead0c3e2STyler Dauwalder 	TAGID_TERMINAL_ENTRY,
682ead0c3e2STyler Dauwalder 	TAGID_FILE_ENTRY,
683ead0c3e2STyler Dauwalder 	TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR,
684ead0c3e2STyler Dauwalder 	TAGID_UNALLOCATED_SPACE_ENTRY,
685ead0c3e2STyler Dauwalder 	TAGID_SPACE_BITMAP_DESCRIPTOR,
686ead0c3e2STyler Dauwalder 	TAGID_PARTITION_INTEGRITY_ENTRY,
687ead0c3e2STyler Dauwalder 	TAGID_EXTENDED_FILE_ENTRY,
688ead0c3e2STyler Dauwalder };
689ead0c3e2STyler Dauwalder 
690ead0c3e2STyler Dauwalder const char *tag_id_to_string(tag_id id);
691ead0c3e2STyler Dauwalder 
692e05a3e1eSTyler Dauwalder extern const uint16 kCrcTable[256];
693e05a3e1eSTyler Dauwalder 
694ead0c3e2STyler Dauwalder /*! \brief Primary volume descriptor
695ead0c3e2STyler Dauwalder */
696ead0c3e2STyler Dauwalder struct primary_volume_descriptor {
697ead0c3e2STyler Dauwalder public:
698ead0c3e2STyler Dauwalder 	void dump() const;
699ead0c3e2STyler Dauwalder 
700ead0c3e2STyler Dauwalder 	// Get functions
tagprimary_volume_descriptor701ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagprimary_volume_descriptor702ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
703ead0c3e2STyler Dauwalder 
vds_numberprimary_volume_descriptor704ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
primary_volume_descriptor_numberprimary_volume_descriptor705ead0c3e2STyler Dauwalder 	uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); }
706ead0c3e2STyler Dauwalder 
volume_identifierprimary_volume_descriptor707ead0c3e2STyler Dauwalder 	const array<char, 32>& volume_identifier() const { return _volume_identifier; }
volume_identifierprimary_volume_descriptor708ead0c3e2STyler Dauwalder 	array<char, 32>& volume_identifier() { return _volume_identifier; }
709ead0c3e2STyler Dauwalder 
volume_sequence_numberprimary_volume_descriptor710ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
max_volume_sequence_numberprimary_volume_descriptor711ead0c3e2STyler Dauwalder 	uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); }
interchange_levelprimary_volume_descriptor712ead0c3e2STyler Dauwalder 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
max_interchange_levelprimary_volume_descriptor713ead0c3e2STyler Dauwalder 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
character_set_listprimary_volume_descriptor714ead0c3e2STyler Dauwalder 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
max_character_set_listprimary_volume_descriptor715ead0c3e2STyler Dauwalder 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
716ead0c3e2STyler Dauwalder 
volume_set_identifierprimary_volume_descriptor717ead0c3e2STyler Dauwalder 	const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
volume_set_identifierprimary_volume_descriptor718ead0c3e2STyler Dauwalder 	array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
719ead0c3e2STyler Dauwalder 
descriptor_character_setprimary_volume_descriptor720ead0c3e2STyler Dauwalder 	const charspec& descriptor_character_set() const { return _descriptor_character_set; }
descriptor_character_setprimary_volume_descriptor721ead0c3e2STyler Dauwalder 	charspec& descriptor_character_set() { return _descriptor_character_set; }
722ead0c3e2STyler Dauwalder 
explanatory_character_setprimary_volume_descriptor723ead0c3e2STyler Dauwalder 	const charspec& explanatory_character_set() const { return _explanatory_character_set; }
explanatory_character_setprimary_volume_descriptor724ead0c3e2STyler Dauwalder 	charspec& explanatory_character_set() { return _explanatory_character_set; }
725ead0c3e2STyler Dauwalder 
volume_abstractprimary_volume_descriptor726ead0c3e2STyler Dauwalder 	const extent_address& volume_abstract() const { return _volume_abstract; }
volume_abstractprimary_volume_descriptor727ead0c3e2STyler Dauwalder 	extent_address& volume_abstract() { return _volume_abstract; }
volume_copyright_noticeprimary_volume_descriptor728ead0c3e2STyler Dauwalder 	const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; }
volume_copyright_noticeprimary_volume_descriptor729ead0c3e2STyler Dauwalder 	extent_address& volume_copyright_notice() { return _volume_copyright_notice; }
730ead0c3e2STyler Dauwalder 
application_idprimary_volume_descriptor731ead0c3e2STyler Dauwalder 	const entity_id& application_id() const { return _application_id; }
application_idprimary_volume_descriptor732ead0c3e2STyler Dauwalder 	entity_id& application_id() { return _application_id; }
733ead0c3e2STyler Dauwalder 
recording_date_and_timeprimary_volume_descriptor734ead0c3e2STyler Dauwalder 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
recording_date_and_timeprimary_volume_descriptor735ead0c3e2STyler Dauwalder 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
736ead0c3e2STyler Dauwalder 
implementation_idprimary_volume_descriptor737ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
implementation_idprimary_volume_descriptor738ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
739ead0c3e2STyler Dauwalder 
implementation_useprimary_volume_descriptor740ead0c3e2STyler Dauwalder 	const array<uint8, 64>& implementation_use() const { return _implementation_use; }
implementation_useprimary_volume_descriptor741ead0c3e2STyler Dauwalder 	array<uint8, 64>& implementation_use() { return _implementation_use; }
742ead0c3e2STyler Dauwalder 
predecessor_volume_descriptor_sequence_locationprimary_volume_descriptor743ead0c3e2STyler Dauwalder 	uint32 predecessor_volume_descriptor_sequence_location() const
744ead0c3e2STyler Dauwalder 	  { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); }
flagsprimary_volume_descriptor745ead0c3e2STyler Dauwalder 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
746ead0c3e2STyler Dauwalder 
reservedprimary_volume_descriptor7479b438e89STyler Dauwalder 	const array<uint8, 22>& reserved() const { return _reserved; }
reservedprimary_volume_descriptor7489b438e89STyler Dauwalder 	array<uint8, 22>& reserved() { return _reserved; }
7499b438e89STyler Dauwalder 
750ead0c3e2STyler Dauwalder 	// Set functions
set_vds_numberprimary_volume_descriptor751ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number)
752ead0c3e2STyler Dauwalder 	  { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
set_primary_volume_descriptor_numberprimary_volume_descriptor753ead0c3e2STyler Dauwalder 	void set_primary_volume_descriptor_number(uint32 number)
754ead0c3e2STyler Dauwalder 	  { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
set_volume_sequence_numberprimary_volume_descriptor755ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number)
756ead0c3e2STyler Dauwalder 	  { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
set_max_volume_sequence_numberprimary_volume_descriptor757ead0c3e2STyler Dauwalder 	void set_max_volume_sequence_number(uint16 number)
758ead0c3e2STyler Dauwalder 	  { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
set_interchange_levelprimary_volume_descriptor759ead0c3e2STyler Dauwalder 	void set_interchange_level(uint16 level)
760ead0c3e2STyler Dauwalder 	  { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
set_max_interchange_levelprimary_volume_descriptor761ead0c3e2STyler Dauwalder 	void set_max_interchange_level(uint16 level)
762ead0c3e2STyler Dauwalder 	  { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
set_character_set_listprimary_volume_descriptor763ead0c3e2STyler Dauwalder 	void set_character_set_list(uint32 list)
764ead0c3e2STyler Dauwalder 	  { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
set_max_character_set_listprimary_volume_descriptor765ead0c3e2STyler Dauwalder 	void set_max_character_set_list(uint32 list)
766ead0c3e2STyler Dauwalder 	  { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
set_predecessor_volume_descriptor_sequence_locationprimary_volume_descriptor767ead0c3e2STyler Dauwalder 	void set_predecessor_volume_descriptor_sequence_location(uint32 location)
768ead0c3e2STyler Dauwalder 	  { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); }
set_flagsprimary_volume_descriptor769ead0c3e2STyler Dauwalder 	void set_flags(uint16 flags)
770ead0c3e2STyler Dauwalder 	  { _flags = B_HOST_TO_LENDIAN_INT16(flags); }
771ead0c3e2STyler Dauwalder 
772ead0c3e2STyler Dauwalder private:
773ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
774ead0c3e2STyler Dauwalder 	uint32 _vds_number;
775ead0c3e2STyler Dauwalder 	uint32 _primary_volume_descriptor_number;
776ead0c3e2STyler Dauwalder 	array<char, 32> _volume_identifier;
777ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
778ead0c3e2STyler Dauwalder 	uint16 _max_volume_sequence_number;
779ead0c3e2STyler Dauwalder 	uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
780ead0c3e2STyler Dauwalder 	uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
781ead0c3e2STyler Dauwalder 	uint32 _character_set_list;
782ead0c3e2STyler Dauwalder 	uint32 _max_character_set_list;
783ead0c3e2STyler Dauwalder 	array<char, 128> _volume_set_identifier;
784ead0c3e2STyler Dauwalder 
785ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set for the \c volume_identifier
786ead0c3e2STyler Dauwalder 		and \c volume_set_identifier fields.
787ead0c3e2STyler Dauwalder 
788ead0c3e2STyler Dauwalder 		To be set to CS0.
789ead0c3e2STyler Dauwalder 	*/
790ead0c3e2STyler Dauwalder 	charspec _descriptor_character_set;
791ead0c3e2STyler Dauwalder 
792ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set used in the \c volume_abstract
793ead0c3e2STyler Dauwalder 		and \c volume_copyright_notice extents.
794ead0c3e2STyler Dauwalder 
795ead0c3e2STyler Dauwalder 		To be set to CS0.
796ead0c3e2STyler Dauwalder 	*/
797ead0c3e2STyler Dauwalder 	charspec _explanatory_character_set;
798ead0c3e2STyler Dauwalder 
799ead0c3e2STyler Dauwalder 	extent_address _volume_abstract;
800ead0c3e2STyler Dauwalder 	extent_address _volume_copyright_notice;
801ead0c3e2STyler Dauwalder 
802ead0c3e2STyler Dauwalder 	entity_id _application_id;
803ead0c3e2STyler Dauwalder 	timestamp _recording_date_and_time;
804ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
805ead0c3e2STyler Dauwalder 	array<uint8, 64> _implementation_use;
806ead0c3e2STyler Dauwalder 	uint32 _predecessor_volume_descriptor_sequence_location;
807ead0c3e2STyler Dauwalder 	uint16 _flags;
8089b438e89STyler Dauwalder 	array<uint8, 22> _reserved;
809ead0c3e2STyler Dauwalder 
810ead0c3e2STyler Dauwalder } __attribute__((packed));
811ead0c3e2STyler Dauwalder 
812ead0c3e2STyler Dauwalder 
813ead0c3e2STyler Dauwalder /*! \brief Anchor Volume Descriptor Pointer
814ead0c3e2STyler Dauwalder 
815ead0c3e2STyler Dauwalder 	vd recorded at preset locations in the partition, used as a reference
816ead0c3e2STyler Dauwalder 	point to the main vd sequences
817ead0c3e2STyler Dauwalder 
818ead0c3e2STyler Dauwalder 	According to UDF 2.01, an avdp shall be recorded in at least 2 of
819ead0c3e2STyler Dauwalder 	the 3 following locations, where N is the last recordable sector
820ead0c3e2STyler Dauwalder 	of the partition:
821ead0c3e2STyler Dauwalder 	- 256
822ead0c3e2STyler Dauwalder 	- (N - 256)
823ead0c3e2STyler Dauwalder 	- N
824ead0c3e2STyler Dauwalder 
825ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
826ead0c3e2STyler Dauwalder */
827ead0c3e2STyler Dauwalder struct anchor_volume_descriptor {
828ead0c3e2STyler Dauwalder public:
anchor_volume_descriptoranchor_volume_descriptor82910186d5dSTyler Dauwalder 	anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
830ead0c3e2STyler Dauwalder 	void dump() const;
831ead0c3e2STyler Dauwalder 
taganchor_volume_descriptor832ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
taganchor_volume_descriptor833ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
834ead0c3e2STyler Dauwalder 
main_vdsanchor_volume_descriptor835ead0c3e2STyler Dauwalder 	extent_address& main_vds() { return _main_vds; }
main_vdsanchor_volume_descriptor836ead0c3e2STyler Dauwalder 	const extent_address& main_vds() const { return _main_vds; }
837ead0c3e2STyler Dauwalder 
reserve_vdsanchor_volume_descriptor838ead0c3e2STyler Dauwalder 	extent_address& reserve_vds() { return _reserve_vds; }
reserve_vdsanchor_volume_descriptor839ead0c3e2STyler Dauwalder 	const extent_address& reserve_vds() const { return _reserve_vds; }
840ead0c3e2STyler Dauwalder private:
841ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
842ead0c3e2STyler Dauwalder 	extent_address _main_vds;	//!< min length of 16 sectors
843ead0c3e2STyler Dauwalder 	extent_address _reserve_vds;	//!< min length of 16 sectors
84410186d5dSTyler Dauwalder 	array<uint8, 480> _reserved;
845ead0c3e2STyler Dauwalder } __attribute__((packed));
846ead0c3e2STyler Dauwalder 
847ead0c3e2STyler Dauwalder 
848ead0c3e2STyler Dauwalder /*! \brief Volume Descriptor Pointer
849ead0c3e2STyler Dauwalder 
850ead0c3e2STyler Dauwalder 	Used to chain extents of volume descriptor sequences together.
851ead0c3e2STyler Dauwalder 
852ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.3
853ead0c3e2STyler Dauwalder */
854ead0c3e2STyler Dauwalder struct descriptor_pointer {
855ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
856ead0c3e2STyler Dauwalder 	uint32 vds_number;
857ead0c3e2STyler Dauwalder 	extent_address next;
858ead0c3e2STyler Dauwalder } __attribute__((packed));
859ead0c3e2STyler Dauwalder 
860ead0c3e2STyler Dauwalder 
8619a043bf9STyler Dauwalder /*! \brief UDF Implementation Use Volume Descriptor struct found in
8629a043bf9STyler Dauwalder 	implementation_use() field of implementation_use_descriptor when
8639a043bf9STyler Dauwalder 	said descriptor's implementation_id() field specifies "*UDF LV Info"
8649a043bf9STyler Dauwalder 
8659a043bf9STyler Dauwalder 	See also: UDF 2.50 2.2.7
8669a043bf9STyler Dauwalder */
8679a043bf9STyler Dauwalder struct logical_volume_info {
8689a043bf9STyler Dauwalder public:
8699a043bf9STyler Dauwalder 	void dump() const;
8709a043bf9STyler Dauwalder 
character_setlogical_volume_info8719a043bf9STyler Dauwalder 	charspec& character_set() { return _character_set; }
character_setlogical_volume_info8729a043bf9STyler Dauwalder 	const charspec& character_set() const { return _character_set; }
8739a043bf9STyler Dauwalder 
logical_volume_idlogical_volume_info8749a043bf9STyler Dauwalder 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
logical_volume_idlogical_volume_info8759a043bf9STyler Dauwalder 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
8769a043bf9STyler Dauwalder 
logical_volume_info_1logical_volume_info8779a043bf9STyler Dauwalder 	array<char, 36>& logical_volume_info_1() { return _logical_volume_info.data[0]; }
logical_volume_info_1logical_volume_info8789a043bf9STyler Dauwalder 	const array<char, 36>& logical_volume_info_1() const { return _logical_volume_info.data[0]; }
8799a043bf9STyler Dauwalder 
logical_volume_info_2logical_volume_info8809a043bf9STyler Dauwalder 	array<char, 36>& logical_volume_info_2() { return _logical_volume_info.data[1]; }
logical_volume_info_2logical_volume_info8819a043bf9STyler Dauwalder 	const array<char, 36>& logical_volume_info_2() const { return _logical_volume_info.data[1]; }
8829a043bf9STyler Dauwalder 
logical_volume_info_3logical_volume_info8839a043bf9STyler Dauwalder 	array<char, 36>& logical_volume_info_3() { return _logical_volume_info.data[2]; }
logical_volume_info_3logical_volume_info8849a043bf9STyler Dauwalder 	const array<char, 36>& logical_volume_info_3() const { return _logical_volume_info.data[2]; }
8859a043bf9STyler Dauwalder 
implementation_idlogical_volume_info8869a043bf9STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
implementation_idlogical_volume_info8879a043bf9STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
8889a043bf9STyler Dauwalder 
implementation_uselogical_volume_info8899a043bf9STyler Dauwalder 	array<uint8, 128>& implementation_use() { return _implementation_use; }
implementation_uselogical_volume_info8909a043bf9STyler Dauwalder 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
8919a043bf9STyler Dauwalder private:
8929a043bf9STyler Dauwalder 	charspec _character_set;
8939a043bf9STyler Dauwalder 	array<char, 128> _logical_volume_id;				// d-string
8949a043bf9STyler Dauwalder 	array<array<char, 36>, 3> _logical_volume_info;	// d-strings
8959a043bf9STyler Dauwalder 	entity_id _implementation_id;
8969a043bf9STyler Dauwalder 	array<uint8, 128> _implementation_use;
8979a043bf9STyler Dauwalder } __attribute__((packed));
8989a043bf9STyler Dauwalder 
899ead0c3e2STyler Dauwalder /*! \brief Implementation Use Volume Descriptor
900ead0c3e2STyler Dauwalder 
901ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.4
902ead0c3e2STyler Dauwalder */
903ead0c3e2STyler Dauwalder struct implementation_use_descriptor {
904ead0c3e2STyler Dauwalder public:
905ead0c3e2STyler Dauwalder 	void dump() const;
906ead0c3e2STyler Dauwalder 
907ead0c3e2STyler Dauwalder 	// Get functions
tagimplementation_use_descriptor908ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagimplementation_use_descriptor909ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
910ead0c3e2STyler Dauwalder 
vds_numberimplementation_use_descriptor911ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
912ead0c3e2STyler Dauwalder 
implementation_idimplementation_use_descriptor913ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
implementation_idimplementation_use_descriptor914ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
915ead0c3e2STyler Dauwalder 
implementation_useimplementation_use_descriptor916ead0c3e2STyler Dauwalder 	const array<uint8, 460>& implementation_use() const { return _implementation_use; }
implementation_useimplementation_use_descriptor917ead0c3e2STyler Dauwalder 	array<uint8, 460>& implementation_use() { return _implementation_use; }
918ead0c3e2STyler Dauwalder 
9199a043bf9STyler Dauwalder 	// Only valid if implementation_id() returns Udf::kLogicalVolumeInfoId.
infoimplementation_use_descriptor9209a043bf9STyler Dauwalder 	logical_volume_info& info() { return *reinterpret_cast<logical_volume_info*>(_implementation_use.data); }
infoimplementation_use_descriptor9219a043bf9STyler Dauwalder 	const logical_volume_info& info() const { return *reinterpret_cast<const logical_volume_info*>(_implementation_use.data); }
9229a043bf9STyler Dauwalder 
923ead0c3e2STyler Dauwalder 	// Set functions
set_vds_numberimplementation_use_descriptor924ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
925ead0c3e2STyler Dauwalder private:
926ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
927ead0c3e2STyler Dauwalder 	uint32 _vds_number;
928ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
929ead0c3e2STyler Dauwalder 	array<uint8, 460> _implementation_use;
930ead0c3e2STyler Dauwalder } __attribute__((packed));
931ead0c3e2STyler Dauwalder 
932ead0c3e2STyler Dauwalder 
933ead0c3e2STyler Dauwalder /*! \brief Maximum number of partition descriptors to be found in volume
934ead0c3e2STyler Dauwalder 	descriptor sequence, per UDF-2.50
935ead0c3e2STyler Dauwalder */
936*9c707f06SJonathan Schleifer const uint8 kMaxPartitionDescriptors = 2;
937ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAPS 2
938ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAP_SIZE 64
939ead0c3e2STyler Dauwalder 
940ead0c3e2STyler Dauwalder /*! \brief Partition Descriptor
941ead0c3e2STyler Dauwalder 
942ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.5
943ead0c3e2STyler Dauwalder */
944ead0c3e2STyler Dauwalder struct partition_descriptor {
945ead0c3e2STyler Dauwalder private:
946ead0c3e2STyler Dauwalder 	union partition_flags_accessor {
947ead0c3e2STyler Dauwalder 		uint16 partition_flags;
948ead0c3e2STyler Dauwalder 		struct {
949ead0c3e2STyler Dauwalder 			uint16 allocated:1,
950ead0c3e2STyler Dauwalder 			       reserved:15;
951ead0c3e2STyler Dauwalder 		} bits;
952ead0c3e2STyler Dauwalder 	};
953ead0c3e2STyler Dauwalder 
954ead0c3e2STyler Dauwalder public:
955ead0c3e2STyler Dauwalder 	void dump() const;
956ead0c3e2STyler Dauwalder 
957ead0c3e2STyler Dauwalder 	// Get functions
tagpartition_descriptor958ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagpartition_descriptor959ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
960ead0c3e2STyler Dauwalder 
vds_numberpartition_descriptor961ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
partition_flagspartition_descriptor962ead0c3e2STyler Dauwalder 	uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); }
allocatedpartition_descriptor963ead0c3e2STyler Dauwalder 	bool allocated() const {
964ead0c3e2STyler Dauwalder 		partition_flags_accessor f;
965ead0c3e2STyler Dauwalder 		f.partition_flags = partition_flags();
966ead0c3e2STyler Dauwalder 		return f.bits.allocated;
967ead0c3e2STyler Dauwalder 	}
partition_numberpartition_descriptor968ead0c3e2STyler Dauwalder 	uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
969ead0c3e2STyler Dauwalder 
partition_contentspartition_descriptor970ead0c3e2STyler Dauwalder 	const entity_id& partition_contents() const { return _partition_contents; }
partition_contentspartition_descriptor971ead0c3e2STyler Dauwalder 	entity_id& partition_contents() { return _partition_contents; }
972ead0c3e2STyler Dauwalder 
partition_contents_usepartition_descriptor973ead0c3e2STyler Dauwalder 	const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
partition_contents_usepartition_descriptor974ead0c3e2STyler Dauwalder 	array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
975ead0c3e2STyler Dauwalder 
access_typepartition_descriptor976ead0c3e2STyler Dauwalder 	uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); }
startpartition_descriptor977ead0c3e2STyler Dauwalder 	uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); }
lengthpartition_descriptor978ead0c3e2STyler Dauwalder 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
979ead0c3e2STyler Dauwalder 
implementation_idpartition_descriptor980ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
implementation_idpartition_descriptor981ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
982ead0c3e2STyler Dauwalder 
implementation_usepartition_descriptor983ead0c3e2STyler Dauwalder 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
implementation_usepartition_descriptor984ead0c3e2STyler Dauwalder 	array<uint8, 128>& implementation_use() { return _implementation_use; }
985ead0c3e2STyler Dauwalder 
reservedpartition_descriptor986003d4e83STyler Dauwalder 	const array<uint8, 156>& reserved() const { return _reserved; }
reservedpartition_descriptor987003d4e83STyler Dauwalder 	array<uint8, 156>& reserved() { return _reserved; }
988003d4e83STyler Dauwalder 
989ead0c3e2STyler Dauwalder 	// Set functions
set_vds_numberpartition_descriptor990ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
set_partition_flagspartition_descriptor991ead0c3e2STyler Dauwalder 	void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); }
set_allocatedpartition_descriptor992ead0c3e2STyler Dauwalder 	void set_allocated(bool allocated) {
993ead0c3e2STyler Dauwalder 		partition_flags_accessor f;
994ead0c3e2STyler Dauwalder 		f.partition_flags = partition_flags();
995ead0c3e2STyler Dauwalder 		f.bits.allocated = allocated;
996ead0c3e2STyler Dauwalder 		set_partition_flags(f.partition_flags);
997ead0c3e2STyler Dauwalder 	}
set_partition_numberpartition_descriptor998003d4e83STyler Dauwalder 	void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
set_access_typepartition_descriptor999ead0c3e2STyler Dauwalder 	void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); }
set_startpartition_descriptor1000ead0c3e2STyler Dauwalder 	void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); }
set_lengthpartition_descriptor1001ead0c3e2STyler Dauwalder 	void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
1002ead0c3e2STyler Dauwalder 
1003ead0c3e2STyler Dauwalder private:
1004ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1005ead0c3e2STyler Dauwalder 	uint32 _vds_number;
1006ead0c3e2STyler Dauwalder 	/*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
1007ead0c3e2STyler Dauwalder 	    shall mean volume space has been allocated.
1008ead0c3e2STyler Dauwalder 	*/
1009ead0c3e2STyler Dauwalder 	uint16 _partition_flags;
1010ead0c3e2STyler Dauwalder 	uint16 _partition_number;
1011ead0c3e2STyler Dauwalder 
1012ead0c3e2STyler Dauwalder 	/*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF
1013ead0c3e2STyler Dauwalder 		- "+CD001" Volume recorded according to ECMA-119, i.e. iso9660
1014ead0c3e2STyler Dauwalder 		- "+FDC01" Volume recorded according to ECMA-107
1015ead0c3e2STyler Dauwalder 		- "+CDW02" Volume recorded according to ECMA-168
1016ead0c3e2STyler Dauwalder 	*/
1017ead0c3e2STyler Dauwalder 	entity_id _partition_contents;
1018ead0c3e2STyler Dauwalder 	array<uint8, 128> _partition_contents_use;
1019ead0c3e2STyler Dauwalder 
1020ead0c3e2STyler Dauwalder 	/*! See \c partition_access_type enum
1021ead0c3e2STyler Dauwalder 	*/
1022ead0c3e2STyler Dauwalder 	uint32 _access_type;
1023ead0c3e2STyler Dauwalder 	uint32 _start;
1024ead0c3e2STyler Dauwalder 	uint32 _length;
1025ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
1026ead0c3e2STyler Dauwalder 	array<uint8, 128> _implementation_use;
1027003d4e83STyler Dauwalder 	array<uint8, 156> _reserved;
1028ead0c3e2STyler Dauwalder } __attribute__((packed));
1029ead0c3e2STyler Dauwalder 
1030ead0c3e2STyler Dauwalder 
1031ead0c3e2STyler Dauwalder enum partition_access_type {
1032003d4e83STyler Dauwalder 	ACCESS_UNSPECIFIED,
1033003d4e83STyler Dauwalder 	ACCESS_READ_ONLY,
1034003d4e83STyler Dauwalder 	ACCESS_WRITE_ONCE,
1035003d4e83STyler Dauwalder 	ACCESS_REWRITABLE,
1036003d4e83STyler Dauwalder 	ACCESS_OVERWRITABLE,
1037ead0c3e2STyler Dauwalder };
1038ead0c3e2STyler Dauwalder 
1039ead0c3e2STyler Dauwalder 
1040ead0c3e2STyler Dauwalder /*! \brief Logical volume descriptor
1041ead0c3e2STyler Dauwalder 
1042ead0c3e2STyler Dauwalder 	See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
1043ead0c3e2STyler Dauwalder */
1044ead0c3e2STyler Dauwalder struct logical_volume_descriptor {
1045ead0c3e2STyler Dauwalder 	void dump() const;
1046ead0c3e2STyler Dauwalder 
1047ead0c3e2STyler Dauwalder 	// Get functions
taglogical_volume_descriptor1048ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
taglogical_volume_descriptor1049ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1050ead0c3e2STyler Dauwalder 
vds_numberlogical_volume_descriptor1051ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1052ead0c3e2STyler Dauwalder 
character_setlogical_volume_descriptor1053ead0c3e2STyler Dauwalder 	const charspec& character_set() const { return _character_set; }
character_setlogical_volume_descriptor1054ead0c3e2STyler Dauwalder 	charspec& character_set() { return _character_set; }
1055ead0c3e2STyler Dauwalder 
logical_volume_identifierlogical_volume_descriptor1056ead0c3e2STyler Dauwalder 	const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
logical_volume_identifierlogical_volume_descriptor1057ead0c3e2STyler Dauwalder 	array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
1058ead0c3e2STyler Dauwalder 
logical_block_sizelogical_volume_descriptor1059ead0c3e2STyler Dauwalder 	uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
1060ead0c3e2STyler Dauwalder 
domain_idlogical_volume_descriptor1061ead0c3e2STyler Dauwalder 	const entity_id& domain_id() const { return _domain_id; }
domain_idlogical_volume_descriptor1062ead0c3e2STyler Dauwalder 	entity_id& domain_id() { return _domain_id; }
1063ead0c3e2STyler Dauwalder 
logical_volume_contents_uselogical_volume_descriptor1064ead0c3e2STyler Dauwalder 	const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
logical_volume_contents_uselogical_volume_descriptor1065ead0c3e2STyler Dauwalder 	array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; }
1066ead0c3e2STyler Dauwalder 
file_set_addresslogical_volume_descriptor1067d1a0387eSTyler Dauwalder 	const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); }
file_set_addresslogical_volume_descriptor1068d1a0387eSTyler Dauwalder 	long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); }
1069ead0c3e2STyler Dauwalder 
map_table_lengthlogical_volume_descriptor1070ead0c3e2STyler Dauwalder 	uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); }
partition_map_countlogical_volume_descriptor1071ead0c3e2STyler Dauwalder 	uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); }
1072ead0c3e2STyler Dauwalder 
implementation_idlogical_volume_descriptor1073ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
implementation_idlogical_volume_descriptor1074ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
1075ead0c3e2STyler Dauwalder 
implementation_uselogical_volume_descriptor1076ead0c3e2STyler Dauwalder 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
implementation_uselogical_volume_descriptor1077ead0c3e2STyler Dauwalder 	array<uint8, 128>& implementation_use() { return _implementation_use; }
1078ead0c3e2STyler Dauwalder 
integrity_sequence_extentlogical_volume_descriptor1079ead0c3e2STyler Dauwalder 	const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
integrity_sequence_extentlogical_volume_descriptor1080ead0c3e2STyler Dauwalder 	extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
1081ead0c3e2STyler Dauwalder 
partition_mapslogical_volume_descriptor1082ead0c3e2STyler Dauwalder 	const uint8* partition_maps() const { return _partition_maps; }
partition_mapslogical_volume_descriptor1083ead0c3e2STyler Dauwalder 	uint8* partition_maps() { return _partition_maps; }
1084ead0c3e2STyler Dauwalder 
1085ead0c3e2STyler Dauwalder 	// Set functions
set_vds_numberlogical_volume_descriptor1086ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
set_logical_block_sizelogical_volume_descriptor1087ead0c3e2STyler Dauwalder 	void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); }
1088ead0c3e2STyler Dauwalder 
set_map_table_lengthlogical_volume_descriptor1089ead0c3e2STyler Dauwalder 	void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); }
set_partition_map_countlogical_volume_descriptor1090ead0c3e2STyler Dauwalder 	void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); }
1091ead0c3e2STyler Dauwalder 
1092ead0c3e2STyler Dauwalder 	// Other functions
1093ead0c3e2STyler Dauwalder 	logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
1094ead0c3e2STyler Dauwalder 
1095ead0c3e2STyler Dauwalder private:
1096ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1097ead0c3e2STyler Dauwalder 	uint32 _vds_number;
1098ead0c3e2STyler Dauwalder 
1099ead0c3e2STyler Dauwalder 	/*! \brief Identifies the character set for the
1100ead0c3e2STyler Dauwalder 		\c logical_volume_identifier field.
1101ead0c3e2STyler Dauwalder 
1102ead0c3e2STyler Dauwalder 		To be set to CS0.
1103ead0c3e2STyler Dauwalder 	*/
1104ead0c3e2STyler Dauwalder 	charspec _character_set;
1105ead0c3e2STyler Dauwalder 	array<char, 128> _logical_volume_identifier;
1106ead0c3e2STyler Dauwalder 	uint32 _logical_block_size;
1107ead0c3e2STyler Dauwalder 
1108ead0c3e2STyler Dauwalder 	/*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
1109ead0c3e2STyler Dauwalder 	*/
1110ead0c3e2STyler Dauwalder 	entity_id _domain_id;
1111ead0c3e2STyler Dauwalder 
1112ead0c3e2STyler Dauwalder 	/*! \brief For UDF, shall contain a \c long_address which identifies
1113ead0c3e2STyler Dauwalder 		the location of the logical volume's first file set.
1114ead0c3e2STyler Dauwalder 	*/
1115ead0c3e2STyler Dauwalder 	array<uint8, 16> _logical_volume_contents_use;
1116ead0c3e2STyler Dauwalder 
1117ead0c3e2STyler Dauwalder 	uint32 _map_table_length;
1118ead0c3e2STyler Dauwalder 	uint32 _partition_map_count;
1119ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
1120ead0c3e2STyler Dauwalder 	array<uint8, 128> _implementation_use;
1121ead0c3e2STyler Dauwalder 
1122ead0c3e2STyler Dauwalder 	/*! \brief Logical volume integrity sequence location.
1123ead0c3e2STyler Dauwalder 
1124ead0c3e2STyler Dauwalder 		For re/overwritable media, shall be a min of 8KB in length.
1125ead0c3e2STyler Dauwalder 		For WORM media, shall be quite frickin large, as a new volume
1126ead0c3e2STyler Dauwalder 		must be added to the set if the extent fills up (since you
1127ead0c3e2STyler Dauwalder 		can't chain lvis's I guess).
1128ead0c3e2STyler Dauwalder 	*/
1129ead0c3e2STyler Dauwalder 	extent_address _integrity_sequence_extent;
1130ead0c3e2STyler Dauwalder 
1131ead0c3e2STyler Dauwalder 	/*! \brief Restricted to maps of type 1 for normal maps and
1132ead0c3e2STyler Dauwalder 		UDF type 2 for virtual maps or maps on systems not supporting
1133ead0c3e2STyler Dauwalder 		defect management.
1134ead0c3e2STyler Dauwalder 
1135ead0c3e2STyler Dauwalder 		Note that we actually allocate memory for the partition maps
1136ead0c3e2STyler Dauwalder 		here due to the fact that we allocate logical_volume_descriptor
1137ead0c3e2STyler Dauwalder 		objects on the stack sometimes.
1138ead0c3e2STyler Dauwalder 
1139ead0c3e2STyler Dauwalder 		See UDF-2.01 2.2.8, 2.2.9
1140ead0c3e2STyler Dauwalder 	*/
1141ead0c3e2STyler Dauwalder 	uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1142ead0c3e2STyler Dauwalder } __attribute__((packed));
1143ead0c3e2STyler Dauwalder 
1144730ba00aSTyler Dauwalder //! Base size (excluding partition maps) of lvd
1145730ba00aSTyler Dauwalder extern const uint32 kLogicalVolumeDescriptorBaseSize;
1146ead0c3e2STyler Dauwalder 
1147ead0c3e2STyler Dauwalder /*! \brief (Mostly) common portion of various partition maps
1148ead0c3e2STyler Dauwalder 
1149ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.7.1
1150ead0c3e2STyler Dauwalder */
1151ead0c3e2STyler Dauwalder struct partition_map_header {
1152ead0c3e2STyler Dauwalder public:
typepartition_map_header1153ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
lengthpartition_map_header1154ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
map_datapartition_map_header1155ead0c3e2STyler Dauwalder 	uint8 *map_data() { return _map_data; }
map_datapartition_map_header1156ead0c3e2STyler Dauwalder 	const uint8 *map_data() const { return _map_data; }
1157ead0c3e2STyler Dauwalder 
partition_type_idpartition_map_header1158ead0c3e2STyler Dauwalder 	entity_id& partition_type_id()
1159ead0c3e2STyler Dauwalder 		{ return *reinterpret_cast<entity_id*>(&_map_data[2]); }
partition_type_idpartition_map_header1160ead0c3e2STyler Dauwalder 	const entity_id& partition_type_id() const
1161ead0c3e2STyler Dauwalder 		{ return *reinterpret_cast<const entity_id*>(&_map_data[2]); }
1162ead0c3e2STyler Dauwalder 
set_typepartition_map_header1163ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
set_lengthpartition_map_header1164ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
1165ead0c3e2STyler Dauwalder private:
1166ead0c3e2STyler Dauwalder 	uint8 _type;
1167ead0c3e2STyler Dauwalder 	uint8 _length;
1168ead0c3e2STyler Dauwalder 	uint8 _map_data[0];
1169ead0c3e2STyler Dauwalder };// __attribute__((packed));
1170ead0c3e2STyler Dauwalder 
1171ead0c3e2STyler Dauwalder 
1172ead0c3e2STyler Dauwalder /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
1173ead0c3e2STyler Dauwalder 
1174ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.7.2
1175ead0c3e2STyler Dauwalder */
1176ead0c3e2STyler Dauwalder struct physical_partition_map {
1177ead0c3e2STyler Dauwalder public:
1178ead0c3e2STyler Dauwalder 	void dump();
1179ead0c3e2STyler Dauwalder 
typephysical_partition_map1180ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
lengthphysical_partition_map1181ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
1182ead0c3e2STyler Dauwalder 
volume_sequence_numberphysical_partition_map1183ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const {
1184ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
partition_numberphysical_partition_map1185ead0c3e2STyler Dauwalder 	uint16 partition_number() const {
1186ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1187ead0c3e2STyler Dauwalder 
set_typephysical_partition_map1188ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
set_lengthphysical_partition_map1189ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
set_volume_sequence_numberphysical_partition_map1190ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number) {
1191ead0c3e2STyler Dauwalder 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
set_partition_numberphysical_partition_map1192ead0c3e2STyler Dauwalder 	void set_partition_number(uint16 number) {
1193ead0c3e2STyler Dauwalder 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1194ead0c3e2STyler Dauwalder private:
1195ead0c3e2STyler Dauwalder 	uint8 _type;
1196ead0c3e2STyler Dauwalder 	uint8 _length;
1197ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
1198ead0c3e2STyler Dauwalder 	uint16 _partition_number;
1199ead0c3e2STyler Dauwalder } __attribute__((packed));
1200ead0c3e2STyler Dauwalder 
1201ead0c3e2STyler Dauwalder 
1202ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1203ead0c3e2STyler Dauwalder /*! \brief Virtual partition map
1204ead0c3e2STyler Dauwalder 
1205ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1206ead0c3e2STyler Dauwalder 	type 2 partition map.
1207ead0c3e2STyler Dauwalder 
1208ead0c3e2STyler Dauwalder 	See also: UDF-2.01 2.2.8
1209ead0c3e2STyler Dauwalder */
1210ead0c3e2STyler Dauwalder struct virtual_partition_map {
1211ead0c3e2STyler Dauwalder 	uint8 type;
1212ead0c3e2STyler Dauwalder 	uint8 length;
1213ead0c3e2STyler Dauwalder 	uint8 reserved1[2];
1214ead0c3e2STyler Dauwalder 
1215ead0c3e2STyler Dauwalder 	/*! - flags: 0
1216ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Virtual Partition"
1217ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1218ead0c3e2STyler Dauwalder 	*/
1219ead0c3e2STyler Dauwalder 	entity_id partition_type_id;
1220ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number;
1221ead0c3e2STyler Dauwalder 
1222ead0c3e2STyler Dauwalder 	/*! corresponding type 1 partition map in same logical volume
1223ead0c3e2STyler Dauwalder 	*/
1224ead0c3e2STyler Dauwalder 	uint16 partition_number;
1225ead0c3e2STyler Dauwalder 	uint8 reserved2[24];
1226ead0c3e2STyler Dauwalder } __attribute__((packed));
1227ead0c3e2STyler Dauwalder 
1228ead0c3e2STyler Dauwalder 
1229ead0c3e2STyler Dauwalder /*! \brief Maximum number of redundant sparing tables found in
1230ead0c3e2STyler Dauwalder 	sparable_partition_map structures.
1231ead0c3e2STyler Dauwalder */
1232ead0c3e2STyler Dauwalder #define UDF_MAX_SPARING_TABLE_COUNT 4
1233ead0c3e2STyler Dauwalder 
1234ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1235ead0c3e2STyler Dauwalder /*! \brief Sparable partition map
1236ead0c3e2STyler Dauwalder 
1237ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1238ead0c3e2STyler Dauwalder 	type 2 partition map.
1239ead0c3e2STyler Dauwalder 
1240ead0c3e2STyler Dauwalder 	See also: UDF-2.01 2.2.9
1241ead0c3e2STyler Dauwalder */
1242ead0c3e2STyler Dauwalder struct sparable_partition_map {
1243ead0c3e2STyler Dauwalder public:
1244ead0c3e2STyler Dauwalder 	void dump();
1245ead0c3e2STyler Dauwalder 
typesparable_partition_map1246ead0c3e2STyler Dauwalder 	uint8 type() const { return _type; }
lengthsparable_partition_map1247ead0c3e2STyler Dauwalder 	uint8 length() const { return _length; }
1248ead0c3e2STyler Dauwalder 
partition_type_idsparable_partition_map1249ead0c3e2STyler Dauwalder 	entity_id& partition_type_id() { return _partition_type_id; }
partition_type_idsparable_partition_map1250ead0c3e2STyler Dauwalder 	const entity_id& partition_type_id() const { return _partition_type_id; }
1251ead0c3e2STyler Dauwalder 
volume_sequence_numbersparable_partition_map1252ead0c3e2STyler Dauwalder 	uint16 volume_sequence_number() const {
1253ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
partition_numbersparable_partition_map1254ead0c3e2STyler Dauwalder 	uint16 partition_number() const {
1255ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
packet_lengthsparable_partition_map1256ead0c3e2STyler Dauwalder 	uint16 packet_length() const {
1257ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT16(_packet_length); }
sparing_table_countsparable_partition_map1258ead0c3e2STyler Dauwalder 	uint8 sparing_table_count() const { return _sparing_table_count; }
sparing_table_sizesparable_partition_map1259ead0c3e2STyler Dauwalder 	uint32 sparing_table_size() const {
1260ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); }
sparing_table_locationsparable_partition_map1261ead0c3e2STyler Dauwalder 	uint32 sparing_table_location(uint8 index) const {
1262ead0c3e2STyler Dauwalder 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); }
1263ead0c3e2STyler Dauwalder 
1264ead0c3e2STyler Dauwalder 
set_typesparable_partition_map1265ead0c3e2STyler Dauwalder 	void set_type(uint8 type) { _type = type; }
set_lengthsparable_partition_map1266ead0c3e2STyler Dauwalder 	void set_length(uint8 length) { _length = length; }
set_volume_sequence_numbersparable_partition_map1267ead0c3e2STyler Dauwalder 	void set_volume_sequence_number(uint16 number) {
1268ead0c3e2STyler Dauwalder 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
set_partition_numbersparable_partition_map1269ead0c3e2STyler Dauwalder 	void set_partition_number(uint16 number) {
1270ead0c3e2STyler Dauwalder 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
set_packet_lengthsparable_partition_map1271ead0c3e2STyler Dauwalder 	void set_packet_length(uint16 length) {
1272ead0c3e2STyler Dauwalder 		_packet_length = B_HOST_TO_LENDIAN_INT16(length); }
set_sparing_table_countsparable_partition_map1273ead0c3e2STyler Dauwalder 	void set_sparing_table_count(uint8 count) {
1274ead0c3e2STyler Dauwalder 		_sparing_table_count = count; }
set_sparing_table_sizesparable_partition_map1275ead0c3e2STyler Dauwalder 	void set_sparing_table_size(uint32 size) {
1276ead0c3e2STyler Dauwalder 		_sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
set_sparing_table_locationsparable_partition_map1277ead0c3e2STyler Dauwalder 	void set_sparing_table_location(uint8 index, uint32 location) {
1278ead0c3e2STyler Dauwalder 		_sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
1279ead0c3e2STyler Dauwalder private:
1280ead0c3e2STyler Dauwalder 	uint8 _type;
1281ead0c3e2STyler Dauwalder 	uint8 _length;
1282ead0c3e2STyler Dauwalder 	uint8 _reserved1[2];
1283ead0c3e2STyler Dauwalder 
1284ead0c3e2STyler Dauwalder 	/*! - flags: 0
1285ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Sparable Partition"
1286ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1287ead0c3e2STyler Dauwalder 	*/
1288ead0c3e2STyler Dauwalder 	entity_id _partition_type_id;
1289ead0c3e2STyler Dauwalder 	uint16 _volume_sequence_number;
1290ead0c3e2STyler Dauwalder 
1291ead0c3e2STyler Dauwalder 	//! partition number of corresponding partition descriptor
1292ead0c3e2STyler Dauwalder 	uint16 _partition_number;
1293ead0c3e2STyler Dauwalder 	uint16 _packet_length;
1294ead0c3e2STyler Dauwalder 	uint8 _sparing_table_count;
1295ead0c3e2STyler Dauwalder 	uint8 _reserved2;
1296ead0c3e2STyler Dauwalder 	uint32 _sparing_table_size;
1297ead0c3e2STyler Dauwalder 	uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT];
1298ead0c3e2STyler Dauwalder } __attribute__((packed));
1299ead0c3e2STyler Dauwalder 
1300ead0c3e2STyler Dauwalder 
1301ead0c3e2STyler Dauwalder /* ----UDF Specific---- */
1302ead0c3e2STyler Dauwalder /*! \brief Metadata partition map
1303ead0c3e2STyler Dauwalder 
1304ead0c3e2STyler Dauwalder 	Note that this map is a customization of the ECMA-167
1305ead0c3e2STyler Dauwalder 	type 2 partition map.
1306ead0c3e2STyler Dauwalder 
1307ead0c3e2STyler Dauwalder 	See also: UDF-2.50 2.2.10
1308ead0c3e2STyler Dauwalder */
1309ead0c3e2STyler Dauwalder struct metadata_partition_map {
1310c530d46cSJérôme Duval public:
partition_type_idmetadata_partition_map1311c530d46cSJérôme Duval 	entity_id& partition_type_id() { return _partition_type_id; }
partition_type_idmetadata_partition_map1312c530d46cSJérôme Duval 	const entity_id& partition_type_id() const { return _partition_type_id; }
1313c530d46cSJérôme Duval 
volume_sequence_numbermetadata_partition_map1314c530d46cSJérôme Duval 	uint16 volume_sequence_number() const {
1315c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
set_volume_sequence_numbermetadata_partition_map1316c530d46cSJérôme Duval 	void set_volume_sequence_number(uint16 number) {
1317c530d46cSJérôme Duval 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1318c530d46cSJérôme Duval 
partition_numbermetadata_partition_map1319c530d46cSJérôme Duval 	uint16 partition_number() const {
1320c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
set_partition_numbermetadata_partition_map1321c530d46cSJérôme Duval 	void set_partition_number(uint16 number) {
1322c530d46cSJérôme Duval 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1323c530d46cSJérôme Duval 
metadata_file_locationmetadata_partition_map1324c530d46cSJérôme Duval 	uint32 metadata_file_location() const {
1325c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT32(_metadata_file_location); }
set_metadata_file_locationmetadata_partition_map1326c530d46cSJérôme Duval 	void set_metadata_file_location(uint32 location) {
1327c530d46cSJérôme Duval 		_metadata_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1328c530d46cSJérôme Duval 
metadata_mirror_file_locationmetadata_partition_map1329c530d46cSJérôme Duval 	uint32 metadata_mirror_file_location() const {
1330c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT32(_metadata_mirror_file_location); }
set_metadata_mirror_file_locationmetadata_partition_map1331c530d46cSJérôme Duval 	void set_metadata_mirror_file_location(uint32 location) {
1332c530d46cSJérôme Duval 		_metadata_mirror_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1333c530d46cSJérôme Duval 
metadata_bitmap_file_locationmetadata_partition_map1334c530d46cSJérôme Duval 	uint32 metadata_bitmap_file_location() const {
1335c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT32(_metadata_bitmap_file_location); }
set_metadata_bitmap_file_locationmetadata_partition_map1336c530d46cSJérôme Duval 	void set_metadata_bitmap_file_location(uint32 location) {
1337c530d46cSJérôme Duval 		_metadata_bitmap_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1338c530d46cSJérôme Duval 
allocation_unit_sizemetadata_partition_map1339c530d46cSJérôme Duval 	uint32 allocation_unit_size() const {
1340c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT32(_allocation_unit_size); }
set_allocation_unit_sizemetadata_partition_map1341c530d46cSJérôme Duval 	void set_allocation_unit_size(uint32 size) {
1342c530d46cSJérôme Duval 		_allocation_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1343c530d46cSJérôme Duval 
alignment_unit_sizemetadata_partition_map1344c530d46cSJérôme Duval 	uint32 alignment_unit_size() const {
1345c530d46cSJérôme Duval 		return B_LENDIAN_TO_HOST_INT32(_alignment_unit_size); }
set_alignment_unit_sizemetadata_partition_map1346c530d46cSJérôme Duval 	void set_alignment_unit_size(uint32 size) {
1347c530d46cSJérôme Duval 		_alignment_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1348c530d46cSJérôme Duval 
flagsmetadata_partition_map1349c530d46cSJérôme Duval 	uint8 flags() const { return _flags; }
set_flagsmetadata_partition_map1350c530d46cSJérôme Duval 	void set_flags(uint8 flags) { _flags = flags; }
1351c530d46cSJérôme Duval 
1352c530d46cSJérôme Duval private:
1353ead0c3e2STyler Dauwalder 	uint8 type;
1354ead0c3e2STyler Dauwalder 	uint8 length;
1355ead0c3e2STyler Dauwalder 	uint8 reserved1[2];
1356ead0c3e2STyler Dauwalder 
1357ead0c3e2STyler Dauwalder 	/*! - flags: 0
1358ead0c3e2STyler Dauwalder 	    - identifier: "*UDF Metadata Partition"
1359ead0c3e2STyler Dauwalder 	    - identifier_suffix: per UDF-2.50 2.1.5
1360ead0c3e2STyler Dauwalder 	*/
1361c530d46cSJérôme Duval 	entity_id _partition_type_id;
1362c530d46cSJérôme Duval 	uint16 _volume_sequence_number;
1363ead0c3e2STyler Dauwalder 
1364ead0c3e2STyler Dauwalder 	/*! corresponding type 1 or type 2 sparable partition
1365ead0c3e2STyler Dauwalder 	    map in same logical volume
1366ead0c3e2STyler Dauwalder 	*/
1367c530d46cSJérôme Duval 	uint16 _partition_number;
1368c530d46cSJérôme Duval 	uint32 _metadata_file_location;
1369c530d46cSJérôme Duval 	uint32 _metadata_mirror_file_location;
1370c530d46cSJérôme Duval 	uint32 _metadata_bitmap_file_location;
1371c530d46cSJérôme Duval 	uint32 _allocation_unit_size;
1372c530d46cSJérôme Duval 	uint16 _alignment_unit_size;
1373c530d46cSJérôme Duval 	uint8 _flags;
1374c530d46cSJérôme Duval 	uint8 reserved2[5];
1375ead0c3e2STyler Dauwalder } __attribute__((packed));
1376ead0c3e2STyler Dauwalder 
1377ead0c3e2STyler Dauwalder 
1378ead0c3e2STyler Dauwalder /*! \brief Unallocated space descriptor
1379ead0c3e2STyler Dauwalder 
1380ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.8
1381ead0c3e2STyler Dauwalder */
1382ead0c3e2STyler Dauwalder struct unallocated_space_descriptor {
1383ead0c3e2STyler Dauwalder 	void dump() const;
1384ead0c3e2STyler Dauwalder 
1385ead0c3e2STyler Dauwalder 	// Get functions
tagunallocated_space_descriptor1386ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagunallocated_space_descriptor1387ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
vds_numberunallocated_space_descriptor1388ead0c3e2STyler Dauwalder 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
allocation_descriptor_countunallocated_space_descriptor1389ead0c3e2STyler Dauwalder 	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
allocation_descriptorsunallocated_space_descriptor1390ead0c3e2STyler Dauwalder 	extent_address* allocation_descriptors() { return _allocation_descriptors; }
1391ead0c3e2STyler Dauwalder 
1392ead0c3e2STyler Dauwalder 	// Set functions
set_vds_numberunallocated_space_descriptor1393ead0c3e2STyler Dauwalder 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
set_allocation_descriptor_countunallocated_space_descriptor1394ead0c3e2STyler Dauwalder 	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1395ead0c3e2STyler Dauwalder private:
1396ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1397ead0c3e2STyler Dauwalder 	uint32 _vds_number;
1398ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptor_count;
1399ead0c3e2STyler Dauwalder 	extent_address _allocation_descriptors[0];
1400ead0c3e2STyler Dauwalder } __attribute__((packed));
1401ead0c3e2STyler Dauwalder 
1402ead0c3e2STyler Dauwalder 
1403ead0c3e2STyler Dauwalder /*! \brief Terminating descriptor
1404ead0c3e2STyler Dauwalder 
1405ead0c3e2STyler Dauwalder 	See also: ECMA-167 3/10.9
1406ead0c3e2STyler Dauwalder */
1407ead0c3e2STyler Dauwalder struct terminating_descriptor {
terminating_descriptorterminating_descriptor140810186d5dSTyler Dauwalder 	terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
1409ead0c3e2STyler Dauwalder 	void dump() const;
1410ead0c3e2STyler Dauwalder 
1411ead0c3e2STyler Dauwalder 	// Get functions
tagterminating_descriptor1412ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagterminating_descriptor1413ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1414ead0c3e2STyler Dauwalder private:
1415ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
141610186d5dSTyler Dauwalder 	array<uint8, 496> _reserved;
1417ead0c3e2STyler Dauwalder } __attribute__((packed));
1418ead0c3e2STyler Dauwalder 
1419ead0c3e2STyler Dauwalder 
1420ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity descriptor
1421ead0c3e2STyler Dauwalder 
1422335fd883STyler Dauwalder 	See also: ECMA-167 3/10.10, UDF-2.50 2.2.6
1423ead0c3e2STyler Dauwalder */
1424ead0c3e2STyler Dauwalder struct logical_volume_integrity_descriptor {
1425335fd883STyler Dauwalder public:
1426b3a4ae39STyler Dauwalder 	static const uint32 minimum_implementation_use_length = 46;
1427b3a4ae39STyler Dauwalder 
1428335fd883STyler Dauwalder 	void dump() const;
descriptor_sizelogical_volume_integrity_descriptor142910186d5dSTyler Dauwalder 	uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length()
143010186d5dSTyler Dauwalder 	                                 + partition_count()*sizeof(uint32)*2; }
1431335fd883STyler Dauwalder 
taglogical_volume_integrity_descriptor1432335fd883STyler Dauwalder 	descriptor_tag& tag() { return _tag; }
taglogical_volume_integrity_descriptor1433335fd883STyler Dauwalder 	const descriptor_tag& tag() const { return _tag; }
1434335fd883STyler Dauwalder 
recording_timelogical_volume_integrity_descriptor1435335fd883STyler Dauwalder 	timestamp& recording_time() { return _recording_time; }
recording_timelogical_volume_integrity_descriptor1436335fd883STyler Dauwalder 	const timestamp& recording_time() const { return _recording_time; }
1437335fd883STyler Dauwalder 
integrity_typelogical_volume_integrity_descriptor1438335fd883STyler Dauwalder 	uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); }
1439335fd883STyler Dauwalder 
next_integrity_extentlogical_volume_integrity_descriptor1440335fd883STyler Dauwalder 	extent_address& next_integrity_extent() { return _next_integrity_extent; }
next_integrity_extentlogical_volume_integrity_descriptor1441335fd883STyler Dauwalder 	const extent_address& next_integrity_extent() const { return _next_integrity_extent; }
1442335fd883STyler Dauwalder 
logical_volume_contents_uselogical_volume_integrity_descriptor1443335fd883STyler Dauwalder 	array<uint8, 32>& logical_volume_contents_use() { return _logical_volume_contents_use; }
logical_volume_contents_uselogical_volume_integrity_descriptor1444335fd883STyler Dauwalder 	const array<uint8, 32>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
1445335fd883STyler Dauwalder 
1446b3a4ae39STyler Dauwalder 	// next_unique_id() field is actually stored in the logical_volume_contents_use()
1447b3a4ae39STyler Dauwalder 	// field, per UDF-2.50 3.2.1
next_unique_idlogical_volume_integrity_descriptor1448b3a4ae39STyler Dauwalder 	uint64 next_unique_id() const { return B_LENDIAN_TO_HOST_INT64(_next_unique_id()); }
1449b3a4ae39STyler Dauwalder 
partition_countlogical_volume_integrity_descriptor1450335fd883STyler Dauwalder 	uint32 partition_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_count); }
implementation_use_lengthlogical_volume_integrity_descriptor1451335fd883STyler Dauwalder 	uint32 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT32(_implementation_use_length); }
1452ead0c3e2STyler Dauwalder 
1453ead0c3e2STyler Dauwalder 	/*! \todo double-check the pointer arithmetic here. */
free_space_tablelogical_volume_integrity_descriptor1454b3a4ae39STyler Dauwalder 	uint32* free_space_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(this)+80); }
free_space_tablelogical_volume_integrity_descriptor1455b3a4ae39STyler Dauwalder 	const uint32* free_space_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(this)+80); }
size_tablelogical_volume_integrity_descriptor1456b3a4ae39STyler Dauwalder 	uint32* size_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
size_tablelogical_volume_integrity_descriptor1457b3a4ae39STyler Dauwalder 	const uint32* size_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
implementation_uselogical_volume_integrity_descriptor1458b3a4ae39STyler Dauwalder 	uint8* implementation_use() { return reinterpret_cast<uint8*>(reinterpret_cast<uint8*>(size_table())+partition_count()*sizeof(uint32)); }
implementation_uselogical_volume_integrity_descriptor1459b3a4ae39STyler Dauwalder 	const uint8* implementation_use() const { return reinterpret_cast<const uint8*>(reinterpret_cast<const uint8*>(size_table())+partition_count()*sizeof(uint32)); }
1460335fd883STyler Dauwalder 
1461335fd883STyler Dauwalder 	// accessors for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
implementation_idlogical_volume_integrity_descriptor1462b3a4ae39STyler Dauwalder 	entity_id& implementation_id() { return _accessor().id; }
implementation_idlogical_volume_integrity_descriptor1463b3a4ae39STyler Dauwalder 	const entity_id& implementation_id() const { return _accessor().id; }
file_countlogical_volume_integrity_descriptor1464335fd883STyler Dauwalder 	uint32 file_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().file_count); }
directory_countlogical_volume_integrity_descriptor1465335fd883STyler Dauwalder 	uint32 directory_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().directory_count); }
minimum_udf_read_revisionlogical_volume_integrity_descriptor1466335fd883STyler Dauwalder 	uint16 minimum_udf_read_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_read_revision); }
minimum_udf_write_revisionlogical_volume_integrity_descriptor1467335fd883STyler Dauwalder 	uint16 minimum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_write_revision); }
maximum_udf_write_revisionlogical_volume_integrity_descriptor1468335fd883STyler Dauwalder 	uint16 maximum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().maximum_udf_write_revision); }
1469335fd883STyler Dauwalder 
1470335fd883STyler Dauwalder 	// set functions
set_integrity_typelogical_volume_integrity_descriptor1471335fd883STyler Dauwalder 	void set_integrity_type(uint32 type) { _integrity_type = B_HOST_TO_LENDIAN_INT32(type); }
set_next_unique_idlogical_volume_integrity_descriptor1472b3a4ae39STyler Dauwalder 	void set_next_unique_id(uint64 id) { _next_unique_id() = B_HOST_TO_LENDIAN_INT64(id); }
set_partition_countlogical_volume_integrity_descriptor1473335fd883STyler Dauwalder 	void set_partition_count(uint32 count) { _partition_count = B_HOST_TO_LENDIAN_INT32(count); }
set_implementation_use_lengthlogical_volume_integrity_descriptor1474b3a4ae39STyler Dauwalder 	void set_implementation_use_length(uint32 length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT32(length); }
1475335fd883STyler Dauwalder 
1476335fd883STyler Dauwalder 	// set functions for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
set_file_countlogical_volume_integrity_descriptor1477335fd883STyler Dauwalder 	void set_file_count(uint32 count) { _accessor().file_count = B_HOST_TO_LENDIAN_INT32(count); }
set_directory_countlogical_volume_integrity_descriptor1478335fd883STyler Dauwalder 	void set_directory_count(uint32 count) { _accessor().directory_count = B_HOST_TO_LENDIAN_INT32(count); }
set_minimum_udf_read_revisionlogical_volume_integrity_descriptor1479335fd883STyler Dauwalder 	void set_minimum_udf_read_revision(uint16 revision) { _accessor().minimum_udf_read_revision = B_HOST_TO_LENDIAN_INT16(revision); }
set_minimum_udf_write_revisionlogical_volume_integrity_descriptor1480335fd883STyler Dauwalder 	void set_minimum_udf_write_revision(uint16 revision) { _accessor().minimum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
set_maximum_udf_write_revisionlogical_volume_integrity_descriptor1481335fd883STyler Dauwalder 	void set_maximum_udf_write_revision(uint16 revision) { _accessor().maximum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1482335fd883STyler Dauwalder 
1483335fd883STyler Dauwalder private:
1484335fd883STyler Dauwalder 	struct _lvid_implementation_use_accessor {
1485335fd883STyler Dauwalder 		entity_id id;
1486335fd883STyler Dauwalder 		uint32 file_count;
1487335fd883STyler Dauwalder 		uint32 directory_count;
1488335fd883STyler Dauwalder 		uint16 minimum_udf_read_revision;
1489335fd883STyler Dauwalder 		uint16 minimum_udf_write_revision;
1490335fd883STyler Dauwalder 		uint16 maximum_udf_write_revision;
1491335fd883STyler Dauwalder 	};
1492335fd883STyler Dauwalder 
_accessorlogical_volume_integrity_descriptor1493335fd883STyler Dauwalder 	_lvid_implementation_use_accessor& _accessor() {
1494335fd883STyler Dauwalder 		return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use());
1495335fd883STyler Dauwalder 	}
_accessorlogical_volume_integrity_descriptor1496335fd883STyler Dauwalder 	const _lvid_implementation_use_accessor& _accessor() const {
1497335fd883STyler Dauwalder 		return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use());
1498335fd883STyler Dauwalder 	}
1499335fd883STyler Dauwalder 
_next_unique_idlogical_volume_integrity_descriptor1500b3a4ae39STyler Dauwalder 	uint64& _next_unique_id() { return *reinterpret_cast<uint64*>(logical_volume_contents_use().data); }
_next_unique_idlogical_volume_integrity_descriptor1501b3a4ae39STyler Dauwalder 	const uint64& _next_unique_id() const { return *reinterpret_cast<const uint64*>(logical_volume_contents_use().data); }
1502b3a4ae39STyler Dauwalder 
1503335fd883STyler Dauwalder 	descriptor_tag  _tag;
1504335fd883STyler Dauwalder 	timestamp _recording_time;
1505335fd883STyler Dauwalder 	uint32 _integrity_type;
1506335fd883STyler Dauwalder 	extent_address _next_integrity_extent;
1507335fd883STyler Dauwalder 	array<uint8, 32> _logical_volume_contents_use;
1508335fd883STyler Dauwalder 	uint32 _partition_count;
1509335fd883STyler Dauwalder 	uint32 _implementation_use_length;
1510ead0c3e2STyler Dauwalder 
1511ead0c3e2STyler Dauwalder } __attribute__((packed));
1512ead0c3e2STyler Dauwalder 
1513ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity types
1514ead0c3e2STyler Dauwalder */
1515ead0c3e2STyler Dauwalder enum {
1516335fd883STyler Dauwalder 	INTEGRITY_OPEN = 0,
1517335fd883STyler Dauwalder 	INTEGRITY_CLOSED = 1,
1518ead0c3e2STyler Dauwalder };
1519ead0c3e2STyler Dauwalder 
1520e9927e2bSTyler Dauwalder /*! \brief Highest currently supported UDF read revision.
1521e9927e2bSTyler Dauwalder */
1522c530d46cSJérôme Duval #define UDF_MAX_READ_REVISION 0x0250
1523e9927e2bSTyler Dauwalder 
1524ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
1525ead0c3e2STyler Dauwalder // ECMA-167 Part 4
1526ead0c3e2STyler Dauwalder //----------------------------------------------------------------------
1527ead0c3e2STyler Dauwalder 
1528ead0c3e2STyler Dauwalder 
1529ead0c3e2STyler Dauwalder 
1530ead0c3e2STyler Dauwalder /*! \brief File set descriptor
1531ead0c3e2STyler Dauwalder 
1532ead0c3e2STyler Dauwalder 	Contains all the pertinent info about a file set (i.e. a hierarchy of files)
1533ead0c3e2STyler Dauwalder 
1534ead0c3e2STyler Dauwalder 	According to UDF-2.01, only one file set descriptor shall be recorded,
1535ead0c3e2STyler Dauwalder 	except on WORM media, where the following rules apply:
1536ead0c3e2STyler Dauwalder 	- Multiple file sets are allowed only on WORM media
1537ead0c3e2STyler Dauwalder 	- The default file set shall be the one with highest value \c file_set_number field.
1538ead0c3e2STyler Dauwalder 	- Only the default file set may be flagged as writeable. All others shall be
1539ead0c3e2STyler Dauwalder 	  flagged as "hard write protect".
1540ead0c3e2STyler Dauwalder 	- No writeable file set may reference metadata structures which are referenced
1541ead0c3e2STyler Dauwalder 	  (directly or indirectly) by any other file set. Writeable file sets may, however,
1542ead0c3e2STyler Dauwalder 	  reference actual file data extents that are also referenced by other file sets.
1543ead0c3e2STyler Dauwalder */
1544ead0c3e2STyler Dauwalder struct file_set_descriptor {
1545ead0c3e2STyler Dauwalder 	void dump() const;
1546ead0c3e2STyler Dauwalder 
1547ead0c3e2STyler Dauwalder 	// Get functions
tagfile_set_descriptor1548ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
tagfile_set_descriptor1549ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
1550ead0c3e2STyler Dauwalder 
recording_date_and_timefile_set_descriptor1551ead0c3e2STyler Dauwalder 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
recording_date_and_timefile_set_descriptor1552ead0c3e2STyler Dauwalder 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
1553ead0c3e2STyler Dauwalder 
interchange_levelfile_set_descriptor1554ead0c3e2STyler Dauwalder 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
max_interchange_levelfile_set_descriptor1555ead0c3e2STyler Dauwalder 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
character_set_listfile_set_descriptor1556ead0c3e2STyler Dauwalder 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
max_character_set_listfile_set_descriptor1557ead0c3e2STyler Dauwalder 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
file_set_numberfile_set_descriptor1558ead0c3e2STyler Dauwalder 	uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); }
file_set_descriptor_numberfile_set_descriptor1559ead0c3e2STyler Dauwalder 	uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); }
1560ead0c3e2STyler Dauwalder 
logical_volume_id_character_setfile_set_descriptor1561ead0c3e2STyler Dauwalder 	const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; }
logical_volume_id_character_setfile_set_descriptor1562ead0c3e2STyler Dauwalder 	charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; }
1563ead0c3e2STyler Dauwalder 
logical_volume_idfile_set_descriptor1564ead0c3e2STyler Dauwalder 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
logical_volume_idfile_set_descriptor1565ead0c3e2STyler Dauwalder 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
1566ead0c3e2STyler Dauwalder 
file_set_id_character_setfile_set_descriptor1567d1a0387eSTyler Dauwalder 	const charspec& file_set_id_character_set() const { return _file_set_id_character_set; }
file_set_id_character_setfile_set_descriptor1568d1a0387eSTyler Dauwalder 	charspec& file_set_id_character_set() { return _file_set_id_character_set; }
1569d1a0387eSTyler Dauwalder 
file_set_idfile_set_descriptor1570ead0c3e2STyler Dauwalder 	const array<char, 32>& file_set_id() const { return _file_set_id; }
file_set_idfile_set_descriptor1571ead0c3e2STyler Dauwalder 	array<char, 32>& file_set_id() { return _file_set_id; }
1572ead0c3e2STyler Dauwalder 
copyright_file_idfile_set_descriptor1573ead0c3e2STyler Dauwalder 	const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
copyright_file_idfile_set_descriptor1574ead0c3e2STyler Dauwalder 	array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1575ead0c3e2STyler Dauwalder 
abstract_file_idfile_set_descriptor1576ead0c3e2STyler Dauwalder 	const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
abstract_file_idfile_set_descriptor1577ead0c3e2STyler Dauwalder 	array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1578ead0c3e2STyler Dauwalder 
root_directory_icbfile_set_descriptor1579ead0c3e2STyler Dauwalder 	const long_address& root_directory_icb() const { return _root_directory_icb; }
root_directory_icbfile_set_descriptor1580ead0c3e2STyler Dauwalder 	long_address& root_directory_icb() { return _root_directory_icb; }
1581ead0c3e2STyler Dauwalder 
domain_idfile_set_descriptor1582ead0c3e2STyler Dauwalder 	const entity_id& domain_id() const { return _domain_id; }
domain_idfile_set_descriptor1583ead0c3e2STyler Dauwalder 	entity_id& domain_id() { return _domain_id; }
1584ead0c3e2STyler Dauwalder 
next_extentfile_set_descriptor1585ead0c3e2STyler Dauwalder 	const long_address& next_extent() const { return _next_extent; }
next_extentfile_set_descriptor1586ead0c3e2STyler Dauwalder 	long_address& next_extent() { return _next_extent; }
1587ead0c3e2STyler Dauwalder 
system_stream_directory_icbfile_set_descriptor1588ead0c3e2STyler Dauwalder 	const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; }
system_stream_directory_icbfile_set_descriptor1589ead0c3e2STyler Dauwalder 	long_address& system_stream_directory_icb() { return _system_stream_directory_icb; }
1590ead0c3e2STyler Dauwalder 
reservedfile_set_descriptor1591d1a0387eSTyler Dauwalder 	const array<uint8, 32>& reserved() const { return _reserved; }
reservedfile_set_descriptor1592d1a0387eSTyler Dauwalder 	array<uint8, 32>& reserved() { return _reserved; }
1593d1a0387eSTyler Dauwalder 
1594ead0c3e2STyler Dauwalder 	// Set functions
set_interchange_levelfile_set_descriptor1595ead0c3e2STyler Dauwalder 	void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
set_max_interchange_levelfile_set_descriptor1596ead0c3e2STyler Dauwalder 	void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
set_character_set_listfile_set_descriptor1597ead0c3e2STyler Dauwalder 	void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
set_max_character_set_listfile_set_descriptor1598ead0c3e2STyler Dauwalder 	void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
set_file_set_numberfile_set_descriptor1599ead0c3e2STyler Dauwalder 	void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
set_file_set_descriptor_numberfile_set_descriptor1600ead0c3e2STyler Dauwalder 	void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1601ead0c3e2STyler Dauwalder private:
1602ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1603ead0c3e2STyler Dauwalder 	timestamp _recording_date_and_time;
1604ead0c3e2STyler Dauwalder 	uint16 _interchange_level;			//!< To be set to 3 (see UDF-2.01 2.3.2.1)
1605ead0c3e2STyler Dauwalder 	uint16 _max_interchange_level;		//!< To be set to 3 (see UDF-2.01 2.3.2.2)
1606ead0c3e2STyler Dauwalder 	uint32 _character_set_list;
1607ead0c3e2STyler Dauwalder 	uint32 _max_character_set_list;
1608ead0c3e2STyler Dauwalder 	uint32 _file_set_number;
1609ead0c3e2STyler Dauwalder 	uint32 _file_set_descriptor_number;
1610ead0c3e2STyler Dauwalder 	charspec _logical_volume_id_character_set;	//!< To be set to kCSOCharspec
1611ead0c3e2STyler Dauwalder 	array<char, 128> _logical_volume_id;
1612d1a0387eSTyler Dauwalder 	charspec _file_set_id_character_set;
1613ead0c3e2STyler Dauwalder 	array<char, 32> _file_set_id;
1614ead0c3e2STyler Dauwalder 	array<char, 32> _copyright_file_id;
1615ead0c3e2STyler Dauwalder 	array<char, 32> _abstract_file_id;
1616ead0c3e2STyler Dauwalder 	long_address _root_directory_icb;
1617ead0c3e2STyler Dauwalder 	entity_id _domain_id;
1618ead0c3e2STyler Dauwalder 	long_address _next_extent;
1619ead0c3e2STyler Dauwalder 	long_address _system_stream_directory_icb;
1620d1a0387eSTyler Dauwalder 	array<uint8, 32> _reserved;
1621ead0c3e2STyler Dauwalder } __attribute__((packed));
1622ead0c3e2STyler Dauwalder 
1623ead0c3e2STyler Dauwalder 
1624ead0c3e2STyler Dauwalder /*! \brief Partition header descriptor
1625ead0c3e2STyler Dauwalder 
1626ead0c3e2STyler Dauwalder 	Contains references to unallocated and freed space data structures.
1627ead0c3e2STyler Dauwalder 
1628ead0c3e2STyler Dauwalder 	Note that unallocated space is space ready to be written with no
1629ead0c3e2STyler Dauwalder 	preprocessing. Freed space is space needing preprocessing (i.e.
1630ead0c3e2STyler Dauwalder 	a special write pass) before use.
1631ead0c3e2STyler Dauwalder 
1632ead0c3e2STyler Dauwalder 	Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent,
1633ead0c3e2STyler Dauwalder 	i.e. only one type or the other shall be used, not both.
1634ead0c3e2STyler Dauwalder 
1635ead0c3e2STyler Dauwalder 	To indicate disuse of a certain field, the fields of the allocation
1636ead0c3e2STyler Dauwalder 	descriptor shall all be set to 0.
1637ead0c3e2STyler Dauwalder 
1638ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1639ead0c3e2STyler Dauwalder */
1640ead0c3e2STyler Dauwalder struct partition_header_descriptor {
1641ead0c3e2STyler Dauwalder 	long_address unallocated_space_table;
1642ead0c3e2STyler Dauwalder 	long_address unallocated_space_bitmap;
1643ead0c3e2STyler Dauwalder 	/*! Unused, per UDF-2.01 2.2.3 */
1644ead0c3e2STyler Dauwalder 	long_address partition_integrity_table;
1645ead0c3e2STyler Dauwalder 	long_address freed_space_table;
1646ead0c3e2STyler Dauwalder 	long_address freed_space_bitmap;
1647ead0c3e2STyler Dauwalder 	uint8 reserved[88];
1648ead0c3e2STyler Dauwalder } __attribute__((packed));
1649ead0c3e2STyler Dauwalder 
1650ead0c3e2STyler Dauwalder #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1651ead0c3e2STyler Dauwalder 
1652ead0c3e2STyler Dauwalder /*! \brief File identifier descriptor
1653ead0c3e2STyler Dauwalder 
1654ead0c3e2STyler Dauwalder 	Identifies the name of a file entry, and the location of its corresponding
1655ead0c3e2STyler Dauwalder 	ICB.
1656ead0c3e2STyler Dauwalder 
1657ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1658ead0c3e2STyler Dauwalder 
1659ead0c3e2STyler Dauwalder 	\todo Check pointer arithmetic
1660ead0c3e2STyler Dauwalder */
1661ead0c3e2STyler Dauwalder struct file_id_descriptor {
1662ead0c3e2STyler Dauwalder public:
descriptor_sizefile_id_descriptor166380b849abSTyler Dauwalder 	uint32 descriptor_size() const { return total_length(); }
1664ead0c3e2STyler Dauwalder 	void dump() const;
1665ead0c3e2STyler Dauwalder 
tagfile_id_descriptor1666ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
tagfile_id_descriptor1667ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
1668ead0c3e2STyler Dauwalder 
version_numberfile_id_descriptor1669ead0c3e2STyler Dauwalder 	uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1670ead0c3e2STyler Dauwalder 
characteristicsfile_id_descriptor1671ead0c3e2STyler Dauwalder 	uint8 characteristics() const { return _characteristics; }
1672ead0c3e2STyler Dauwalder 
may_be_hiddenfile_id_descriptor1673ead0c3e2STyler Dauwalder 	bool may_be_hidden() const {
1674ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1675ead0c3e2STyler Dauwalder 		c.all = characteristics();
1676ead0c3e2STyler Dauwalder 		return c.bits.may_be_hidden;
1677ead0c3e2STyler Dauwalder 	}
1678ead0c3e2STyler Dauwalder 
is_directoryfile_id_descriptor1679ead0c3e2STyler Dauwalder 	bool is_directory() const {
1680ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1681ead0c3e2STyler Dauwalder 		c.all = characteristics();
1682ead0c3e2STyler Dauwalder 		return c.bits.is_directory;
1683ead0c3e2STyler Dauwalder 	}
1684ead0c3e2STyler Dauwalder 
is_deletedfile_id_descriptor1685ead0c3e2STyler Dauwalder 	bool is_deleted() const {
1686ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1687ead0c3e2STyler Dauwalder 		c.all = characteristics();
1688ead0c3e2STyler Dauwalder 		return c.bits.is_deleted;
1689ead0c3e2STyler Dauwalder 	}
1690ead0c3e2STyler Dauwalder 
is_parentfile_id_descriptor1691ead0c3e2STyler Dauwalder 	bool is_parent() const {
1692ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1693ead0c3e2STyler Dauwalder 		c.all = characteristics();
1694ead0c3e2STyler Dauwalder 		return c.bits.is_parent;
1695ead0c3e2STyler Dauwalder 	}
1696ead0c3e2STyler Dauwalder 
is_metadata_streamfile_id_descriptor1697ead0c3e2STyler Dauwalder 	bool is_metadata_stream() const {
1698ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1699ead0c3e2STyler Dauwalder 		c.all = characteristics();
1700ead0c3e2STyler Dauwalder 		return c.bits.is_metadata_stream;
1701ead0c3e2STyler Dauwalder 	}
1702ead0c3e2STyler Dauwalder 
id_lengthfile_id_descriptor1703ead0c3e2STyler Dauwalder 	uint8 id_length() const { return _id_length; }
1704ead0c3e2STyler Dauwalder 
icbfile_id_descriptor1705ead0c3e2STyler Dauwalder 	long_address& icb() { return _icb; }
icbfile_id_descriptor1706ead0c3e2STyler Dauwalder 	const long_address& icb() const { return _icb; }
1707ead0c3e2STyler Dauwalder 
implementation_use_lengthfile_id_descriptor170880b849abSTyler Dauwalder 	uint16 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT16(_implementation_use_length); }
1709ead0c3e2STyler Dauwalder 
1710ead0c3e2STyler Dauwalder 	/*! If implementation_use_length is greater than 0, the first 32
1711ead0c3e2STyler Dauwalder 		bytes of implementation_use() shall be an entity_id identifying
1712ead0c3e2STyler Dauwalder 		the implementation that generated the rest of the data in the
1713ead0c3e2STyler Dauwalder 		implementation_use() field.
1714ead0c3e2STyler Dauwalder 	*/
implementation_usefile_id_descriptor17154f0e6a75STyler Dauwalder 	uint8* implementation_use() { return ((uint8*)this)+(38); }
idfile_id_descriptor17164f0e6a75STyler Dauwalder 	char* id() { return ((char*)this)+(38)+implementation_use_length(); }
idfile_id_descriptor17174f0e6a75STyler Dauwalder 	const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); }
1718ead0c3e2STyler Dauwalder 
structure_lengthfile_id_descriptor17194f0e6a75STyler Dauwalder 	uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); }
padding_lengthfile_id_descriptor1720ead0c3e2STyler Dauwalder 	uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); }
total_lengthfile_id_descriptor1721ead0c3e2STyler Dauwalder 	uint16 total_length() const { return structure_length() + padding_length(); }
1722ead0c3e2STyler Dauwalder 
1723ead0c3e2STyler Dauwalder 	// Set functions
set_version_numberfile_id_descriptor1724ead0c3e2STyler Dauwalder 	void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1725ead0c3e2STyler Dauwalder 
set_characteristicsfile_id_descriptor1726ead0c3e2STyler Dauwalder 	void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
1727ead0c3e2STyler Dauwalder 
set_may_be_hiddenfile_id_descriptor1728ead0c3e2STyler Dauwalder 	void set_may_be_hidden(bool how) {
1729ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1730ead0c3e2STyler Dauwalder 		c.all = characteristics();
1731ead0c3e2STyler Dauwalder 		c.bits.may_be_hidden = how;
1732ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1733ead0c3e2STyler Dauwalder 	}
1734ead0c3e2STyler Dauwalder 
set_is_directoryfile_id_descriptor1735ead0c3e2STyler Dauwalder 	void set_is_directory(bool how) {
1736ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1737ead0c3e2STyler Dauwalder 		c.all = characteristics();
1738ead0c3e2STyler Dauwalder 		c.bits.is_directory = how;
1739ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1740ead0c3e2STyler Dauwalder 	}
1741ead0c3e2STyler Dauwalder 
set_is_deletedfile_id_descriptor1742ead0c3e2STyler Dauwalder 	void set_is_deleted(bool how) {
1743ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1744ead0c3e2STyler Dauwalder 		c.all = characteristics();
1745ead0c3e2STyler Dauwalder 		c.bits.is_deleted = how;
1746ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1747ead0c3e2STyler Dauwalder 	}
1748ead0c3e2STyler Dauwalder 
set_is_parentfile_id_descriptor1749ead0c3e2STyler Dauwalder 	void set_is_parent(bool how) {
1750ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1751ead0c3e2STyler Dauwalder 		c.all = characteristics();
1752ead0c3e2STyler Dauwalder 		c.bits.is_parent = how;
1753ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1754ead0c3e2STyler Dauwalder 	}
1755ead0c3e2STyler Dauwalder 
set_is_metadata_streamfile_id_descriptor1756ead0c3e2STyler Dauwalder 	void set_is_metadata_stream(bool how) {
1757ead0c3e2STyler Dauwalder 		characteristics_accessor c;
1758ead0c3e2STyler Dauwalder 		c.all = characteristics();
1759ead0c3e2STyler Dauwalder 		c.bits.is_metadata_stream = how;
1760ead0c3e2STyler Dauwalder 		set_characteristics(c.all);
1761ead0c3e2STyler Dauwalder 	}
1762ead0c3e2STyler Dauwalder 
1763ead0c3e2STyler Dauwalder 
set_id_lengthfile_id_descriptor1764ead0c3e2STyler Dauwalder 	void set_id_length(uint8 id_length) { _id_length = id_length; }
set_implementation_use_lengthfile_id_descriptor176580b849abSTyler Dauwalder 	void set_implementation_use_length(uint16 implementation_use_length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT16(implementation_use_length); }
1766ead0c3e2STyler Dauwalder 
1767ead0c3e2STyler Dauwalder 
1768ead0c3e2STyler Dauwalder 
1769ead0c3e2STyler Dauwalder private:
1770ead0c3e2STyler Dauwalder 	union characteristics_accessor {
1771ead0c3e2STyler Dauwalder 		uint8 all;
1772ead0c3e2STyler Dauwalder 		struct {
1773ead0c3e2STyler Dauwalder 			uint8	may_be_hidden:1,
1774ead0c3e2STyler Dauwalder 					is_directory:1,
1775ead0c3e2STyler Dauwalder 					is_deleted:1,
1776ead0c3e2STyler Dauwalder 					is_parent:1,
1777ead0c3e2STyler Dauwalder 					is_metadata_stream:1,
1778ead0c3e2STyler Dauwalder 					reserved_characteristics:3;
1779ead0c3e2STyler Dauwalder 		} bits;
1780ead0c3e2STyler Dauwalder 	};
1781ead0c3e2STyler Dauwalder 
1782ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1783ead0c3e2STyler Dauwalder 	/*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1784ead0c3e2STyler Dauwalder 
1785ead0c3e2STyler Dauwalder 		However, according to UDF-2.01, there shall be exactly one version of
1786ead0c3e2STyler Dauwalder 		a file, and it shall be 1.
1787ead0c3e2STyler Dauwalder 	 */
1788ead0c3e2STyler Dauwalder 	uint16 _version_number;
1789ead0c3e2STyler Dauwalder 	/*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */
1790ead0c3e2STyler Dauwalder 	uint8 _characteristics;
1791ead0c3e2STyler Dauwalder 	uint8 _id_length;
1792ead0c3e2STyler Dauwalder 	long_address _icb;
179380b849abSTyler Dauwalder 	uint16 _implementation_use_length;
1794ead0c3e2STyler Dauwalder } __attribute__((packed));
1795ead0c3e2STyler Dauwalder 
1796ead0c3e2STyler Dauwalder 
1797ead0c3e2STyler Dauwalder /*! \brief Allocation extent descriptor
1798ead0c3e2STyler Dauwalder 
1799ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.5
1800ead0c3e2STyler Dauwalder */
1801ead0c3e2STyler Dauwalder struct allocation_extent_descriptor {
1802ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1803ead0c3e2STyler Dauwalder 	uint32 previous_allocation_extent_location;
1804ead0c3e2STyler Dauwalder 	uint32 length_of_allocation_descriptors;
1805ead0c3e2STyler Dauwalder 
1806ead0c3e2STyler Dauwalder 	/*! \todo Check that this is really how things work: */
allocation_descriptorsallocation_extent_descriptor1807b3a4ae39STyler Dauwalder 	uint8* allocation_descriptors() { return (uint8*)(reinterpret_cast<uint8*>(this)+sizeof(allocation_extent_descriptor)); }
1808ead0c3e2STyler Dauwalder } __attribute__((packed));
1809ead0c3e2STyler Dauwalder 
1810ead0c3e2STyler Dauwalder 
1811ead0c3e2STyler Dauwalder /*! \brief icb_tag::file_type values
1812ead0c3e2STyler Dauwalder 
1813ead0c3e2STyler Dauwalder 	See also ECMA-167 4/14.6.6
1814ead0c3e2STyler Dauwalder */
1815ead0c3e2STyler Dauwalder enum icb_file_types {
1816ead0c3e2STyler Dauwalder 	ICB_TYPE_UNSPECIFIED = 0,
1817ead0c3e2STyler Dauwalder 	ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1818ead0c3e2STyler Dauwalder 	ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1819ead0c3e2STyler Dauwalder 	ICB_TYPE_INDIRECT_ENTRY,
1820ead0c3e2STyler Dauwalder 	ICB_TYPE_DIRECTORY,
1821ead0c3e2STyler Dauwalder 	ICB_TYPE_REGULAR_FILE,
1822ead0c3e2STyler Dauwalder 	ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1823ead0c3e2STyler Dauwalder 	ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1824ead0c3e2STyler Dauwalder 	ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1825ead0c3e2STyler Dauwalder 	ICB_TYPE_FIFO,
1826ead0c3e2STyler Dauwalder 	ICB_TYPE_ISSOCK,
1827ead0c3e2STyler Dauwalder 	ICB_TYPE_TERMINAL,
1828ead0c3e2STyler Dauwalder 	ICB_TYPE_SYMLINK,
1829ead0c3e2STyler Dauwalder 	ICB_TYPE_STREAM_DIRECTORY,
1830ead0c3e2STyler Dauwalder 
1831ead0c3e2STyler Dauwalder 	ICB_TYPE_RESERVED_START = 14,
1832ead0c3e2STyler Dauwalder 	ICB_TYPE_RESERVED_END = 247,
1833ead0c3e2STyler Dauwalder 
1834ead0c3e2STyler Dauwalder 	ICB_TYPE_CUSTOM_START = 248,
1835ead0c3e2STyler Dauwalder 	ICB_TYPE_CUSTOM_END = 255,
1836ead0c3e2STyler Dauwalder };
1837ead0c3e2STyler Dauwalder 
1838ead0c3e2STyler Dauwalder /*!	\brief idb_entry_tag::_flags::descriptor_flags() values
1839ead0c3e2STyler Dauwalder 
1840ead0c3e2STyler Dauwalder 	See also ECMA-167 4/14.6.8
1841ead0c3e2STyler Dauwalder */
1842ead0c3e2STyler Dauwalder enum icb_descriptor_types {
1843ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_SHORT = 0,
1844ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_LONG,
1845ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_EXTENDED,
1846ead0c3e2STyler Dauwalder 	ICB_DESCRIPTOR_TYPE_EMBEDDED,
1847ead0c3e2STyler Dauwalder };
1848ead0c3e2STyler Dauwalder 
1849e631ed51STyler Dauwalder /*!	\brief idb_entry_tag::strategy_type() values
1850e631ed51STyler Dauwalder 
1851e631ed51STyler Dauwalder 	See also UDF-2.50 2.3.5.1
1852e631ed51STyler Dauwalder */
1853e631ed51STyler Dauwalder enum icb_strategy_types {
1854e631ed51STyler Dauwalder 	ICB_STRATEGY_SINGLE = 4,
1855e631ed51STyler Dauwalder 	ICB_STRATEGY_LINKED_LIST = 4096
1856e631ed51STyler Dauwalder };
1857e631ed51STyler Dauwalder 
1858ead0c3e2STyler Dauwalder /*! \brief ICB entry tag
1859ead0c3e2STyler Dauwalder 
1860ead0c3e2STyler Dauwalder 	Common tag found in all ICB entries (in addition to, and immediately following,
1861ead0c3e2STyler Dauwalder 	the descriptor tag).
1862ead0c3e2STyler Dauwalder 
1863ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1864ead0c3e2STyler Dauwalder */
1865ead0c3e2STyler Dauwalder struct icb_entry_tag {
1866e631ed51STyler Dauwalder public:
1867ead0c3e2STyler Dauwalder 	union flags_accessor {
1868ead0c3e2STyler Dauwalder 		uint16 all_flags;
1869ead0c3e2STyler Dauwalder 		struct {
1870ead0c3e2STyler Dauwalder 			uint16	descriptor_flags:3,
1871ead0c3e2STyler Dauwalder 					if_directory_then_sort:1,	//!< To be set to 0 per UDF-2.01 2.3.5.4
1872ead0c3e2STyler Dauwalder 					non_relocatable:1,
1873ead0c3e2STyler Dauwalder 					archive:1,
1874ead0c3e2STyler Dauwalder 					setuid:1,
1875ead0c3e2STyler Dauwalder 					setgid:1,
1876ead0c3e2STyler Dauwalder 					sticky:1,
1877ead0c3e2STyler Dauwalder 					contiguous:1,
1878ead0c3e2STyler Dauwalder 					system:1,
1879ead0c3e2STyler Dauwalder 					transformed:1,
1880ead0c3e2STyler Dauwalder 					multi_version:1,			//!< To be set to 0 per UDF-2.01 2.3.5.4
1881ead0c3e2STyler Dauwalder 					is_stream:1,
1882ead0c3e2STyler Dauwalder 					reserved_icb_entry_flags:2;
1883ead0c3e2STyler Dauwalder 		} flags;
1884ead0c3e2STyler Dauwalder 	};
1885ead0c3e2STyler Dauwalder 
1886ead0c3e2STyler Dauwalder public:
1887ead0c3e2STyler Dauwalder 	void dump() const;
1888ead0c3e2STyler Dauwalder 
prior_recorded_number_of_direct_entriesicb_entry_tag1889ead0c3e2STyler Dauwalder 	uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); }
strategy_typeicb_entry_tag1890ead0c3e2STyler Dauwalder 	uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); }
1891ead0c3e2STyler Dauwalder 
strategy_parametersicb_entry_tag1892ead0c3e2STyler Dauwalder 	array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
strategy_parametersicb_entry_tag1893ead0c3e2STyler Dauwalder 	const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
1894ead0c3e2STyler Dauwalder 
entry_counticb_entry_tag1895ead0c3e2STyler Dauwalder 	uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); }
reservedicb_entry_tag1896e631ed51STyler Dauwalder 	uint8& reserved() { return _reserved; }
file_typeicb_entry_tag1897ead0c3e2STyler Dauwalder 	uint8 file_type() const { return _file_type; }
parent_icb_locationicb_entry_tag1898ead0c3e2STyler Dauwalder 	logical_block_address& parent_icb_location() { return _parent_icb_location; }
parent_icb_locationicb_entry_tag1899ead0c3e2STyler Dauwalder 	const logical_block_address& parent_icb_location() const { return _parent_icb_location; }
1900ead0c3e2STyler Dauwalder 
flagsicb_entry_tag1901ead0c3e2STyler Dauwalder 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
flags_accessicb_entry_tag1902e631ed51STyler Dauwalder 	flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); }
1903ead0c3e2STyler Dauwalder 
1904ead0c3e2STyler Dauwalder 	// flags accessor functions
descriptor_flagsicb_entry_tag1905ead0c3e2STyler Dauwalder 	uint8 descriptor_flags() const {
1906ead0c3e2STyler Dauwalder 		flags_accessor f;
1907ead0c3e2STyler Dauwalder 		f.all_flags = flags();
1908ead0c3e2STyler Dauwalder 		return f.flags.descriptor_flags;
1909ead0c3e2STyler Dauwalder 	}
1910e631ed51STyler Dauwalder /*	void set_descriptor_flags(uint8 value) {
1911e631ed51STyler Dauwalder 		flags_accessor f;
1912e631ed51STyler Dauwalder 		f.all_flags = flags();
1913e631ed51STyler Dauwalder 		f.flags.descriptor_flags = value;
1914e631ed51STyler Dauwalder 		set_flags
1915e631ed51STyler Dauwalder */
1916ead0c3e2STyler Dauwalder 
set_prior_recorded_number_of_direct_entriesicb_entry_tag1917ead0c3e2STyler Dauwalder 	void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); }
set_strategy_typeicb_entry_tag1918ead0c3e2STyler Dauwalder 	void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); }
1919ead0c3e2STyler Dauwalder 
set_entry_counticb_entry_tag1920ead0c3e2STyler Dauwalder 	void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); }
set_file_typeicb_entry_tag1921ead0c3e2STyler Dauwalder 	void set_file_type(uint8 type) { _file_type = type; }
1922ead0c3e2STyler Dauwalder 
set_flagsicb_entry_tag1923ead0c3e2STyler Dauwalder 	void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1924ead0c3e2STyler Dauwalder 
1925ead0c3e2STyler Dauwalder private:
1926ead0c3e2STyler Dauwalder 	uint32 _prior_recorded_number_of_direct_entries;
1927ead0c3e2STyler Dauwalder 	/*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1928ead0c3e2STyler Dauwalder 
1929ead0c3e2STyler Dauwalder 		\todo Describe strategy types here.
1930ead0c3e2STyler Dauwalder 	*/
1931ead0c3e2STyler Dauwalder 	uint16 _strategy_type;
1932ead0c3e2STyler Dauwalder 	array<uint8, 2> _strategy_parameters;
1933ead0c3e2STyler Dauwalder 	uint16 _entry_count;
1934ead0c3e2STyler Dauwalder 	uint8 _reserved;
1935ead0c3e2STyler Dauwalder 	/*! \brief icb_file_type value identifying the type of this icb entry */
1936ead0c3e2STyler Dauwalder 	uint8 _file_type;
1937ead0c3e2STyler Dauwalder 	logical_block_address _parent_icb_location;
1938ead0c3e2STyler Dauwalder 	uint16 _flags;
1939ead0c3e2STyler Dauwalder } __attribute__((packed));
1940ead0c3e2STyler Dauwalder 
1941ead0c3e2STyler Dauwalder /*! \brief Header portion of an ICB entry.
1942ead0c3e2STyler Dauwalder */
1943ead0c3e2STyler Dauwalder struct icb_header {
1944ead0c3e2STyler Dauwalder public:
1945ead0c3e2STyler Dauwalder 	void dump() const;
1946ead0c3e2STyler Dauwalder 
tagicb_header1947ead0c3e2STyler Dauwalder 	descriptor_tag  &tag() { return _tag; }
tagicb_header1948ead0c3e2STyler Dauwalder 	const descriptor_tag  &tag() const { return _tag; }
1949ead0c3e2STyler Dauwalder 
icb_tagicb_header1950ead0c3e2STyler Dauwalder 	icb_entry_tag &icb_tag() { return _icb_tag; }
icb_tagicb_header1951ead0c3e2STyler Dauwalder 	const icb_entry_tag &icb_tag() const { return _icb_tag; }
1952ead0c3e2STyler Dauwalder private:
1953ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
1954ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
1955ead0c3e2STyler Dauwalder };
1956ead0c3e2STyler Dauwalder 
1957ead0c3e2STyler Dauwalder /*! \brief Indirect ICB entry
1958ead0c3e2STyler Dauwalder */
1959ead0c3e2STyler Dauwalder struct indirect_icb_entry {
1960ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1961ead0c3e2STyler Dauwalder 	icb_entry_tag icb_tag;
1962ead0c3e2STyler Dauwalder 	long_address indirect_icb;
1963ead0c3e2STyler Dauwalder } __attribute__((packed));
1964ead0c3e2STyler Dauwalder 
1965ead0c3e2STyler Dauwalder 
1966ead0c3e2STyler Dauwalder /*! \brief Terminal ICB entry
1967ead0c3e2STyler Dauwalder */
1968ead0c3e2STyler Dauwalder struct terminal_icb_entry {
1969ead0c3e2STyler Dauwalder 	descriptor_tag  tag;
1970ead0c3e2STyler Dauwalder 	icb_entry_tag icb_tag;
1971ead0c3e2STyler Dauwalder } __attribute__((packed));
1972ead0c3e2STyler Dauwalder 
1973e631ed51STyler Dauwalder enum permissions {
1974e631ed51STyler Dauwalder 	OTHER_EXECUTE	 	= 0x0001,
1975e631ed51STyler Dauwalder 	OTHER_WRITE			= 0x0002,
1976e631ed51STyler Dauwalder 	OTHER_READ			= 0x0004,
1977e631ed51STyler Dauwalder 	OTHER_ATTRIBUTES	= 0x0008,
1978e631ed51STyler Dauwalder 	OTHER_DELETE		= 0x0010,
1979e631ed51STyler Dauwalder 	GROUP_EXECUTE	 	= 0x0020,
1980e631ed51STyler Dauwalder 	GROUP_WRITE			= 0x0040,
1981e631ed51STyler Dauwalder 	GROUP_READ			= 0x0080,
1982e631ed51STyler Dauwalder 	GROUP_ATTRIBUTES	= 0x0100,
1983e631ed51STyler Dauwalder 	GROUP_DELETE		= 0x0200,
1984e631ed51STyler Dauwalder 	USER_EXECUTE	 	= 0x0400,
1985e631ed51STyler Dauwalder 	USER_WRITE			= 0x0800,
1986e631ed51STyler Dauwalder 	USER_READ			= 0x1000,
1987e631ed51STyler Dauwalder 	USER_ATTRIBUTES		= 0x2000,
1988e631ed51STyler Dauwalder 	USER_DELETE			= 0x4000,
1989e631ed51STyler Dauwalder };
1990ead0c3e2STyler Dauwalder 
1991ead0c3e2STyler Dauwalder /*! \brief File ICB entry
1992ead0c3e2STyler Dauwalder 
1993ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.9
1994ead0c3e2STyler Dauwalder 
1995ead0c3e2STyler Dauwalder 	\todo Check pointer math.
1996ead0c3e2STyler Dauwalder */
1997ead0c3e2STyler Dauwalder struct file_icb_entry {
1998e631ed51STyler Dauwalder 	void dump() const;
descriptor_sizefile_icb_entry1999e9927e2bSTyler Dauwalder 	uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
2000e9927e2bSTyler Dauwalder 	                                 +allocation_descriptors_length(); }
descriptor_namefile_icb_entry2001e9927e2bSTyler Dauwalder 	const char* descriptor_name() const { return "file_icb_entry"; }
2002e631ed51STyler Dauwalder 
2003ead0c3e2STyler Dauwalder 	// get functions
tagfile_icb_entry2004ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
tagfile_icb_entry2005ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
2006ead0c3e2STyler Dauwalder 
icb_tagfile_icb_entry2007ead0c3e2STyler Dauwalder 	icb_entry_tag& icb_tag() { return _icb_tag; }
icb_tagfile_icb_entry2008ead0c3e2STyler Dauwalder 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
2009ead0c3e2STyler Dauwalder 
uidfile_icb_entry2010e631ed51STyler Dauwalder 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
gidfile_icb_entry2011e631ed51STyler Dauwalder 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
permissionsfile_icb_entry2012e631ed51STyler Dauwalder 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
file_link_countfile_icb_entry2013e631ed51STyler Dauwalder 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
record_formatfile_icb_entry2014e631ed51STyler Dauwalder 	uint8 record_format() const { return _record_format; }
record_display_attributesfile_icb_entry2015e631ed51STyler Dauwalder 	uint8 record_display_attributes() const { return _record_display_attributes; }
record_lengthfile_icb_entry2016e631ed51STyler Dauwalder 	uint8 record_length() const { return _record_length; }
information_lengthfile_icb_entry2017e631ed51STyler Dauwalder 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
logical_blocks_recordedfile_icb_entry2018e631ed51STyler Dauwalder 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
2019ead0c3e2STyler Dauwalder 
access_date_and_timefile_icb_entry2020ead0c3e2STyler Dauwalder 	timestamp& access_date_and_time() { return _access_date_and_time; }
access_date_and_timefile_icb_entry2021ead0c3e2STyler Dauwalder 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
2022ead0c3e2STyler Dauwalder 
modification_date_and_timefile_icb_entry2023ead0c3e2STyler Dauwalder 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
modification_date_and_timefile_icb_entry2024ead0c3e2STyler Dauwalder 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2025ead0c3e2STyler Dauwalder 
attribute_date_and_timefile_icb_entry2026ead0c3e2STyler Dauwalder 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
attribute_date_and_timefile_icb_entry2027ead0c3e2STyler Dauwalder 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2028ead0c3e2STyler Dauwalder 
checkpointfile_icb_entry2029e631ed51STyler Dauwalder 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2030ead0c3e2STyler Dauwalder 
extended_attribute_icbfile_icb_entry2031ead0c3e2STyler Dauwalder 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
extended_attribute_icbfile_icb_entry2032ead0c3e2STyler Dauwalder 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2033ead0c3e2STyler Dauwalder 
implementation_idfile_icb_entry2034ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
implementation_idfile_icb_entry2035ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
2036ead0c3e2STyler Dauwalder 
unique_idfile_icb_entry2037e631ed51STyler Dauwalder 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
extended_attributes_lengthfile_icb_entry2038e631ed51STyler Dauwalder 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
allocation_descriptors_lengthfile_icb_entry2039e631ed51STyler Dauwalder 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
2040ead0c3e2STyler Dauwalder 
extended_attributesfile_icb_entry204110186d5dSTyler Dauwalder 	uint8* extended_attributes() { return _end(); }
extended_attributesfile_icb_entry204210186d5dSTyler Dauwalder 	const uint8* extended_attributes() const { return _end(); }
allocation_descriptorsfile_icb_entry204310186d5dSTyler Dauwalder 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
allocation_descriptorsfile_icb_entry204410186d5dSTyler Dauwalder 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
2045ead0c3e2STyler Dauwalder 
2046ead0c3e2STyler Dauwalder 	// set functions
set_uidfile_icb_entry2047ead0c3e2STyler Dauwalder 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
set_gidfile_icb_entry2048ead0c3e2STyler Dauwalder 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
set_permissionsfile_icb_entry2049ead0c3e2STyler Dauwalder 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
2050ead0c3e2STyler Dauwalder 
set_file_link_countfile_icb_entry2051ead0c3e2STyler Dauwalder 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
set_record_formatfile_icb_entry2052ead0c3e2STyler Dauwalder 	void set_record_format(uint8 format) { _record_format = format; }
set_record_display_attributesfile_icb_entry2053ead0c3e2STyler Dauwalder 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
set_record_lengthfile_icb_entry2054ead0c3e2STyler Dauwalder 	void set_record_length(uint8 length) { _record_length = length; }
2055ead0c3e2STyler Dauwalder 
set_information_lengthfile_icb_entry2056ead0c3e2STyler Dauwalder 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
set_logical_blocks_recordedfile_icb_entry2057ead0c3e2STyler Dauwalder 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
2058ead0c3e2STyler Dauwalder 
set_checkpointfile_icb_entry2059ead0c3e2STyler Dauwalder 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
2060ead0c3e2STyler Dauwalder 
set_unique_idfile_icb_entry2061ead0c3e2STyler Dauwalder 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
2062ead0c3e2STyler Dauwalder 
set_extended_attributes_lengthfile_icb_entry2063ead0c3e2STyler Dauwalder 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
set_allocation_descriptors_lengthfile_icb_entry2064ead0c3e2STyler Dauwalder 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
2065ead0c3e2STyler Dauwalder 
2066e9927e2bSTyler Dauwalder 	// extended_file_icb_entry compatability functions
creation_date_and_timefile_icb_entry2067e9927e2bSTyler Dauwalder 	timestamp& creation_date_and_time() { return _attribute_date_and_time; }
creation_date_and_timefile_icb_entry2068e9927e2bSTyler Dauwalder 	const timestamp& creation_date_and_time() const { return _attribute_date_and_time; }
2069e9927e2bSTyler Dauwalder 
2070e9927e2bSTyler Dauwalder 
set_object_sizefile_icb_entry2071e9927e2bSTyler Dauwalder 	void set_object_size(uint64 size) { }
set_reservedfile_icb_entry2072e9927e2bSTyler Dauwalder 	void set_reserved(uint32 reserved) { }
stream_directory_icbfile_icb_entry2073e9927e2bSTyler Dauwalder 	long_address& stream_directory_icb() { return _dummy_stream_directory_icb; }
stream_directory_icbfile_icb_entry2074e9927e2bSTyler Dauwalder 	const long_address& stream_directory_icb() const { return _dummy_stream_directory_icb; }
2075e9927e2bSTyler Dauwalder 
2076e9927e2bSTyler Dauwalder 
2077ead0c3e2STyler Dauwalder private:
207810186d5dSTyler Dauwalder 	static const uint32 _descriptor_length = 176;
2079e9927e2bSTyler Dauwalder 	static long_address _dummy_stream_directory_icb;
_endfile_icb_entry208010186d5dSTyler Dauwalder 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
_endfile_icb_entry208110186d5dSTyler Dauwalder 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
208210186d5dSTyler Dauwalder 
2083ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
2084ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
2085ead0c3e2STyler Dauwalder 	uint32 _uid;
2086ead0c3e2STyler Dauwalder 	uint32 _gid;
2087ead0c3e2STyler Dauwalder 	/*! \todo List perms in comment and add handy union thingy */
2088ead0c3e2STyler Dauwalder 	uint32 _permissions;
2089ead0c3e2STyler Dauwalder 	/*! Identifies the number of file identifier descriptors referencing
2090ead0c3e2STyler Dauwalder 		this icb.
2091ead0c3e2STyler Dauwalder 	*/
2092ead0c3e2STyler Dauwalder 	uint16 _file_link_count;
2093ead0c3e2STyler Dauwalder 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
2094ead0c3e2STyler Dauwalder 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
2095ead0c3e2STyler Dauwalder 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
2096ead0c3e2STyler Dauwalder 	uint64 _information_length;
2097ead0c3e2STyler Dauwalder 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
2098ead0c3e2STyler Dauwalder 	timestamp _access_date_and_time;
2099ead0c3e2STyler Dauwalder 	timestamp _modification_date_and_time;
2100ead0c3e2STyler Dauwalder 
2101ead0c3e2STyler Dauwalder 	// NOTE: data members following this point in the descriptor are in
2102ead0c3e2STyler Dauwalder 	// different locations in extended file entries
2103ead0c3e2STyler Dauwalder 
2104ead0c3e2STyler Dauwalder 	timestamp _attribute_date_and_time;
2105ead0c3e2STyler Dauwalder 	/*! \brief Initially 1, may be incremented upon user request. */
2106ead0c3e2STyler Dauwalder 	uint32 _checkpoint;
2107ead0c3e2STyler Dauwalder 	long_address _extended_attribute_icb;
2108ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
2109ead0c3e2STyler Dauwalder 	/*! \brief The unique id identifying this file entry
2110ead0c3e2STyler Dauwalder 
2111ead0c3e2STyler Dauwalder 		The id of the root directory of a file set shall be 0.
2112ead0c3e2STyler Dauwalder 
2113ead0c3e2STyler Dauwalder 		\todo Detail the system specific requirements for unique ids from UDF-2.01
2114ead0c3e2STyler Dauwalder 	*/
2115ead0c3e2STyler Dauwalder 	uint64 _unique_id;
2116ead0c3e2STyler Dauwalder 	uint32 _extended_attributes_length;
2117ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptors_length;
2118ead0c3e2STyler Dauwalder 
2119ead0c3e2STyler Dauwalder };
2120ead0c3e2STyler Dauwalder 
2121ead0c3e2STyler Dauwalder 
2122ead0c3e2STyler Dauwalder /*! \brief Extended file ICB entry
2123ead0c3e2STyler Dauwalder 
2124ead0c3e2STyler Dauwalder 	See also: ECMA-167 4/14.17
2125ead0c3e2STyler Dauwalder 
2126ead0c3e2STyler Dauwalder 	\todo Check pointer math.
2127ead0c3e2STyler Dauwalder */
2128ead0c3e2STyler Dauwalder struct extended_file_icb_entry {
2129e631ed51STyler Dauwalder 	void dump() const;
descriptor_sizeextended_file_icb_entry213010186d5dSTyler Dauwalder 	uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
213110186d5dSTyler Dauwalder 	                                 +allocation_descriptors_length(); }
descriptor_nameextended_file_icb_entry2132e9927e2bSTyler Dauwalder 	const char* descriptor_name() const { return "extended_file_icb_entry"; }
2133e631ed51STyler Dauwalder 
2134ead0c3e2STyler Dauwalder 	// get functions
tagextended_file_icb_entry2135ead0c3e2STyler Dauwalder 	descriptor_tag & tag() { return _tag; }
tagextended_file_icb_entry2136ead0c3e2STyler Dauwalder 	const descriptor_tag & tag() const { return _tag; }
2137ead0c3e2STyler Dauwalder 
icb_tagextended_file_icb_entry2138ead0c3e2STyler Dauwalder 	icb_entry_tag& icb_tag() { return _icb_tag; }
icb_tagextended_file_icb_entry2139ead0c3e2STyler Dauwalder 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
2140ead0c3e2STyler Dauwalder 
uidextended_file_icb_entry2141e631ed51STyler Dauwalder 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
gidextended_file_icb_entry2142e631ed51STyler Dauwalder 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
permissionsextended_file_icb_entry2143e631ed51STyler Dauwalder 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
file_link_countextended_file_icb_entry2144e631ed51STyler Dauwalder 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
record_formatextended_file_icb_entry2145e631ed51STyler Dauwalder 	uint8 record_format() const { return _record_format; }
record_display_attributesextended_file_icb_entry2146e631ed51STyler Dauwalder 	uint8 record_display_attributes() const { return _record_display_attributes; }
record_lengthextended_file_icb_entry214710186d5dSTyler Dauwalder 	uint32 record_length() const { return _record_length; }
information_lengthextended_file_icb_entry2148e631ed51STyler Dauwalder 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
object_sizeextended_file_icb_entry214910186d5dSTyler Dauwalder 	uint64 object_size() const { return B_LENDIAN_TO_HOST_INT64(_object_size); }
logical_blocks_recordedextended_file_icb_entry2150e631ed51STyler Dauwalder 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
2151ead0c3e2STyler Dauwalder 
access_date_and_timeextended_file_icb_entry2152ead0c3e2STyler Dauwalder 	timestamp& access_date_and_time() { return _access_date_and_time; }
access_date_and_timeextended_file_icb_entry2153ead0c3e2STyler Dauwalder 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
2154ead0c3e2STyler Dauwalder 
modification_date_and_timeextended_file_icb_entry2155ead0c3e2STyler Dauwalder 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
modification_date_and_timeextended_file_icb_entry2156ead0c3e2STyler Dauwalder 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2157ead0c3e2STyler Dauwalder 
creation_date_and_timeextended_file_icb_entry2158e631ed51STyler Dauwalder 	timestamp& creation_date_and_time() { return _creation_date_and_time; }
creation_date_and_timeextended_file_icb_entry2159e631ed51STyler Dauwalder 	const timestamp& creation_date_and_time() const { return _creation_date_and_time; }
2160e631ed51STyler Dauwalder 
attribute_date_and_timeextended_file_icb_entry2161ead0c3e2STyler Dauwalder 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
attribute_date_and_timeextended_file_icb_entry2162ead0c3e2STyler Dauwalder 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2163ead0c3e2STyler Dauwalder 
checkpointextended_file_icb_entry2164e631ed51STyler Dauwalder 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2165ead0c3e2STyler Dauwalder 
extended_attribute_icbextended_file_icb_entry2166ead0c3e2STyler Dauwalder 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
extended_attribute_icbextended_file_icb_entry2167ead0c3e2STyler Dauwalder 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2168ead0c3e2STyler Dauwalder 
stream_directory_icbextended_file_icb_entry2169e631ed51STyler Dauwalder 	long_address& stream_directory_icb() { return _stream_directory_icb; }
stream_directory_icbextended_file_icb_entry2170e631ed51STyler Dauwalder 	const long_address& stream_directory_icb() const { return _stream_directory_icb; }
2171e631ed51STyler Dauwalder 
implementation_idextended_file_icb_entry2172ead0c3e2STyler Dauwalder 	entity_id& implementation_id() { return _implementation_id; }
implementation_idextended_file_icb_entry2173ead0c3e2STyler Dauwalder 	const entity_id& implementation_id() const { return _implementation_id; }
2174ead0c3e2STyler Dauwalder 
unique_idextended_file_icb_entry2175e631ed51STyler Dauwalder 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
extended_attributes_lengthextended_file_icb_entry2176e631ed51STyler Dauwalder 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
allocation_descriptors_lengthextended_file_icb_entry2177e631ed51STyler Dauwalder 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
2178ead0c3e2STyler Dauwalder 
extended_attributesextended_file_icb_entry217910186d5dSTyler Dauwalder 	uint8* extended_attributes() { return _end(); }
extended_attributesextended_file_icb_entry218010186d5dSTyler Dauwalder 	const uint8* extended_attributes() const { return _end(); }
allocation_descriptorsextended_file_icb_entry218110186d5dSTyler Dauwalder 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
allocation_descriptorsextended_file_icb_entry218210186d5dSTyler Dauwalder 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
2183ead0c3e2STyler Dauwalder 
2184ead0c3e2STyler Dauwalder 	// set functions
set_uidextended_file_icb_entry2185ead0c3e2STyler Dauwalder 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
set_gidextended_file_icb_entry2186ead0c3e2STyler Dauwalder 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
set_permissionsextended_file_icb_entry2187ead0c3e2STyler Dauwalder 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
2188ead0c3e2STyler Dauwalder 
set_file_link_countextended_file_icb_entry2189ead0c3e2STyler Dauwalder 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
set_record_formatextended_file_icb_entry2190ead0c3e2STyler Dauwalder 	void set_record_format(uint8 format) { _record_format = format; }
set_record_display_attributesextended_file_icb_entry2191ead0c3e2STyler Dauwalder 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
set_record_lengthextended_file_icb_entry219210186d5dSTyler Dauwalder 	void set_record_length(uint32 length) { _record_length = B_HOST_TO_LENDIAN_INT32(length); }
2193ead0c3e2STyler Dauwalder 
set_information_lengthextended_file_icb_entry2194ead0c3e2STyler Dauwalder 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
set_object_sizeextended_file_icb_entry219510186d5dSTyler Dauwalder 	void set_object_size(uint64 size) { _object_size = B_HOST_TO_LENDIAN_INT64(size); }
set_logical_blocks_recordedextended_file_icb_entry2196ead0c3e2STyler Dauwalder 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
2197ead0c3e2STyler Dauwalder 
set_checkpointextended_file_icb_entry2198ead0c3e2STyler Dauwalder 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
set_reservedextended_file_icb_entry2199e631ed51STyler Dauwalder 	void set_reserved(uint32 reserved) { _reserved = B_HOST_TO_LENDIAN_INT32(reserved); }
2200ead0c3e2STyler Dauwalder 
set_unique_idextended_file_icb_entry2201ead0c3e2STyler Dauwalder 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
2202ead0c3e2STyler Dauwalder 
set_extended_attributes_lengthextended_file_icb_entry2203ead0c3e2STyler Dauwalder 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
set_allocation_descriptors_lengthextended_file_icb_entry2204ead0c3e2STyler Dauwalder 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
2205ead0c3e2STyler Dauwalder 
2206ead0c3e2STyler Dauwalder private:
220710186d5dSTyler Dauwalder 	static const uint32 _descriptor_length = 216;
_endextended_file_icb_entry220810186d5dSTyler Dauwalder 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
_endextended_file_icb_entry220910186d5dSTyler Dauwalder 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
221010186d5dSTyler Dauwalder 
2211ead0c3e2STyler Dauwalder 	descriptor_tag  _tag;
2212ead0c3e2STyler Dauwalder 	icb_entry_tag _icb_tag;
2213ead0c3e2STyler Dauwalder 	uint32 _uid;
2214ead0c3e2STyler Dauwalder 	uint32 _gid;
2215ead0c3e2STyler Dauwalder 	/*! \todo List perms in comment and add handy union thingy */
2216ead0c3e2STyler Dauwalder 	uint32 _permissions;
2217ead0c3e2STyler Dauwalder 	/*! Identifies the number of file identifier descriptors referencing
2218ead0c3e2STyler Dauwalder 		this icb.
2219ead0c3e2STyler Dauwalder 	*/
2220ead0c3e2STyler Dauwalder 	uint16 _file_link_count;
2221ead0c3e2STyler Dauwalder 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
2222ead0c3e2STyler Dauwalder 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
222310186d5dSTyler Dauwalder 	uint32 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
2224ead0c3e2STyler Dauwalder 	uint64 _information_length;
222510186d5dSTyler Dauwalder 	uint64 _object_size;
2226ead0c3e2STyler Dauwalder 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
2227ead0c3e2STyler Dauwalder 	timestamp _access_date_and_time;
2228ead0c3e2STyler Dauwalder 	timestamp _modification_date_and_time;
2229ead0c3e2STyler Dauwalder 	timestamp _creation_date_and_time;	// <== EXTENDED FILE ENTRY ONLY
2230ead0c3e2STyler Dauwalder 	timestamp _attribute_date_and_time;
2231ead0c3e2STyler Dauwalder 	/*! \brief Initially 1, may be incremented upon user request. */
2232ead0c3e2STyler Dauwalder 	uint32 _checkpoint;
2233ead0c3e2STyler Dauwalder 	uint32 _reserved;	// <== EXTENDED FILE ENTRY ONLY
2234ead0c3e2STyler Dauwalder 	long_address _extended_attribute_icb;
2235ead0c3e2STyler Dauwalder 	long_address _stream_directory_icb;	// <== EXTENDED FILE ENTRY ONLY
2236ead0c3e2STyler Dauwalder 	entity_id _implementation_id;
2237ead0c3e2STyler Dauwalder 	/*! \brief The unique id identifying this file entry
2238ead0c3e2STyler Dauwalder 
2239ead0c3e2STyler Dauwalder 		The id of the root directory of a file set shall be 0.
2240ead0c3e2STyler Dauwalder 
2241ead0c3e2STyler Dauwalder 		\todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
2242ead0c3e2STyler Dauwalder 	*/
2243ead0c3e2STyler Dauwalder 	uint64 _unique_id;
2244ead0c3e2STyler Dauwalder 	uint32 _extended_attributes_length;
2245ead0c3e2STyler Dauwalder 	uint32 _allocation_descriptors_length;
2246ead0c3e2STyler Dauwalder 
2247ead0c3e2STyler Dauwalder };
2248ead0c3e2STyler Dauwalder 
2249ead0c3e2STyler Dauwalder 
2250ead0c3e2STyler Dauwalder #endif	// _UDF_DISK_STRUCTURES_H
2251ead0c3e2STyler Dauwalder 
2252