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