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