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