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