xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.h (revision 80b849abc742a2ae4310449d4c42c9f0c07076e1)
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 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_accessor().flags); }
481 	uint32 unique_id() const { return B_LENDIAN_TO_HOST_INT32(_accessor().unique_id); }
482 
483 	void set_type(uint8 type) {
484 		type_and_length_accessor t;
485 		t.type_and_length = type_and_length();
486 		t.bits.type = type;
487 		set_type_and_length(t.type_and_length);
488 	}
489 	void set_length(uint32 length) {
490 		type_and_length_accessor t;
491 		t.type_and_length = type_and_length();
492 		t.bits.length = length;
493 		set_type_and_length(t.type_and_length);
494 	}
495 	void set_block(uint32 block) { _location.set_block(block); }
496 	void set_partition(uint16 partition) { _location.set_partition(partition); }
497 
498 	void set_flags(uint16 flags) { _accessor().flags = B_HOST_TO_LENDIAN_INT16(flags); }
499 	void set_unique_id(uint32 id) { _accessor().unique_id = B_HOST_TO_LENDIAN_INT32(id); }
500 
501 	void set_to(uint32 block, uint16 partition, uint32 length = 1,
502 	       uint8 type = EXTENT_TYPE_RECORDED, uint16 flags = 0, uint32 unique_id = 0)
503 	{
504 		set_block(block);
505 		set_partition(partition);
506 		set_length(length);
507 		set_type(type);
508 		set_flags(flags);
509 		set_unique_id(unique_id);
510 	}
511 
512 private:
513 	//! See UDF-2.50 2.3.4.3
514 	struct _implementation_use_accessor {
515 		uint16 flags;
516 		uint32 unique_id;
517 	} __attribute__((packed));
518 
519 	_implementation_use_accessor& _accessor() { return
520 		*reinterpret_cast<_implementation_use_accessor*>(implementation_use().data); }
521 	const _implementation_use_accessor& _accessor() const { return
522 		*reinterpret_cast<const _implementation_use_accessor*>(implementation_use().data); }
523 
524 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
525 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
526 
527 	uint32 _type_and_length;
528 	logical_block_address _location;
529 	array<uint8, 6> _implementation_use;
530 } __attribute__((packed));
531 
532 /*! \brief Common tag found at the beginning of most udf descriptor structures.
533 
534 	For error checking, \c descriptor_tag  structures have:
535 	- The disk location of the tag redundantly stored in the tag itself
536 	- A checksum value for the tag
537 	- A CRC value and length
538 
539 	See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
540 */
541 struct descriptor_tag  {
542 public:
543 	void dump() const;
544 
545 	status_t init_check(uint32 block, bool calculateCrc = true);
546 
547 	uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); }
548 	uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); }
549 	uint8 checksum() const { return _checksum; }
550 	uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); }
551 	uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); }
552 	uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); }
553 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
554 
555 	void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); }
556 	void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); }
557 	void set_checksum(uint8 checksum) { _checksum = checksum; }
558 	void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); }
559 	void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); }
560 	void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); }
561 	void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
562 
563 	/*! \brief Calculates and sets the crc length, crc checksumm, and
564 		checksum for the tag.
565 
566 		This function should not be called until all member variables in
567 		the descriptor_tag's enclosing descriptor and all member variables
568 		in the descriptor_tag itself other than crc_length, crc, and checksum
569 		have been set (since the checksum is based off of values in the
570 		descriptor_tag, and the crc is based off the values in and the
571 		size of the	enclosing descriptor).
572 
573 		\param The tag's enclosing descriptor.
574 		\param The size of the tag's enclosing descriptor (including the
575 		       tag); only necessary if different from sizeof(Descriptor).
576 	*/
577 	template <class Descriptor>
578 	void
579 	set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
580 	{
581 
582 		// check that this tag is actually owned by
583 		// the given descriptor
584 		if (this == &descriptor.tag())
585 		{
586 			// crc_length, based off provided descriptor
587 			set_crc_length(size - sizeof(descriptor_tag));
588 			// crc
589 			uint16 crc = Udf::calculate_crc(reinterpret_cast<uint8*>(this)
590 			               + sizeof(descriptor_tag), crc_length());
591 			set_crc(crc);
592 			// checksum (which depends on the other two values)
593 			uint32 sum = 0;
594 			for (int i = 0; i <= 3; i++)
595 				sum += reinterpret_cast<uint8*>(this)[i];
596 			for (int i = 5; i <= 15; i++)
597 				sum += reinterpret_cast<uint8*>(this)[i];
598 			set_checksum(sum % 256);
599 		}
600 	}
601 private:
602 	uint16 _id;
603 	uint16 _version;
604 	uint8 _checksum;			//!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
605 	uint8 _reserved;			//!< Set to #00.
606 	uint16 _serial_number;
607 	uint16 _crc;				//!< May be 0 if \c crc_length field is 0.
608 	/*! \brief Length of the data chunk used to calculate CRC.
609 
610 		If 0, no CRC was calculated, and the \c crc field must be 0.
611 
612 		According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors
613 		unless otherwise noted, and this field shall be set to:
614 
615 		<code>(descriptor length) - (descriptor tag length)</code>
616 	*/
617 	uint16 _crc_length;
618 	/*! \brief Address of this tag within its partition (for error checking).
619 
620 		For virtually addressed structures (i.e. those accessed thru a VAT), this
621 		shall be the virtual address, not the physical or logical address.
622 	*/
623 	uint32 _location;
624 
625 } __attribute__((packed));
626 
627 
628 /*! \c descriptor_tag ::id values
629 */
630 enum tag_id {
631 	TAGID_UNDEFINED	= 0,
632 
633 	// ECMA 167, PART 3
634 	TAGID_PRIMARY_VOLUME_DESCRIPTOR,
635 	TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER,
636 	TAGID_VOLUME_DESCRIPTOR_POINTER,
637 	TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR,
638 	TAGID_PARTITION_DESCRIPTOR,
639 	TAGID_LOGICAL_VOLUME_DESCRIPTOR,
640 	TAGID_UNALLOCATED_SPACE_DESCRIPTOR,
641 	TAGID_TERMINATING_DESCRIPTOR,
642 	TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR,
643 
644 	TAGID_CUSTOM_START = 65280,
645 	TAGID_CUSTOM_END = 65535,
646 
647 	// ECMA 167, PART 4
648 	TAGID_FILE_SET_DESCRIPTOR = 256,
649 	TAGID_FILE_ID_DESCRIPTOR,
650 	TAGID_ALLOCATION_EXTENT_DESCRIPTOR,
651 	TAGID_INDIRECT_ENTRY,
652 	TAGID_TERMINAL_ENTRY,
653 	TAGID_FILE_ENTRY,
654 	TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR,
655 	TAGID_UNALLOCATED_SPACE_ENTRY,
656 	TAGID_SPACE_BITMAP_DESCRIPTOR,
657 	TAGID_PARTITION_INTEGRITY_ENTRY,
658 	TAGID_EXTENDED_FILE_ENTRY,
659 };
660 
661 const char *tag_id_to_string(tag_id id);
662 
663 extern const uint16 kCrcTable[256];
664 
665 /*! \brief Primary volume descriptor
666 */
667 struct primary_volume_descriptor {
668 public:
669 	void dump() const;
670 
671 	// Get functions
672 	const descriptor_tag & tag() const { return _tag; }
673 	descriptor_tag & tag() { return _tag; }
674 
675 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
676 	uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); }
677 
678 	const array<char, 32>& volume_identifier() const { return _volume_identifier; }
679 	array<char, 32>& volume_identifier() { return _volume_identifier; }
680 
681 	uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
682 	uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); }
683 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
684 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
685 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
686 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
687 
688 	const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
689 	array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
690 
691 	const charspec& descriptor_character_set() const { return _descriptor_character_set; }
692 	charspec& descriptor_character_set() { return _descriptor_character_set; }
693 
694 	const charspec& explanatory_character_set() const { return _explanatory_character_set; }
695 	charspec& explanatory_character_set() { return _explanatory_character_set; }
696 
697 	const extent_address& volume_abstract() const { return _volume_abstract; }
698 	extent_address& volume_abstract() { return _volume_abstract; }
699 	const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; }
700 	extent_address& volume_copyright_notice() { return _volume_copyright_notice; }
701 
702 	const entity_id& application_id() const { return _application_id; }
703 	entity_id& application_id() { return _application_id; }
704 
705 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
706 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
707 
708 	const entity_id& implementation_id() const { return _implementation_id; }
709 	entity_id& implementation_id() { return _implementation_id; }
710 
711 	const array<uint8, 64>& implementation_use() const { return _implementation_use; }
712 	array<uint8, 64>& implementation_use() { return _implementation_use; }
713 
714 	uint32 predecessor_volume_descriptor_sequence_location() const
715 	  { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); }
716 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
717 
718 	const array<uint8, 22>& reserved() const { return _reserved; }
719 	array<uint8, 22>& reserved() { return _reserved; }
720 
721 	// Set functions
722 	void set_vds_number(uint32 number)
723 	  { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
724 	void set_primary_volume_descriptor_number(uint32 number)
725 	  { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
726 	void set_volume_sequence_number(uint16 number)
727 	  { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
728 	void set_max_volume_sequence_number(uint16 number)
729 	  { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
730 	void set_interchange_level(uint16 level)
731 	  { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
732 	void set_max_interchange_level(uint16 level)
733 	  { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
734 	void set_character_set_list(uint32 list)
735 	  { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
736 	void set_max_character_set_list(uint32 list)
737 	  { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
738 	void set_predecessor_volume_descriptor_sequence_location(uint32 location)
739 	  { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); }
740 	void set_flags(uint16 flags)
741 	  { _flags = B_HOST_TO_LENDIAN_INT16(flags); }
742 
743 private:
744 	descriptor_tag  _tag;
745 	uint32 _vds_number;
746 	uint32 _primary_volume_descriptor_number;
747 	array<char, 32> _volume_identifier;
748 	uint16 _volume_sequence_number;
749 	uint16 _max_volume_sequence_number;
750 	uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
751 	uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
752 	uint32 _character_set_list;
753 	uint32 _max_character_set_list;
754 	array<char, 128> _volume_set_identifier;
755 
756 	/*! \brief Identifies the character set for the \c volume_identifier
757 		and \c volume_set_identifier fields.
758 
759 		To be set to CS0.
760 	*/
761 	charspec _descriptor_character_set;
762 
763 	/*! \brief Identifies the character set used in the \c volume_abstract
764 		and \c volume_copyright_notice extents.
765 
766 		To be set to CS0.
767 	*/
768 	charspec _explanatory_character_set;
769 
770 	extent_address _volume_abstract;
771 	extent_address _volume_copyright_notice;
772 
773 	entity_id _application_id;
774 	timestamp _recording_date_and_time;
775 	entity_id _implementation_id;
776 	array<uint8, 64> _implementation_use;
777 	uint32 _predecessor_volume_descriptor_sequence_location;
778 	uint16 _flags;
779 	array<uint8, 22> _reserved;
780 
781 } __attribute__((packed));
782 
783 
784 /*! \brief Anchor Volume Descriptor Pointer
785 
786 	vd recorded at preset locations in the partition, used as a reference
787 	point to the main vd sequences
788 
789 	According to UDF 2.01, an avdp shall be recorded in at least 2 of
790 	the 3 following locations, where N is the last recordable sector
791 	of the partition:
792 	- 256
793 	- (N - 256)
794 	- N
795 
796 	See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
797 */
798 struct anchor_volume_descriptor {
799 public:
800 	anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
801 	void dump() const;
802 
803 	descriptor_tag & tag() { return _tag; }
804 	const descriptor_tag & tag() const { return _tag; }
805 
806 	extent_address& main_vds() { return _main_vds; }
807 	const extent_address& main_vds() const { return _main_vds; }
808 
809 	extent_address& reserve_vds() { return _reserve_vds; }
810 	const extent_address& reserve_vds() const { return _reserve_vds; }
811 private:
812 	descriptor_tag  _tag;
813 	extent_address _main_vds;	//!< min length of 16 sectors
814 	extent_address _reserve_vds;	//!< min length of 16 sectors
815 	array<uint8, 480> _reserved;
816 } __attribute__((packed));
817 
818 
819 /*! \brief Volume Descriptor Pointer
820 
821 	Used to chain extents of volume descriptor sequences together.
822 
823 	See also: ECMA 167 3/10.3
824 */
825 struct descriptor_pointer {
826 	descriptor_tag  tag;
827 	uint32 vds_number;
828 	extent_address next;
829 } __attribute__((packed));
830 
831 
832 /*! \brief Implementation Use Volume Descriptor
833 
834 	See also: ECMA 167 3/10.4
835 */
836 struct implementation_use_descriptor {
837 public:
838 	void dump() const;
839 
840 	// Get functions
841 	const descriptor_tag & tag() const { return _tag; }
842 	descriptor_tag & tag() { return _tag; }
843 
844 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
845 
846 	const entity_id& implementation_id() const { return _implementation_id; }
847 	entity_id& implementation_id() { return _implementation_id; }
848 
849 	const array<uint8, 460>& implementation_use() const { return _implementation_use; }
850 	array<uint8, 460>& implementation_use() { return _implementation_use; }
851 
852 	// Set functions
853 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
854 private:
855 	descriptor_tag  _tag;
856 	uint32 _vds_number;
857 	entity_id _implementation_id;
858 	array<uint8, 460> _implementation_use;
859 } __attribute__((packed));
860 
861 
862 /*! \brief Maximum number of partition descriptors to be found in volume
863 	descriptor sequence, per UDF-2.50
864 */
865 extern const uint8 kMaxPartitionDescriptors;
866 #define UDF_MAX_PARTITION_MAPS 2
867 #define UDF_MAX_PARTITION_MAP_SIZE 64
868 
869 /*! \brief Partition Descriptor
870 
871 	See also: ECMA 167 3/10.5
872 */
873 struct partition_descriptor {
874 private:
875 	union partition_flags_accessor {
876 		uint16 partition_flags;
877 		struct {
878 			uint16 allocated:1,
879 			       reserved:15;
880 		} bits;
881 	};
882 
883 public:
884 	void dump() const;
885 
886 	// Get functions
887 	const descriptor_tag & tag() const { return _tag; }
888 	descriptor_tag & tag() { return _tag; }
889 
890 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
891 	uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); }
892 	bool allocated() const {
893 		partition_flags_accessor f;
894 		f.partition_flags = partition_flags();
895 		return f.bits.allocated;
896 	}
897 	uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
898 
899 	const entity_id& partition_contents() const { return _partition_contents; }
900 	entity_id& partition_contents() { return _partition_contents; }
901 
902 	const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
903 	array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
904 
905 	uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); }
906 	uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); }
907 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
908 
909 	const entity_id& implementation_id() const { return _implementation_id; }
910 	entity_id& implementation_id() { return _implementation_id; }
911 
912 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
913 	array<uint8, 128>& implementation_use() { return _implementation_use; }
914 
915 	const array<uint8, 156>& reserved() const { return _reserved; }
916 	array<uint8, 156>& reserved() { return _reserved; }
917 
918 	// Set functions
919 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
920 	void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); }
921 	void set_allocated(bool allocated) {
922 		partition_flags_accessor f;
923 		f.partition_flags = partition_flags();
924 		f.bits.allocated = allocated;
925 		set_partition_flags(f.partition_flags);
926 	}
927 	void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
928 	void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); }
929 	void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); }
930 	void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
931 
932 private:
933 	descriptor_tag  _tag;
934 	uint32 _vds_number;
935 	/*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
936 	    shall mean volume space has been allocated.
937 	*/
938 	uint16 _partition_flags;
939 	uint16 _partition_number;
940 
941 	/*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF
942 		- "+CD001" Volume recorded according to ECMA-119, i.e. iso9660
943 		- "+FDC01" Volume recorded according to ECMA-107
944 		- "+CDW02" Volume recorded according to ECMA-168
945 	*/
946 	entity_id _partition_contents;
947 	array<uint8, 128> _partition_contents_use;
948 
949 	/*! See \c partition_access_type enum
950 	*/
951 	uint32 _access_type;
952 	uint32 _start;
953 	uint32 _length;
954 	entity_id _implementation_id;
955 	array<uint8, 128> _implementation_use;
956 	array<uint8, 156> _reserved;
957 } __attribute__((packed));
958 
959 
960 enum partition_access_type {
961 	ACCESS_UNSPECIFIED,
962 	ACCESS_READ_ONLY,
963 	ACCESS_WRITE_ONCE,
964 	ACCESS_REWRITABLE,
965 	ACCESS_OVERWRITABLE,
966 };
967 
968 
969 /*! \brief Logical volume descriptor
970 
971 	See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
972 */
973 struct logical_volume_descriptor {
974 	void dump() const;
975 
976 	// Get functions
977 	const descriptor_tag & tag() const { return _tag; }
978 	descriptor_tag & tag() { return _tag; }
979 
980 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
981 
982 	const charspec& character_set() const { return _character_set; }
983 	charspec& character_set() { return _character_set; }
984 
985 	const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
986 	array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
987 
988 	uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
989 
990 	const entity_id& domain_id() const { return _domain_id; }
991 	entity_id& domain_id() { return _domain_id; }
992 
993 	const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
994 	array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; }
995 
996 	const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); }
997 	long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); }
998 
999 	uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); }
1000 	uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); }
1001 
1002 	const entity_id& implementation_id() const { return _implementation_id; }
1003 	entity_id& implementation_id() { return _implementation_id; }
1004 
1005 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
1006 	array<uint8, 128>& implementation_use() { return _implementation_use; }
1007 
1008 	const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
1009 	extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
1010 
1011 	const uint8* partition_maps() const { return _partition_maps; }
1012 	uint8* partition_maps() { return _partition_maps; }
1013 
1014 	// Set functions
1015 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1016 	void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); }
1017 
1018 	void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); }
1019 	void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); }
1020 
1021 	// Other functions
1022 	logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
1023 
1024 private:
1025 	descriptor_tag  _tag;
1026 	uint32 _vds_number;
1027 
1028 	/*! \brief Identifies the character set for the
1029 		\c logical_volume_identifier field.
1030 
1031 		To be set to CS0.
1032 	*/
1033 	charspec _character_set;
1034 	array<char, 128> _logical_volume_identifier;
1035 	uint32 _logical_block_size;
1036 
1037 	/*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
1038 	*/
1039 	entity_id _domain_id;
1040 
1041 	/*! \brief For UDF, shall contain a \c long_address which identifies
1042 		the location of the logical volume's first file set.
1043 	*/
1044 	array<uint8, 16> _logical_volume_contents_use;
1045 
1046 	uint32 _map_table_length;
1047 	uint32 _partition_map_count;
1048 	entity_id _implementation_id;
1049 	array<uint8, 128> _implementation_use;
1050 
1051 	/*! \brief Logical volume integrity sequence location.
1052 
1053 		For re/overwritable media, shall be a min of 8KB in length.
1054 		For WORM media, shall be quite frickin large, as a new volume
1055 		must be added to the set if the extent fills up (since you
1056 		can't chain lvis's I guess).
1057 	*/
1058 	extent_address _integrity_sequence_extent;
1059 
1060 	/*! \brief Restricted to maps of type 1 for normal maps and
1061 		UDF type 2 for virtual maps or maps on systems not supporting
1062 		defect management.
1063 
1064 		Note that we actually allocate memory for the partition maps
1065 		here due to the fact that we allocate logical_volume_descriptor
1066 		objects on the stack sometimes.
1067 
1068 		See UDF-2.01 2.2.8, 2.2.9
1069 	*/
1070 	uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1071 } __attribute__((packed));
1072 
1073 //! Base size (excluding partition maps) of lvd
1074 extern const uint32 kLogicalVolumeDescriptorBaseSize;
1075 
1076 /*! \brief (Mostly) common portion of various partition maps
1077 
1078 	See also: ECMA-167 3/10.7.1
1079 */
1080 struct partition_map_header {
1081 public:
1082 	uint8 type() const { return _type; }
1083 	uint8 length() const { return _length; }
1084 	uint8 *map_data() { return _map_data; }
1085 	const uint8 *map_data() const { return _map_data; }
1086 
1087 	entity_id& partition_type_id()
1088 		{ return *reinterpret_cast<entity_id*>(&_map_data[2]); }
1089 	const entity_id& partition_type_id() const
1090 		{ return *reinterpret_cast<const entity_id*>(&_map_data[2]); }
1091 
1092 	void set_type(uint8 type) { _type = type; }
1093 	void set_length(uint8 length) { _length = length; }
1094 private:
1095 	uint8 _type;
1096 	uint8 _length;
1097 	uint8 _map_data[0];
1098 };// __attribute__((packed));
1099 
1100 
1101 /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
1102 
1103 	See also: ECMA-167 3/10.7.2
1104 */
1105 struct physical_partition_map {
1106 public:
1107 	void dump();
1108 
1109 	uint8 type() const { return _type; }
1110 	uint8 length() const { return _length; }
1111 
1112 	uint16 volume_sequence_number() const {
1113 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1114 	uint16 partition_number() const {
1115 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1116 
1117 	void set_type(uint8 type) { _type = type; }
1118 	void set_length(uint8 length) { _length = length; }
1119 	void set_volume_sequence_number(uint16 number) {
1120 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1121 	void set_partition_number(uint16 number) {
1122 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1123 private:
1124 	uint8 _type;
1125 	uint8 _length;
1126 	uint16 _volume_sequence_number;
1127 	uint16 _partition_number;
1128 } __attribute__((packed));
1129 
1130 
1131 /* ----UDF Specific---- */
1132 /*! \brief Virtual partition map
1133 
1134 	Note that this map is a customization of the ECMA-167
1135 	type 2 partition map.
1136 
1137 	See also: UDF-2.01 2.2.8
1138 */
1139 struct virtual_partition_map {
1140 	uint8 type;
1141 	uint8 length;
1142 	uint8 reserved1[2];
1143 
1144 	/*! - flags: 0
1145 	    - identifier: "*UDF Virtual Partition"
1146 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1147 	*/
1148 	entity_id partition_type_id;
1149 	uint16 volume_sequence_number;
1150 
1151 	/*! corresponding type 1 partition map in same logical volume
1152 	*/
1153 	uint16 partition_number;
1154 	uint8 reserved2[24];
1155 } __attribute__((packed));
1156 
1157 
1158 /*! \brief Maximum number of redundant sparing tables found in
1159 	sparable_partition_map structures.
1160 */
1161 #define UDF_MAX_SPARING_TABLE_COUNT 4
1162 
1163 /* ----UDF Specific---- */
1164 /*! \brief Sparable partition map
1165 
1166 	Note that this map is a customization of the ECMA-167
1167 	type 2 partition map.
1168 
1169 	See also: UDF-2.01 2.2.9
1170 */
1171 struct sparable_partition_map {
1172 public:
1173 	void dump();
1174 
1175 	uint8 type() const { return _type; }
1176 	uint8 length() const { return _length; }
1177 
1178 	entity_id& partition_type_id() { return _partition_type_id; }
1179 	const entity_id& partition_type_id() const { return _partition_type_id; }
1180 
1181 	uint16 volume_sequence_number() const {
1182 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1183 	uint16 partition_number() const {
1184 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1185 	uint16 packet_length() const {
1186 		return B_LENDIAN_TO_HOST_INT16(_packet_length); }
1187 	uint8 sparing_table_count() const { return _sparing_table_count; }
1188 	uint32 sparing_table_size() const {
1189 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); }
1190 	uint32 sparing_table_location(uint8 index) const {
1191 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); }
1192 
1193 
1194 	void set_type(uint8 type) { _type = type; }
1195 	void set_length(uint8 length) { _length = length; }
1196 	void set_volume_sequence_number(uint16 number) {
1197 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1198 	void set_partition_number(uint16 number) {
1199 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1200 	void set_packet_length(uint16 length) {
1201 		_packet_length = B_HOST_TO_LENDIAN_INT16(length); }
1202 	void set_sparing_table_count(uint8 count) {
1203 		_sparing_table_count = count; }
1204 	void set_sparing_table_size(uint32 size) {
1205 		_sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
1206 	void set_sparing_table_location(uint8 index, uint32 location) {
1207 		_sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
1208 private:
1209 	uint8 _type;
1210 	uint8 _length;
1211 	uint8 _reserved1[2];
1212 
1213 	/*! - flags: 0
1214 	    - identifier: "*UDF Sparable Partition"
1215 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1216 	*/
1217 	entity_id _partition_type_id;
1218 	uint16 _volume_sequence_number;
1219 
1220 	//! partition number of corresponding partition descriptor
1221 	uint16 _partition_number;
1222 	uint16 _packet_length;
1223 	uint8 _sparing_table_count;
1224 	uint8 _reserved2;
1225 	uint32 _sparing_table_size;
1226 	uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT];
1227 } __attribute__((packed));
1228 
1229 
1230 /* ----UDF Specific---- */
1231 /*! \brief Metadata partition map
1232 
1233 	Note that this map is a customization of the ECMA-167
1234 	type 2 partition map.
1235 
1236 	See also: UDF-2.50 2.2.10
1237 */
1238 struct metadata_partition_map {
1239 	uint8 type;
1240 	uint8 length;
1241 	uint8 reserved1[2];
1242 
1243 	/*! - flags: 0
1244 	    - identifier: "*UDF Metadata Partition"
1245 	    - identifier_suffix: per UDF-2.50 2.1.5
1246 	*/
1247 	entity_id partition_type_id;
1248 	uint16 volume_sequence_number;
1249 
1250 	/*! corresponding type 1 or type 2 sparable partition
1251 	    map in same logical volume
1252 	*/
1253 	uint16 partition_number;
1254 	uint8 reserved2[24];
1255 } __attribute__((packed));
1256 
1257 
1258 /*! \brief Unallocated space descriptor
1259 
1260 	See also: ECMA-167 3/10.8
1261 */
1262 struct unallocated_space_descriptor {
1263 	void dump() const;
1264 
1265 	// Get functions
1266 	const descriptor_tag & tag() const { return _tag; }
1267 	descriptor_tag & tag() { return _tag; }
1268 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1269 	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
1270 	extent_address* allocation_descriptors() { return _allocation_descriptors; }
1271 
1272 	// Set functions
1273 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1274 	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1275 private:
1276 	descriptor_tag  _tag;
1277 	uint32 _vds_number;
1278 	uint32 _allocation_descriptor_count;
1279 	extent_address _allocation_descriptors[0];
1280 } __attribute__((packed));
1281 
1282 
1283 /*! \brief Terminating descriptor
1284 
1285 	See also: ECMA-167 3/10.9
1286 */
1287 struct terminating_descriptor {
1288 	terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
1289 	void dump() const;
1290 
1291 	// Get functions
1292 	const descriptor_tag & tag() const { return _tag; }
1293 	descriptor_tag & tag() { return _tag; }
1294 private:
1295 	descriptor_tag  _tag;
1296 	array<uint8, 496> _reserved;
1297 } __attribute__((packed));
1298 
1299 
1300 /*! \brief Logical volume integrity descriptor
1301 
1302 	See also: ECMA-167 3/10.10, UDF-2.50 2.2.6
1303 */
1304 struct logical_volume_integrity_descriptor {
1305 public:
1306 	static const uint32 minimum_implementation_use_length = 46;
1307 
1308 	void dump() const;
1309 	uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length()
1310 	                                 + partition_count()*sizeof(uint32)*2; }
1311 
1312 	descriptor_tag& tag() { return _tag; }
1313 	const descriptor_tag& tag() const { return _tag; }
1314 
1315 	timestamp& recording_time() { return _recording_time; }
1316 	const timestamp& recording_time() const { return _recording_time; }
1317 
1318 	uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); }
1319 
1320 	extent_address& next_integrity_extent() { return _next_integrity_extent; }
1321 	const extent_address& next_integrity_extent() const { return _next_integrity_extent; }
1322 
1323 	array<uint8, 32>& logical_volume_contents_use() { return _logical_volume_contents_use; }
1324 	const array<uint8, 32>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
1325 
1326 	// next_unique_id() field is actually stored in the logical_volume_contents_use()
1327 	// field, per UDF-2.50 3.2.1
1328 	uint64 next_unique_id() const { return B_LENDIAN_TO_HOST_INT64(_next_unique_id()); }
1329 
1330 	uint32 partition_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_count); }
1331 	uint32 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT32(_implementation_use_length); }
1332 
1333 	/*! \todo double-check the pointer arithmetic here. */
1334 	uint32* free_space_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(this)+80); }
1335 	const uint32* free_space_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(this)+80); }
1336 	uint32* size_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
1337 	const uint32* size_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
1338 	uint8* implementation_use() { return reinterpret_cast<uint8*>(reinterpret_cast<uint8*>(size_table())+partition_count()*sizeof(uint32)); }
1339 	const uint8* implementation_use() const { return reinterpret_cast<const uint8*>(reinterpret_cast<const uint8*>(size_table())+partition_count()*sizeof(uint32)); }
1340 
1341 	// accessors for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
1342 	entity_id& implementation_id() { return _accessor().id; }
1343 	const entity_id& implementation_id() const { return _accessor().id; }
1344 	uint32 file_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().file_count); }
1345 	uint32 directory_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().directory_count); }
1346 	uint16 minimum_udf_read_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_read_revision); }
1347 	uint16 minimum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_write_revision); }
1348 	uint16 maximum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().maximum_udf_write_revision); }
1349 
1350 	// set functions
1351 	void set_integrity_type(uint32 type) { _integrity_type = B_HOST_TO_LENDIAN_INT32(type); }
1352 	void set_next_unique_id(uint64 id) { _next_unique_id() = B_HOST_TO_LENDIAN_INT64(id); }
1353 	void set_partition_count(uint32 count) { _partition_count = B_HOST_TO_LENDIAN_INT32(count); }
1354 	void set_implementation_use_length(uint32 length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT32(length); }
1355 
1356 	// set functions for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
1357 	void set_file_count(uint32 count) { _accessor().file_count = B_HOST_TO_LENDIAN_INT32(count); }
1358 	void set_directory_count(uint32 count) { _accessor().directory_count = B_HOST_TO_LENDIAN_INT32(count); }
1359 	void set_minimum_udf_read_revision(uint16 revision) { _accessor().minimum_udf_read_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1360 	void set_minimum_udf_write_revision(uint16 revision) { _accessor().minimum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1361 	void set_maximum_udf_write_revision(uint16 revision) { _accessor().maximum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1362 
1363 private:
1364 	struct _lvid_implementation_use_accessor {
1365 		entity_id id;
1366 		uint32 file_count;
1367 		uint32 directory_count;
1368 		uint16 minimum_udf_read_revision;
1369 		uint16 minimum_udf_write_revision;
1370 		uint16 maximum_udf_write_revision;
1371 	};
1372 
1373 	_lvid_implementation_use_accessor& _accessor() {
1374 		return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use());
1375 	}
1376 	const _lvid_implementation_use_accessor& _accessor() const {
1377 		return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use());
1378 	}
1379 
1380 	uint64& _next_unique_id() { return *reinterpret_cast<uint64*>(logical_volume_contents_use().data); }
1381 	const uint64& _next_unique_id() const { return *reinterpret_cast<const uint64*>(logical_volume_contents_use().data); }
1382 
1383 	descriptor_tag  _tag;
1384 	timestamp _recording_time;
1385 	uint32 _integrity_type;
1386 	extent_address _next_integrity_extent;
1387 	array<uint8, 32> _logical_volume_contents_use;
1388 	uint32 _partition_count;
1389 	uint32 _implementation_use_length;
1390 
1391 } __attribute__((packed));
1392 
1393 /*! \brief Logical volume integrity types
1394 */
1395 enum {
1396 	INTEGRITY_OPEN = 0,
1397 	INTEGRITY_CLOSED = 1,
1398 };
1399 
1400 //----------------------------------------------------------------------
1401 // ECMA-167 Part 4
1402 //----------------------------------------------------------------------
1403 
1404 
1405 
1406 /*! \brief File set descriptor
1407 
1408 	Contains all the pertinent info about a file set (i.e. a hierarchy of files)
1409 
1410 	According to UDF-2.01, only one file set descriptor shall be recorded,
1411 	except on WORM media, where the following rules apply:
1412 	- Multiple file sets are allowed only on WORM media
1413 	- The default file set shall be the one with highest value \c file_set_number field.
1414 	- Only the default file set may be flagged as writeable. All others shall be
1415 	  flagged as "hard write protect".
1416 	- No writeable file set may reference metadata structures which are referenced
1417 	  (directly or indirectly) by any other file set. Writeable file sets may, however,
1418 	  reference actual file data extents that are also referenced by other file sets.
1419 */
1420 struct file_set_descriptor {
1421 	void dump() const;
1422 
1423 	// Get functions
1424 	const descriptor_tag & tag() const { return _tag; }
1425 	descriptor_tag & tag() { return _tag; }
1426 
1427 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
1428 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
1429 
1430 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
1431 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
1432 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
1433 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
1434 	uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); }
1435 	uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); }
1436 
1437 	const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; }
1438 	charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; }
1439 
1440 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
1441 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
1442 
1443 	const charspec& file_set_id_character_set() const { return _file_set_id_character_set; }
1444 	charspec& file_set_id_character_set() { return _file_set_id_character_set; }
1445 
1446 	const array<char, 32>& file_set_id() const { return _file_set_id; }
1447 	array<char, 32>& file_set_id() { return _file_set_id; }
1448 
1449 	const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
1450 	array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1451 
1452 	const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
1453 	array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1454 
1455 	const long_address& root_directory_icb() const { return _root_directory_icb; }
1456 	long_address& root_directory_icb() { return _root_directory_icb; }
1457 
1458 	const entity_id& domain_id() const { return _domain_id; }
1459 	entity_id& domain_id() { return _domain_id; }
1460 
1461 	const long_address& next_extent() const { return _next_extent; }
1462 	long_address& next_extent() { return _next_extent; }
1463 
1464 	const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; }
1465 	long_address& system_stream_directory_icb() { return _system_stream_directory_icb; }
1466 
1467 	const array<uint8, 32>& reserved() const { return _reserved; }
1468 	array<uint8, 32>& reserved() { return _reserved; }
1469 
1470 	// Set functions
1471 	void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1472 	void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1473 	void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1474 	void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1475 	void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
1476 	void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1477 private:
1478 	descriptor_tag  _tag;
1479 	timestamp _recording_date_and_time;
1480 	uint16 _interchange_level;			//!< To be set to 3 (see UDF-2.01 2.3.2.1)
1481 	uint16 _max_interchange_level;		//!< To be set to 3 (see UDF-2.01 2.3.2.2)
1482 	uint32 _character_set_list;
1483 	uint32 _max_character_set_list;
1484 	uint32 _file_set_number;
1485 	uint32 _file_set_descriptor_number;
1486 	charspec _logical_volume_id_character_set;	//!< To be set to kCSOCharspec
1487 	array<char, 128> _logical_volume_id;
1488 	charspec _file_set_id_character_set;
1489 	array<char, 32> _file_set_id;
1490 	array<char, 32> _copyright_file_id;
1491 	array<char, 32> _abstract_file_id;
1492 	long_address _root_directory_icb;
1493 	entity_id _domain_id;
1494 	long_address _next_extent;
1495 	long_address _system_stream_directory_icb;
1496 	array<uint8, 32> _reserved;
1497 } __attribute__((packed));
1498 
1499 
1500 /*! \brief Partition header descriptor
1501 
1502 	Contains references to unallocated and freed space data structures.
1503 
1504 	Note that unallocated space is space ready to be written with no
1505 	preprocessing. Freed space is space needing preprocessing (i.e.
1506 	a special write pass) before use.
1507 
1508 	Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent,
1509 	i.e. only one type or the other shall be used, not both.
1510 
1511 	To indicate disuse of a certain field, the fields of the allocation
1512 	descriptor shall all be set to 0.
1513 
1514 	See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1515 */
1516 struct partition_header_descriptor {
1517 	long_address unallocated_space_table;
1518 	long_address unallocated_space_bitmap;
1519 	/*! Unused, per UDF-2.01 2.2.3 */
1520 	long_address partition_integrity_table;
1521 	long_address freed_space_table;
1522 	long_address freed_space_bitmap;
1523 	uint8 reserved[88];
1524 } __attribute__((packed));
1525 
1526 #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1527 
1528 /*! \brief File identifier descriptor
1529 
1530 	Identifies the name of a file entry, and the location of its corresponding
1531 	ICB.
1532 
1533 	See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1534 
1535 	\todo Check pointer arithmetic
1536 */
1537 struct file_id_descriptor {
1538 public:
1539 	uint32 descriptor_size() const { return total_length(); }
1540 	void dump() const;
1541 
1542 	descriptor_tag & tag() { return _tag; }
1543 	const descriptor_tag & tag() const { return _tag; }
1544 
1545 	uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1546 
1547 	uint8 characteristics() const { return _characteristics; }
1548 
1549 	bool may_be_hidden() const {
1550 		characteristics_accessor c;
1551 		c.all = characteristics();
1552 		return c.bits.may_be_hidden;
1553 	}
1554 
1555 	bool is_directory() const {
1556 		characteristics_accessor c;
1557 		c.all = characteristics();
1558 		return c.bits.is_directory;
1559 	}
1560 
1561 	bool is_deleted() const {
1562 		characteristics_accessor c;
1563 		c.all = characteristics();
1564 		return c.bits.is_deleted;
1565 	}
1566 
1567 	bool is_parent() const {
1568 		characteristics_accessor c;
1569 		c.all = characteristics();
1570 		return c.bits.is_parent;
1571 	}
1572 
1573 	bool is_metadata_stream() const {
1574 		characteristics_accessor c;
1575 		c.all = characteristics();
1576 		return c.bits.is_metadata_stream;
1577 	}
1578 
1579 	uint8 id_length() const { return _id_length; }
1580 
1581 	long_address& icb() { return _icb; }
1582 	const long_address& icb() const { return _icb; }
1583 
1584 	uint16 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT16(_implementation_use_length); }
1585 
1586 	/*! If implementation_use_length is greater than 0, the first 32
1587 		bytes of implementation_use() shall be an entity_id identifying
1588 		the implementation that generated the rest of the data in the
1589 		implementation_use() field.
1590 	*/
1591 	uint8* implementation_use() { return ((uint8*)this)+(38); }
1592 	char* id() { return ((char*)this)+(38)+implementation_use_length(); }
1593 	const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); }
1594 
1595 	uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); }
1596 	uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); }
1597 	uint16 total_length() const { return structure_length() + padding_length(); }
1598 
1599 	// Set functions
1600 	void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1601 
1602 	void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
1603 
1604 	void set_may_be_hidden(bool how) {
1605 		characteristics_accessor c;
1606 		c.all = characteristics();
1607 		c.bits.may_be_hidden = how;
1608 		set_characteristics(c.all);
1609 	}
1610 
1611 	void set_is_directory(bool how) {
1612 		characteristics_accessor c;
1613 		c.all = characteristics();
1614 		c.bits.is_directory = how;
1615 		set_characteristics(c.all);
1616 	}
1617 
1618 	void set_is_deleted(bool how) {
1619 		characteristics_accessor c;
1620 		c.all = characteristics();
1621 		c.bits.is_deleted = how;
1622 		set_characteristics(c.all);
1623 	}
1624 
1625 	void set_is_parent(bool how) {
1626 		characteristics_accessor c;
1627 		c.all = characteristics();
1628 		c.bits.is_parent = how;
1629 		set_characteristics(c.all);
1630 	}
1631 
1632 	void set_is_metadata_stream(bool how) {
1633 		characteristics_accessor c;
1634 		c.all = characteristics();
1635 		c.bits.is_metadata_stream = how;
1636 		set_characteristics(c.all);
1637 	}
1638 
1639 
1640 	void set_id_length(uint8 id_length) { _id_length = id_length; }
1641 	void set_implementation_use_length(uint16 implementation_use_length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT16(implementation_use_length); }
1642 
1643 
1644 
1645 private:
1646 	union characteristics_accessor {
1647 		uint8 all;
1648 		struct {
1649 			uint8	may_be_hidden:1,
1650 					is_directory:1,
1651 					is_deleted:1,
1652 					is_parent:1,
1653 					is_metadata_stream:1,
1654 					reserved_characteristics:3;
1655 		} bits;
1656 	};
1657 
1658 	descriptor_tag  _tag;
1659 	/*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1660 
1661 		However, according to UDF-2.01, there shall be exactly one version of
1662 		a file, and it shall be 1.
1663 	 */
1664 	uint16 _version_number;
1665 	/*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */
1666 	uint8 _characteristics;
1667 	uint8 _id_length;
1668 	long_address _icb;
1669 	uint16 _implementation_use_length;
1670 } __attribute__((packed));
1671 
1672 
1673 /*! \brief Allocation extent descriptor
1674 
1675 	See also: ECMA-167 4/14.5
1676 */
1677 struct allocation_extent_descriptor {
1678 	descriptor_tag  tag;
1679 	uint32 previous_allocation_extent_location;
1680 	uint32 length_of_allocation_descriptors;
1681 
1682 	/*! \todo Check that this is really how things work: */
1683 	uint8* allocation_descriptors() { return (uint8*)(reinterpret_cast<uint8*>(this)+sizeof(allocation_extent_descriptor)); }
1684 } __attribute__((packed));
1685 
1686 
1687 /*! \brief icb_tag::file_type values
1688 
1689 	See also ECMA-167 4/14.6.6
1690 */
1691 enum icb_file_types {
1692 	ICB_TYPE_UNSPECIFIED = 0,
1693 	ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1694 	ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1695 	ICB_TYPE_INDIRECT_ENTRY,
1696 	ICB_TYPE_DIRECTORY,
1697 	ICB_TYPE_REGULAR_FILE,
1698 	ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1699 	ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1700 	ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1701 	ICB_TYPE_FIFO,
1702 	ICB_TYPE_ISSOCK,
1703 	ICB_TYPE_TERMINAL,
1704 	ICB_TYPE_SYMLINK,
1705 	ICB_TYPE_STREAM_DIRECTORY,
1706 
1707 	ICB_TYPE_RESERVED_START = 14,
1708 	ICB_TYPE_RESERVED_END = 247,
1709 
1710 	ICB_TYPE_CUSTOM_START = 248,
1711 	ICB_TYPE_CUSTOM_END = 255,
1712 };
1713 
1714 /*!	\brief idb_entry_tag::_flags::descriptor_flags() values
1715 
1716 	See also ECMA-167 4/14.6.8
1717 */
1718 enum icb_descriptor_types {
1719 	ICB_DESCRIPTOR_TYPE_SHORT = 0,
1720 	ICB_DESCRIPTOR_TYPE_LONG,
1721 	ICB_DESCRIPTOR_TYPE_EXTENDED,
1722 	ICB_DESCRIPTOR_TYPE_EMBEDDED,
1723 };
1724 
1725 /*!	\brief idb_entry_tag::strategy_type() values
1726 
1727 	See also UDF-2.50 2.3.5.1
1728 */
1729 enum icb_strategy_types {
1730 	ICB_STRATEGY_SINGLE = 4,
1731 	ICB_STRATEGY_LINKED_LIST = 4096
1732 };
1733 
1734 /*! \brief ICB entry tag
1735 
1736 	Common tag found in all ICB entries (in addition to, and immediately following,
1737 	the descriptor tag).
1738 
1739 	See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1740 */
1741 struct icb_entry_tag {
1742 public:
1743 	union flags_accessor {
1744 		uint16 all_flags;
1745 		struct {
1746 			uint16	descriptor_flags:3,
1747 					if_directory_then_sort:1,	//!< To be set to 0 per UDF-2.01 2.3.5.4
1748 					non_relocatable:1,
1749 					archive:1,
1750 					setuid:1,
1751 					setgid:1,
1752 					sticky:1,
1753 					contiguous:1,
1754 					system:1,
1755 					transformed:1,
1756 					multi_version:1,			//!< To be set to 0 per UDF-2.01 2.3.5.4
1757 					is_stream:1,
1758 					reserved_icb_entry_flags:2;
1759 		} flags;
1760 	};
1761 
1762 public:
1763 	void dump() const;
1764 
1765 	uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); }
1766 	uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); }
1767 
1768 	array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
1769 	const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
1770 
1771 	uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); }
1772 	uint8& reserved() { return _reserved; }
1773 	uint8 file_type() const { return _file_type; }
1774 	logical_block_address& parent_icb_location() { return _parent_icb_location; }
1775 	const logical_block_address& parent_icb_location() const { return _parent_icb_location; }
1776 
1777 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
1778 	flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); }
1779 
1780 	// flags accessor functions
1781 	uint8 descriptor_flags() const {
1782 		flags_accessor f;
1783 		f.all_flags = flags();
1784 		return f.flags.descriptor_flags;
1785 	}
1786 /*	void set_descriptor_flags(uint8 value) {
1787 		flags_accessor f;
1788 		f.all_flags = flags();
1789 		f.flags.descriptor_flags = value;
1790 		set_flags
1791 */
1792 
1793 	void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); }
1794 	void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); }
1795 
1796 	void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); }
1797 	void set_file_type(uint8 type) { _file_type = type; }
1798 
1799 	void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1800 
1801 private:
1802 	uint32 _prior_recorded_number_of_direct_entries;
1803 	/*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1804 
1805 		\todo Describe strategy types here.
1806 	*/
1807 	uint16 _strategy_type;
1808 	array<uint8, 2> _strategy_parameters;
1809 	uint16 _entry_count;
1810 	uint8 _reserved;
1811 	/*! \brief icb_file_type value identifying the type of this icb entry */
1812 	uint8 _file_type;
1813 	logical_block_address _parent_icb_location;
1814 	uint16 _flags;
1815 } __attribute__((packed));
1816 
1817 /*! \brief Header portion of an ICB entry.
1818 */
1819 struct icb_header {
1820 public:
1821 	void dump() const;
1822 
1823 	descriptor_tag  &tag() { return _tag; }
1824 	const descriptor_tag  &tag() const { return _tag; }
1825 
1826 	icb_entry_tag &icb_tag() { return _icb_tag; }
1827 	const icb_entry_tag &icb_tag() const { return _icb_tag; }
1828 private:
1829 	descriptor_tag  _tag;
1830 	icb_entry_tag _icb_tag;
1831 };
1832 
1833 /*! \brief Indirect ICB entry
1834 */
1835 struct indirect_icb_entry {
1836 	descriptor_tag  tag;
1837 	icb_entry_tag icb_tag;
1838 	long_address indirect_icb;
1839 } __attribute__((packed));
1840 
1841 
1842 /*! \brief Terminal ICB entry
1843 */
1844 struct terminal_icb_entry {
1845 	descriptor_tag  tag;
1846 	icb_entry_tag icb_tag;
1847 } __attribute__((packed));
1848 
1849 enum permissions {
1850 	OTHER_EXECUTE	 	= 0x0001,
1851 	OTHER_WRITE			= 0x0002,
1852 	OTHER_READ			= 0x0004,
1853 	OTHER_ATTRIBUTES	= 0x0008,
1854 	OTHER_DELETE		= 0x0010,
1855 	GROUP_EXECUTE	 	= 0x0020,
1856 	GROUP_WRITE			= 0x0040,
1857 	GROUP_READ			= 0x0080,
1858 	GROUP_ATTRIBUTES	= 0x0100,
1859 	GROUP_DELETE		= 0x0200,
1860 	USER_EXECUTE	 	= 0x0400,
1861 	USER_WRITE			= 0x0800,
1862 	USER_READ			= 0x1000,
1863 	USER_ATTRIBUTES		= 0x2000,
1864 	USER_DELETE			= 0x4000,
1865 };
1866 
1867 /*! \brief File ICB entry
1868 
1869 	See also: ECMA-167 4/14.9
1870 
1871 	\todo Check pointer math.
1872 */
1873 struct file_icb_entry {
1874 	void dump() const;
1875 
1876 	// get functions
1877 	descriptor_tag & tag() { return _tag; }
1878 	const descriptor_tag & tag() const { return _tag; }
1879 
1880 	icb_entry_tag& icb_tag() { return _icb_tag; }
1881 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
1882 
1883 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
1884 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
1885 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
1886 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
1887 	uint8 record_format() const { return _record_format; }
1888 	uint8 record_display_attributes() const { return _record_display_attributes; }
1889 	uint8 record_length() const { return _record_length; }
1890 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
1891 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
1892 
1893 	timestamp& access_date_and_time() { return _access_date_and_time; }
1894 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
1895 
1896 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
1897 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
1898 
1899 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
1900 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
1901 
1902 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
1903 
1904 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
1905 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
1906 
1907 	entity_id& implementation_id() { return _implementation_id; }
1908 	const entity_id& implementation_id() const { return _implementation_id; }
1909 
1910 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
1911 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
1912 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
1913 
1914 	uint8* extended_attributes() { return _end(); }
1915 	const uint8* extended_attributes() const { return _end(); }
1916 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
1917 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
1918 
1919 	// set functions
1920 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
1921 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
1922 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
1923 
1924 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
1925 	void set_record_format(uint8 format) { _record_format = format; }
1926 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
1927 	void set_record_length(uint8 length) { _record_length = length; }
1928 
1929 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
1930 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
1931 
1932 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
1933 
1934 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
1935 
1936 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
1937 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
1938 
1939 private:
1940 	static const uint32 _descriptor_length = 176;
1941 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
1942 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
1943 
1944 	descriptor_tag  _tag;
1945 	icb_entry_tag _icb_tag;
1946 	uint32 _uid;
1947 	uint32 _gid;
1948 	/*! \todo List perms in comment and add handy union thingy */
1949 	uint32 _permissions;
1950 	/*! Identifies the number of file identifier descriptors referencing
1951 		this icb.
1952 	*/
1953 	uint16 _file_link_count;
1954 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
1955 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
1956 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
1957 	uint64 _information_length;
1958 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
1959 	timestamp _access_date_and_time;
1960 	timestamp _modification_date_and_time;
1961 
1962 	// NOTE: data members following this point in the descriptor are in
1963 	// different locations in extended file entries
1964 
1965 	timestamp _attribute_date_and_time;
1966 	/*! \brief Initially 1, may be incremented upon user request. */
1967 	uint32 _checkpoint;
1968 	long_address _extended_attribute_icb;
1969 	entity_id _implementation_id;
1970 	/*! \brief The unique id identifying this file entry
1971 
1972 		The id of the root directory of a file set shall be 0.
1973 
1974 		\todo Detail the system specific requirements for unique ids from UDF-2.01
1975 	*/
1976 	uint64 _unique_id;
1977 	uint32 _extended_attributes_length;
1978 	uint32 _allocation_descriptors_length;
1979 
1980 };
1981 
1982 
1983 /*! \brief Extended file ICB entry
1984 
1985 	See also: ECMA-167 4/14.17
1986 
1987 	\todo Check pointer math.
1988 */
1989 struct extended_file_icb_entry {
1990 	void dump() const;
1991 	uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
1992 	                                 +allocation_descriptors_length(); }
1993 
1994 	// get functions
1995 	descriptor_tag & tag() { return _tag; }
1996 	const descriptor_tag & tag() const { return _tag; }
1997 
1998 	icb_entry_tag& icb_tag() { return _icb_tag; }
1999 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
2000 
2001 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
2002 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
2003 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
2004 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
2005 	uint8 record_format() const { return _record_format; }
2006 	uint8 record_display_attributes() const { return _record_display_attributes; }
2007 	uint32 record_length() const { return _record_length; }
2008 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
2009 	uint64 object_size() const { return B_LENDIAN_TO_HOST_INT64(_object_size); }
2010 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
2011 
2012 	timestamp& access_date_and_time() { return _access_date_and_time; }
2013 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
2014 
2015 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
2016 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2017 
2018 	timestamp& creation_date_and_time() { return _creation_date_and_time; }
2019 	const timestamp& creation_date_and_time() const { return _creation_date_and_time; }
2020 
2021 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
2022 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2023 
2024 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2025 
2026 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
2027 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2028 
2029 	long_address& stream_directory_icb() { return _stream_directory_icb; }
2030 	const long_address& stream_directory_icb() const { return _stream_directory_icb; }
2031 
2032 	entity_id& implementation_id() { return _implementation_id; }
2033 	const entity_id& implementation_id() const { return _implementation_id; }
2034 
2035 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
2036 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
2037 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
2038 
2039 	uint8* extended_attributes() { return _end(); }
2040 	const uint8* extended_attributes() const { return _end(); }
2041 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
2042 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
2043 
2044 	// set functions
2045 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
2046 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
2047 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
2048 
2049 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
2050 	void set_record_format(uint8 format) { _record_format = format; }
2051 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
2052 	void set_record_length(uint32 length) { _record_length = B_HOST_TO_LENDIAN_INT32(length); }
2053 
2054 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
2055 	void set_object_size(uint64 size) { _object_size = B_HOST_TO_LENDIAN_INT64(size); }
2056 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
2057 
2058 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
2059 	void set_reserved(uint32 reserved) { _reserved = B_HOST_TO_LENDIAN_INT32(reserved); }
2060 
2061 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
2062 
2063 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
2064 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
2065 
2066 private:
2067 	static const uint32 _descriptor_length = 216;
2068 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
2069 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
2070 
2071 	descriptor_tag  _tag;
2072 	icb_entry_tag _icb_tag;
2073 	uint32 _uid;
2074 	uint32 _gid;
2075 	/*! \todo List perms in comment and add handy union thingy */
2076 	uint32 _permissions;
2077 	/*! Identifies the number of file identifier descriptors referencing
2078 		this icb.
2079 	*/
2080 	uint16 _file_link_count;
2081 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
2082 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
2083 	uint32 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
2084 	uint64 _information_length;
2085 	uint64 _object_size;
2086 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
2087 	timestamp _access_date_and_time;
2088 	timestamp _modification_date_and_time;
2089 	timestamp _creation_date_and_time;	// <== EXTENDED FILE ENTRY ONLY
2090 	timestamp _attribute_date_and_time;
2091 	/*! \brief Initially 1, may be incremented upon user request. */
2092 	uint32 _checkpoint;
2093 	uint32 _reserved;	// <== EXTENDED FILE ENTRY ONLY
2094 	long_address _extended_attribute_icb;
2095 	long_address _stream_directory_icb;	// <== EXTENDED FILE ENTRY ONLY
2096 	entity_id _implementation_id;
2097 	/*! \brief The unique id identifying this file entry
2098 
2099 		The id of the root directory of a file set shall be 0.
2100 
2101 		\todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
2102 	*/
2103 	uint64 _unique_id;
2104 	uint32 _extended_attributes_length;
2105 	uint32 _allocation_descriptors_length;
2106 
2107 };
2108 
2109 
2110 };	// namespace Udf
2111 
2112 #endif	// _UDF_DISK_STRUCTURES_H
2113 
2114