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