xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.h (revision a3e794ae459fec76826407f8ba8c94cd3535f128)
1 /*
2  * Copyright 2012, Jérôme Duval, korli@users.berlios.de.
3  * Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
4  * This file may be used under the terms of the MIT License.
5  */
6 #ifndef _UDF_DISK_STRUCTURES_H
7 #define _UDF_DISK_STRUCTURES_H
8 
9 #include <string.h>
10 
11 #include <ByteOrder.h>
12 #include <SupportDefs.h>
13 
14 #include "UdfDebug.h"
15 #include "Utils.h"
16 
17 #include "Array.h"
18 
19 /*! \file UdfStructures.h
20 
21 	\brief UDF on-disk data structure declarations
22 
23 	UDF is a specialization of the ECMA-167 standard. For the most part,
24 	ECMA-167 structures are used by UDF with special restrictions. In a
25 	few instances, UDF introduces its own structures to augment those
26 	supplied by ECMA-167; those structures are clearly marked.
27 
28 	For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a>
29 	For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a>
30 
31 	For lack of a better place to store this info, the structures that
32 	are allowed to have length greater than the logical block size are
33 	as follows (other length restrictions may be found in UDF-2.01 5.1):
34 	- \c logical_volume_descriptor
35 	- \c unallocated_space_descriptor
36 	- \c logical_volume_integrity_descriptor
37 	- \c space_bitmap_descriptor
38 
39 	Other links of interest:
40 	- <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a>
41 	- <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a>
42 */
43 
44 //----------------------------------------------------------------------
45 // ECMA-167 Part 1
46 //----------------------------------------------------------------------
47 
48 /*! \brief Character set specifications
49 
50 	The character_set_info field shall be set to the ASCII string
51 	"OSTA Compressed Unicode" (padded right with NULL chars).
52 
53 	See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
54 */
55 struct charspec {
56 public:
57 	charspec(uint8 type = 0, const char *info = NULL);
58 
59 	void dump() const;
60 
61 	uint8 character_set_type() const { return _character_set_type; }
62 	const char* character_set_info() const { return _character_set_info; }
63 	char* character_set_info() { return _character_set_info; }
64 
65 	void set_character_set_type(uint8 type) { _character_set_type = type; }
66 	void set_character_set_info(const char *info);
67 private:
68 	uint8 _character_set_type;	//!< to be set to 0 to indicate CS0
69 	char _character_set_info[63];	//!< "OSTA Compressed Unicode"
70 } __attribute__((packed));
71 
72 extern const charspec kCs0CharacterSet;
73 
74 /*! \brief Date and time stamp
75 
76 	See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
77 */
78 class timestamp {
79 private:
80 	union type_and_timezone_accessor {
81 		uint16 type_and_timezone;
82 		struct {
83 			uint16 timezone:12,
84 			       type:4;
85 		} bits;
86 	};
87 
88 public:
89 	timestamp() { _clear(); }
90 	timestamp(time_t time);
91 
92 	void dump() const;
93 
94 	// Get functions
95 	uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); }
96 	uint8 type() const {
97 		type_and_timezone_accessor t;
98 		t.type_and_timezone = type_and_timezone();
99 		return t.bits.type;
100 	}
101 	int16 timezone() const {
102 		type_and_timezone_accessor t;
103 		t.type_and_timezone = type_and_timezone();
104 		int16 result = t.bits.timezone;
105 		// Fill the lefmost bits with ones if timezone is negative
106 		result <<= 4;
107 		result >>= 4;
108 		return result;
109 	}
110 	uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); }
111 	uint8 month() const { return _month; }
112 	uint8 day() const { return _day; }
113 	uint8 hour() const { return _hour; }
114 	uint8 minute() const { return _minute; }
115 	uint8 second() const { return _second; }
116 	uint8 centisecond() const { return _centisecond; }
117 	uint8 hundred_microsecond() const { return _hundred_microsecond; }
118 	uint8 microsecond() const { return _microsecond; }
119 
120 	// Set functions
121 	void set_type_and_timezone(uint16 type_and_timezone) {
122 		_type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
123 	void set_type(uint8 type) {
124 		type_and_timezone_accessor t;
125 		t.type_and_timezone = type_and_timezone();
126 		t.bits.type = type;
127 		set_type_and_timezone(t.type_and_timezone);
128 	}
129 	void set_timezone(int16 tz) {
130 		type_and_timezone_accessor t;
131 		t.type_and_timezone = type_and_timezone();
132 		t.bits.timezone = tz;
133 		set_type_and_timezone(t.type_and_timezone);
134 	}
135 	void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
136 	void set_month(uint8 month) { _month = month; }
137 	void set_day(uint8 day) { _day = day; }
138 	void set_hour(uint8 hour) { _hour = hour; }
139 	void set_minute(uint8 minute) { _minute = minute; }
140 	void set_second(uint8 second) { _second = second; }
141 	void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
142 	void set_hundred_microsecond(uint8 hundred_microsecond) {
143 		_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, const char *identifier = NULL,
269 	          uint8 *identifier_suffix = NULL);
270 	entity_id(uint8 flags, const char *identifier,
271 	          const udf_id_suffix &suffix);
272 	entity_id(uint8 flags, const char *identifier,
273 	          const implementation_id_suffix &suffix);
274 	entity_id(uint8 flags, const 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 entity_id kMetadataPartitionMapId;
296 extern entity_id kSparablePartitionMapId;
297 extern entity_id kVirtualPartitionMapId;
298 extern entity_id kImplementationId;
299 extern entity_id kPartitionContentsId1xx;
300 extern entity_id kPartitionContentsId2xx;
301 extern entity_id kUdfId;
302 extern entity_id kLogicalVolumeInfoId150;
303 extern entity_id kLogicalVolumeInfoId201;
304 extern entity_id kDomainId150;
305 extern entity_id kDomainId201;
306 extern void init_entities(void);
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 = 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 const uint8 kMaxPartitionDescriptors = 2;
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 public:
1311 	entity_id& partition_type_id() { return _partition_type_id; }
1312 	const entity_id& partition_type_id() const { return _partition_type_id; }
1313 
1314 	uint16 volume_sequence_number() const {
1315 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1316 	void set_volume_sequence_number(uint16 number) {
1317 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1318 
1319 	uint16 partition_number() const {
1320 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1321 	void set_partition_number(uint16 number) {
1322 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1323 
1324 	uint32 metadata_file_location() const {
1325 		return B_LENDIAN_TO_HOST_INT32(_metadata_file_location); }
1326 	void set_metadata_file_location(uint32 location) {
1327 		_metadata_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1328 
1329 	uint32 metadata_mirror_file_location() const {
1330 		return B_LENDIAN_TO_HOST_INT32(_metadata_mirror_file_location); }
1331 	void set_metadata_mirror_file_location(uint32 location) {
1332 		_metadata_mirror_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1333 
1334 	uint32 metadata_bitmap_file_location() const {
1335 		return B_LENDIAN_TO_HOST_INT32(_metadata_bitmap_file_location); }
1336 	void set_metadata_bitmap_file_location(uint32 location) {
1337 		_metadata_bitmap_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1338 
1339 	uint32 allocation_unit_size() const {
1340 		return B_LENDIAN_TO_HOST_INT32(_allocation_unit_size); }
1341 	void set_allocation_unit_size(uint32 size) {
1342 		_allocation_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1343 
1344 	uint32 alignment_unit_size() const {
1345 		return B_LENDIAN_TO_HOST_INT32(_alignment_unit_size); }
1346 	void set_alignment_unit_size(uint32 size) {
1347 		_alignment_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1348 
1349 	uint8 flags() const { return _flags; }
1350 	void set_flags(uint8 flags) { _flags = flags; }
1351 
1352 private:
1353 	uint8 type;
1354 	uint8 length;
1355 	uint8 reserved1[2];
1356 
1357 	/*! - flags: 0
1358 	    - identifier: "*UDF Metadata Partition"
1359 	    - identifier_suffix: per UDF-2.50 2.1.5
1360 	*/
1361 	entity_id _partition_type_id;
1362 	uint16 _volume_sequence_number;
1363 
1364 	/*! corresponding type 1 or type 2 sparable partition
1365 	    map in same logical volume
1366 	*/
1367 	uint16 _partition_number;
1368 	uint32 _metadata_file_location;
1369 	uint32 _metadata_mirror_file_location;
1370 	uint32 _metadata_bitmap_file_location;
1371 	uint32 _allocation_unit_size;
1372 	uint16 _alignment_unit_size;
1373 	uint8 _flags;
1374 	uint8 reserved2[5];
1375 } __attribute__((packed));
1376 
1377 
1378 /*! \brief Unallocated space descriptor
1379 
1380 	See also: ECMA-167 3/10.8
1381 */
1382 struct unallocated_space_descriptor {
1383 	void dump() const;
1384 
1385 	// Get functions
1386 	const descriptor_tag & tag() const { return _tag; }
1387 	descriptor_tag & tag() { return _tag; }
1388 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1389 	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
1390 	extent_address* allocation_descriptors() { return _allocation_descriptors; }
1391 
1392 	// Set functions
1393 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1394 	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1395 private:
1396 	descriptor_tag  _tag;
1397 	uint32 _vds_number;
1398 	uint32 _allocation_descriptor_count;
1399 	extent_address _allocation_descriptors[0];
1400 } __attribute__((packed));
1401 
1402 
1403 /*! \brief Terminating descriptor
1404 
1405 	See also: ECMA-167 3/10.9
1406 */
1407 struct terminating_descriptor {
1408 	terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
1409 	void dump() const;
1410 
1411 	// Get functions
1412 	const descriptor_tag & tag() const { return _tag; }
1413 	descriptor_tag & tag() { return _tag; }
1414 private:
1415 	descriptor_tag  _tag;
1416 	array<uint8, 496> _reserved;
1417 } __attribute__((packed));
1418 
1419 
1420 /*! \brief Logical volume integrity descriptor
1421 
1422 	See also: ECMA-167 3/10.10, UDF-2.50 2.2.6
1423 */
1424 struct logical_volume_integrity_descriptor {
1425 public:
1426 	static const uint32 minimum_implementation_use_length = 46;
1427 
1428 	void dump() const;
1429 	uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length()
1430 	                                 + partition_count()*sizeof(uint32)*2; }
1431 
1432 	descriptor_tag& tag() { return _tag; }
1433 	const descriptor_tag& tag() const { return _tag; }
1434 
1435 	timestamp& recording_time() { return _recording_time; }
1436 	const timestamp& recording_time() const { return _recording_time; }
1437 
1438 	uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); }
1439 
1440 	extent_address& next_integrity_extent() { return _next_integrity_extent; }
1441 	const extent_address& next_integrity_extent() const { return _next_integrity_extent; }
1442 
1443 	array<uint8, 32>& logical_volume_contents_use() { return _logical_volume_contents_use; }
1444 	const array<uint8, 32>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
1445 
1446 	// next_unique_id() field is actually stored in the logical_volume_contents_use()
1447 	// field, per UDF-2.50 3.2.1
1448 	uint64 next_unique_id() const { return B_LENDIAN_TO_HOST_INT64(_next_unique_id()); }
1449 
1450 	uint32 partition_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_count); }
1451 	uint32 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT32(_implementation_use_length); }
1452 
1453 	/*! \todo double-check the pointer arithmetic here. */
1454 	uint32* free_space_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(this)+80); }
1455 	const uint32* free_space_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(this)+80); }
1456 	uint32* size_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
1457 	const uint32* size_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(free_space_table())+partition_count()*sizeof(uint32)); }
1458 	uint8* implementation_use() { return reinterpret_cast<uint8*>(reinterpret_cast<uint8*>(size_table())+partition_count()*sizeof(uint32)); }
1459 	const uint8* implementation_use() const { return reinterpret_cast<const uint8*>(reinterpret_cast<const uint8*>(size_table())+partition_count()*sizeof(uint32)); }
1460 
1461 	// accessors for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
1462 	entity_id& implementation_id() { return _accessor().id; }
1463 	const entity_id& implementation_id() const { return _accessor().id; }
1464 	uint32 file_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().file_count); }
1465 	uint32 directory_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().directory_count); }
1466 	uint16 minimum_udf_read_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_read_revision); }
1467 	uint16 minimum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_write_revision); }
1468 	uint16 maximum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().maximum_udf_write_revision); }
1469 
1470 	// set functions
1471 	void set_integrity_type(uint32 type) { _integrity_type = B_HOST_TO_LENDIAN_INT32(type); }
1472 	void set_next_unique_id(uint64 id) { _next_unique_id() = B_HOST_TO_LENDIAN_INT64(id); }
1473 	void set_partition_count(uint32 count) { _partition_count = B_HOST_TO_LENDIAN_INT32(count); }
1474 	void set_implementation_use_length(uint32 length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT32(length); }
1475 
1476 	// set functions for fields stored in implementation_use() field per UDF-2.50 2.2.6.4
1477 	void set_file_count(uint32 count) { _accessor().file_count = B_HOST_TO_LENDIAN_INT32(count); }
1478 	void set_directory_count(uint32 count) { _accessor().directory_count = B_HOST_TO_LENDIAN_INT32(count); }
1479 	void set_minimum_udf_read_revision(uint16 revision) { _accessor().minimum_udf_read_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1480 	void set_minimum_udf_write_revision(uint16 revision) { _accessor().minimum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1481 	void set_maximum_udf_write_revision(uint16 revision) { _accessor().maximum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); }
1482 
1483 private:
1484 	struct _lvid_implementation_use_accessor {
1485 		entity_id id;
1486 		uint32 file_count;
1487 		uint32 directory_count;
1488 		uint16 minimum_udf_read_revision;
1489 		uint16 minimum_udf_write_revision;
1490 		uint16 maximum_udf_write_revision;
1491 	};
1492 
1493 	_lvid_implementation_use_accessor& _accessor() {
1494 		return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use());
1495 	}
1496 	const _lvid_implementation_use_accessor& _accessor() const {
1497 		return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use());
1498 	}
1499 
1500 	uint64& _next_unique_id() { return *reinterpret_cast<uint64*>(logical_volume_contents_use().data); }
1501 	const uint64& _next_unique_id() const { return *reinterpret_cast<const uint64*>(logical_volume_contents_use().data); }
1502 
1503 	descriptor_tag  _tag;
1504 	timestamp _recording_time;
1505 	uint32 _integrity_type;
1506 	extent_address _next_integrity_extent;
1507 	array<uint8, 32> _logical_volume_contents_use;
1508 	uint32 _partition_count;
1509 	uint32 _implementation_use_length;
1510 
1511 } __attribute__((packed));
1512 
1513 /*! \brief Logical volume integrity types
1514 */
1515 enum {
1516 	INTEGRITY_OPEN = 0,
1517 	INTEGRITY_CLOSED = 1,
1518 };
1519 
1520 /*! \brief Highest currently supported UDF read revision.
1521 */
1522 #define UDF_MAX_READ_REVISION 0x0250
1523 
1524 //----------------------------------------------------------------------
1525 // ECMA-167 Part 4
1526 //----------------------------------------------------------------------
1527 
1528 
1529 
1530 /*! \brief File set descriptor
1531 
1532 	Contains all the pertinent info about a file set (i.e. a hierarchy of files)
1533 
1534 	According to UDF-2.01, only one file set descriptor shall be recorded,
1535 	except on WORM media, where the following rules apply:
1536 	- Multiple file sets are allowed only on WORM media
1537 	- The default file set shall be the one with highest value \c file_set_number field.
1538 	- Only the default file set may be flagged as writeable. All others shall be
1539 	  flagged as "hard write protect".
1540 	- No writeable file set may reference metadata structures which are referenced
1541 	  (directly or indirectly) by any other file set. Writeable file sets may, however,
1542 	  reference actual file data extents that are also referenced by other file sets.
1543 */
1544 struct file_set_descriptor {
1545 	void dump() const;
1546 
1547 	// Get functions
1548 	const descriptor_tag & tag() const { return _tag; }
1549 	descriptor_tag & tag() { return _tag; }
1550 
1551 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
1552 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
1553 
1554 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
1555 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
1556 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
1557 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
1558 	uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); }
1559 	uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); }
1560 
1561 	const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; }
1562 	charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; }
1563 
1564 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
1565 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
1566 
1567 	const charspec& file_set_id_character_set() const { return _file_set_id_character_set; }
1568 	charspec& file_set_id_character_set() { return _file_set_id_character_set; }
1569 
1570 	const array<char, 32>& file_set_id() const { return _file_set_id; }
1571 	array<char, 32>& file_set_id() { return _file_set_id; }
1572 
1573 	const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
1574 	array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1575 
1576 	const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
1577 	array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1578 
1579 	const long_address& root_directory_icb() const { return _root_directory_icb; }
1580 	long_address& root_directory_icb() { return _root_directory_icb; }
1581 
1582 	const entity_id& domain_id() const { return _domain_id; }
1583 	entity_id& domain_id() { return _domain_id; }
1584 
1585 	const long_address& next_extent() const { return _next_extent; }
1586 	long_address& next_extent() { return _next_extent; }
1587 
1588 	const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; }
1589 	long_address& system_stream_directory_icb() { return _system_stream_directory_icb; }
1590 
1591 	const array<uint8, 32>& reserved() const { return _reserved; }
1592 	array<uint8, 32>& reserved() { return _reserved; }
1593 
1594 	// Set functions
1595 	void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1596 	void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1597 	void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1598 	void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1599 	void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
1600 	void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1601 private:
1602 	descriptor_tag  _tag;
1603 	timestamp _recording_date_and_time;
1604 	uint16 _interchange_level;			//!< To be set to 3 (see UDF-2.01 2.3.2.1)
1605 	uint16 _max_interchange_level;		//!< To be set to 3 (see UDF-2.01 2.3.2.2)
1606 	uint32 _character_set_list;
1607 	uint32 _max_character_set_list;
1608 	uint32 _file_set_number;
1609 	uint32 _file_set_descriptor_number;
1610 	charspec _logical_volume_id_character_set;	//!< To be set to kCSOCharspec
1611 	array<char, 128> _logical_volume_id;
1612 	charspec _file_set_id_character_set;
1613 	array<char, 32> _file_set_id;
1614 	array<char, 32> _copyright_file_id;
1615 	array<char, 32> _abstract_file_id;
1616 	long_address _root_directory_icb;
1617 	entity_id _domain_id;
1618 	long_address _next_extent;
1619 	long_address _system_stream_directory_icb;
1620 	array<uint8, 32> _reserved;
1621 } __attribute__((packed));
1622 
1623 
1624 /*! \brief Partition header descriptor
1625 
1626 	Contains references to unallocated and freed space data structures.
1627 
1628 	Note that unallocated space is space ready to be written with no
1629 	preprocessing. Freed space is space needing preprocessing (i.e.
1630 	a special write pass) before use.
1631 
1632 	Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent,
1633 	i.e. only one type or the other shall be used, not both.
1634 
1635 	To indicate disuse of a certain field, the fields of the allocation
1636 	descriptor shall all be set to 0.
1637 
1638 	See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1639 */
1640 struct partition_header_descriptor {
1641 	long_address unallocated_space_table;
1642 	long_address unallocated_space_bitmap;
1643 	/*! Unused, per UDF-2.01 2.2.3 */
1644 	long_address partition_integrity_table;
1645 	long_address freed_space_table;
1646 	long_address freed_space_bitmap;
1647 	uint8 reserved[88];
1648 } __attribute__((packed));
1649 
1650 #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1651 
1652 /*! \brief File identifier descriptor
1653 
1654 	Identifies the name of a file entry, and the location of its corresponding
1655 	ICB.
1656 
1657 	See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1658 
1659 	\todo Check pointer arithmetic
1660 */
1661 struct file_id_descriptor {
1662 public:
1663 	uint32 descriptor_size() const { return total_length(); }
1664 	void dump() const;
1665 
1666 	descriptor_tag & tag() { return _tag; }
1667 	const descriptor_tag & tag() const { return _tag; }
1668 
1669 	uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1670 
1671 	uint8 characteristics() const { return _characteristics; }
1672 
1673 	bool may_be_hidden() const {
1674 		characteristics_accessor c;
1675 		c.all = characteristics();
1676 		return c.bits.may_be_hidden;
1677 	}
1678 
1679 	bool is_directory() const {
1680 		characteristics_accessor c;
1681 		c.all = characteristics();
1682 		return c.bits.is_directory;
1683 	}
1684 
1685 	bool is_deleted() const {
1686 		characteristics_accessor c;
1687 		c.all = characteristics();
1688 		return c.bits.is_deleted;
1689 	}
1690 
1691 	bool is_parent() const {
1692 		characteristics_accessor c;
1693 		c.all = characteristics();
1694 		return c.bits.is_parent;
1695 	}
1696 
1697 	bool is_metadata_stream() const {
1698 		characteristics_accessor c;
1699 		c.all = characteristics();
1700 		return c.bits.is_metadata_stream;
1701 	}
1702 
1703 	uint8 id_length() const { return _id_length; }
1704 
1705 	long_address& icb() { return _icb; }
1706 	const long_address& icb() const { return _icb; }
1707 
1708 	uint16 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT16(_implementation_use_length); }
1709 
1710 	/*! If implementation_use_length is greater than 0, the first 32
1711 		bytes of implementation_use() shall be an entity_id identifying
1712 		the implementation that generated the rest of the data in the
1713 		implementation_use() field.
1714 	*/
1715 	uint8* implementation_use() { return ((uint8*)this)+(38); }
1716 	char* id() { return ((char*)this)+(38)+implementation_use_length(); }
1717 	const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); }
1718 
1719 	uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); }
1720 	uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); }
1721 	uint16 total_length() const { return structure_length() + padding_length(); }
1722 
1723 	// Set functions
1724 	void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1725 
1726 	void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
1727 
1728 	void set_may_be_hidden(bool how) {
1729 		characteristics_accessor c;
1730 		c.all = characteristics();
1731 		c.bits.may_be_hidden = how;
1732 		set_characteristics(c.all);
1733 	}
1734 
1735 	void set_is_directory(bool how) {
1736 		characteristics_accessor c;
1737 		c.all = characteristics();
1738 		c.bits.is_directory = how;
1739 		set_characteristics(c.all);
1740 	}
1741 
1742 	void set_is_deleted(bool how) {
1743 		characteristics_accessor c;
1744 		c.all = characteristics();
1745 		c.bits.is_deleted = how;
1746 		set_characteristics(c.all);
1747 	}
1748 
1749 	void set_is_parent(bool how) {
1750 		characteristics_accessor c;
1751 		c.all = characteristics();
1752 		c.bits.is_parent = how;
1753 		set_characteristics(c.all);
1754 	}
1755 
1756 	void set_is_metadata_stream(bool how) {
1757 		characteristics_accessor c;
1758 		c.all = characteristics();
1759 		c.bits.is_metadata_stream = how;
1760 		set_characteristics(c.all);
1761 	}
1762 
1763 
1764 	void set_id_length(uint8 id_length) { _id_length = id_length; }
1765 	void set_implementation_use_length(uint16 implementation_use_length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT16(implementation_use_length); }
1766 
1767 
1768 
1769 private:
1770 	union characteristics_accessor {
1771 		uint8 all;
1772 		struct {
1773 			uint8	may_be_hidden:1,
1774 					is_directory:1,
1775 					is_deleted:1,
1776 					is_parent:1,
1777 					is_metadata_stream:1,
1778 					reserved_characteristics:3;
1779 		} bits;
1780 	};
1781 
1782 	descriptor_tag  _tag;
1783 	/*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1784 
1785 		However, according to UDF-2.01, there shall be exactly one version of
1786 		a file, and it shall be 1.
1787 	 */
1788 	uint16 _version_number;
1789 	/*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */
1790 	uint8 _characteristics;
1791 	uint8 _id_length;
1792 	long_address _icb;
1793 	uint16 _implementation_use_length;
1794 } __attribute__((packed));
1795 
1796 
1797 /*! \brief Allocation extent descriptor
1798 
1799 	See also: ECMA-167 4/14.5
1800 */
1801 struct allocation_extent_descriptor {
1802 	descriptor_tag  tag;
1803 	uint32 previous_allocation_extent_location;
1804 	uint32 length_of_allocation_descriptors;
1805 
1806 	/*! \todo Check that this is really how things work: */
1807 	uint8* allocation_descriptors() { return (uint8*)(reinterpret_cast<uint8*>(this)+sizeof(allocation_extent_descriptor)); }
1808 } __attribute__((packed));
1809 
1810 
1811 /*! \brief icb_tag::file_type values
1812 
1813 	See also ECMA-167 4/14.6.6
1814 */
1815 enum icb_file_types {
1816 	ICB_TYPE_UNSPECIFIED = 0,
1817 	ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1818 	ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1819 	ICB_TYPE_INDIRECT_ENTRY,
1820 	ICB_TYPE_DIRECTORY,
1821 	ICB_TYPE_REGULAR_FILE,
1822 	ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1823 	ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1824 	ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1825 	ICB_TYPE_FIFO,
1826 	ICB_TYPE_ISSOCK,
1827 	ICB_TYPE_TERMINAL,
1828 	ICB_TYPE_SYMLINK,
1829 	ICB_TYPE_STREAM_DIRECTORY,
1830 
1831 	ICB_TYPE_RESERVED_START = 14,
1832 	ICB_TYPE_RESERVED_END = 247,
1833 
1834 	ICB_TYPE_CUSTOM_START = 248,
1835 	ICB_TYPE_CUSTOM_END = 255,
1836 };
1837 
1838 /*!	\brief idb_entry_tag::_flags::descriptor_flags() values
1839 
1840 	See also ECMA-167 4/14.6.8
1841 */
1842 enum icb_descriptor_types {
1843 	ICB_DESCRIPTOR_TYPE_SHORT = 0,
1844 	ICB_DESCRIPTOR_TYPE_LONG,
1845 	ICB_DESCRIPTOR_TYPE_EXTENDED,
1846 	ICB_DESCRIPTOR_TYPE_EMBEDDED,
1847 };
1848 
1849 /*!	\brief idb_entry_tag::strategy_type() values
1850 
1851 	See also UDF-2.50 2.3.5.1
1852 */
1853 enum icb_strategy_types {
1854 	ICB_STRATEGY_SINGLE = 4,
1855 	ICB_STRATEGY_LINKED_LIST = 4096
1856 };
1857 
1858 /*! \brief ICB entry tag
1859 
1860 	Common tag found in all ICB entries (in addition to, and immediately following,
1861 	the descriptor tag).
1862 
1863 	See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1864 */
1865 struct icb_entry_tag {
1866 public:
1867 	union flags_accessor {
1868 		uint16 all_flags;
1869 		struct {
1870 			uint16	descriptor_flags:3,
1871 					if_directory_then_sort:1,	//!< To be set to 0 per UDF-2.01 2.3.5.4
1872 					non_relocatable:1,
1873 					archive:1,
1874 					setuid:1,
1875 					setgid:1,
1876 					sticky:1,
1877 					contiguous:1,
1878 					system:1,
1879 					transformed:1,
1880 					multi_version:1,			//!< To be set to 0 per UDF-2.01 2.3.5.4
1881 					is_stream:1,
1882 					reserved_icb_entry_flags:2;
1883 		} flags;
1884 	};
1885 
1886 public:
1887 	void dump() const;
1888 
1889 	uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); }
1890 	uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); }
1891 
1892 	array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
1893 	const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
1894 
1895 	uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); }
1896 	uint8& reserved() { return _reserved; }
1897 	uint8 file_type() const { return _file_type; }
1898 	logical_block_address& parent_icb_location() { return _parent_icb_location; }
1899 	const logical_block_address& parent_icb_location() const { return _parent_icb_location; }
1900 
1901 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
1902 	flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); }
1903 
1904 	// flags accessor functions
1905 	uint8 descriptor_flags() const {
1906 		flags_accessor f;
1907 		f.all_flags = flags();
1908 		return f.flags.descriptor_flags;
1909 	}
1910 /*	void set_descriptor_flags(uint8 value) {
1911 		flags_accessor f;
1912 		f.all_flags = flags();
1913 		f.flags.descriptor_flags = value;
1914 		set_flags
1915 */
1916 
1917 	void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); }
1918 	void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); }
1919 
1920 	void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); }
1921 	void set_file_type(uint8 type) { _file_type = type; }
1922 
1923 	void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1924 
1925 private:
1926 	uint32 _prior_recorded_number_of_direct_entries;
1927 	/*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1928 
1929 		\todo Describe strategy types here.
1930 	*/
1931 	uint16 _strategy_type;
1932 	array<uint8, 2> _strategy_parameters;
1933 	uint16 _entry_count;
1934 	uint8 _reserved;
1935 	/*! \brief icb_file_type value identifying the type of this icb entry */
1936 	uint8 _file_type;
1937 	logical_block_address _parent_icb_location;
1938 	uint16 _flags;
1939 } __attribute__((packed));
1940 
1941 /*! \brief Header portion of an ICB entry.
1942 */
1943 struct icb_header {
1944 public:
1945 	void dump() const;
1946 
1947 	descriptor_tag  &tag() { return _tag; }
1948 	const descriptor_tag  &tag() const { return _tag; }
1949 
1950 	icb_entry_tag &icb_tag() { return _icb_tag; }
1951 	const icb_entry_tag &icb_tag() const { return _icb_tag; }
1952 private:
1953 	descriptor_tag  _tag;
1954 	icb_entry_tag _icb_tag;
1955 };
1956 
1957 /*! \brief Indirect ICB entry
1958 */
1959 struct indirect_icb_entry {
1960 	descriptor_tag  tag;
1961 	icb_entry_tag icb_tag;
1962 	long_address indirect_icb;
1963 } __attribute__((packed));
1964 
1965 
1966 /*! \brief Terminal ICB entry
1967 */
1968 struct terminal_icb_entry {
1969 	descriptor_tag  tag;
1970 	icb_entry_tag icb_tag;
1971 } __attribute__((packed));
1972 
1973 enum permissions {
1974 	OTHER_EXECUTE	 	= 0x0001,
1975 	OTHER_WRITE			= 0x0002,
1976 	OTHER_READ			= 0x0004,
1977 	OTHER_ATTRIBUTES	= 0x0008,
1978 	OTHER_DELETE		= 0x0010,
1979 	GROUP_EXECUTE	 	= 0x0020,
1980 	GROUP_WRITE			= 0x0040,
1981 	GROUP_READ			= 0x0080,
1982 	GROUP_ATTRIBUTES	= 0x0100,
1983 	GROUP_DELETE		= 0x0200,
1984 	USER_EXECUTE	 	= 0x0400,
1985 	USER_WRITE			= 0x0800,
1986 	USER_READ			= 0x1000,
1987 	USER_ATTRIBUTES		= 0x2000,
1988 	USER_DELETE			= 0x4000,
1989 };
1990 
1991 /*! \brief File ICB entry
1992 
1993 	See also: ECMA-167 4/14.9
1994 
1995 	\todo Check pointer math.
1996 */
1997 struct file_icb_entry {
1998 	void dump() const;
1999 	uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
2000 	                                 +allocation_descriptors_length(); }
2001 	const char* descriptor_name() const { return "file_icb_entry"; }
2002 
2003 	// get functions
2004 	descriptor_tag & tag() { return _tag; }
2005 	const descriptor_tag & tag() const { return _tag; }
2006 
2007 	icb_entry_tag& icb_tag() { return _icb_tag; }
2008 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
2009 
2010 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
2011 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
2012 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
2013 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
2014 	uint8 record_format() const { return _record_format; }
2015 	uint8 record_display_attributes() const { return _record_display_attributes; }
2016 	uint8 record_length() const { return _record_length; }
2017 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
2018 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
2019 
2020 	timestamp& access_date_and_time() { return _access_date_and_time; }
2021 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
2022 
2023 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
2024 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2025 
2026 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
2027 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2028 
2029 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2030 
2031 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
2032 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2033 
2034 	entity_id& implementation_id() { return _implementation_id; }
2035 	const entity_id& implementation_id() const { return _implementation_id; }
2036 
2037 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
2038 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
2039 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
2040 
2041 	uint8* extended_attributes() { return _end(); }
2042 	const uint8* extended_attributes() const { return _end(); }
2043 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
2044 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
2045 
2046 	// set functions
2047 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
2048 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
2049 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
2050 
2051 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
2052 	void set_record_format(uint8 format) { _record_format = format; }
2053 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
2054 	void set_record_length(uint8 length) { _record_length = length; }
2055 
2056 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
2057 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
2058 
2059 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
2060 
2061 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
2062 
2063 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
2064 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
2065 
2066 	// extended_file_icb_entry compatability functions
2067 	timestamp& creation_date_and_time() { return _attribute_date_and_time; }
2068 	const timestamp& creation_date_and_time() const { return _attribute_date_and_time; }
2069 
2070 
2071 	void set_object_size(uint64 size) { }
2072 	void set_reserved(uint32 reserved) { }
2073 	long_address& stream_directory_icb() { return _dummy_stream_directory_icb; }
2074 	const long_address& stream_directory_icb() const { return _dummy_stream_directory_icb; }
2075 
2076 
2077 private:
2078 	static const uint32 _descriptor_length = 176;
2079 	static long_address _dummy_stream_directory_icb;
2080 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
2081 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
2082 
2083 	descriptor_tag  _tag;
2084 	icb_entry_tag _icb_tag;
2085 	uint32 _uid;
2086 	uint32 _gid;
2087 	/*! \todo List perms in comment and add handy union thingy */
2088 	uint32 _permissions;
2089 	/*! Identifies the number of file identifier descriptors referencing
2090 		this icb.
2091 	*/
2092 	uint16 _file_link_count;
2093 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
2094 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
2095 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
2096 	uint64 _information_length;
2097 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
2098 	timestamp _access_date_and_time;
2099 	timestamp _modification_date_and_time;
2100 
2101 	// NOTE: data members following this point in the descriptor are in
2102 	// different locations in extended file entries
2103 
2104 	timestamp _attribute_date_and_time;
2105 	/*! \brief Initially 1, may be incremented upon user request. */
2106 	uint32 _checkpoint;
2107 	long_address _extended_attribute_icb;
2108 	entity_id _implementation_id;
2109 	/*! \brief The unique id identifying this file entry
2110 
2111 		The id of the root directory of a file set shall be 0.
2112 
2113 		\todo Detail the system specific requirements for unique ids from UDF-2.01
2114 	*/
2115 	uint64 _unique_id;
2116 	uint32 _extended_attributes_length;
2117 	uint32 _allocation_descriptors_length;
2118 
2119 };
2120 
2121 
2122 /*! \brief Extended file ICB entry
2123 
2124 	See also: ECMA-167 4/14.17
2125 
2126 	\todo Check pointer math.
2127 */
2128 struct extended_file_icb_entry {
2129 	void dump() const;
2130 	uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
2131 	                                 +allocation_descriptors_length(); }
2132 	const char* descriptor_name() const { return "extended_file_icb_entry"; }
2133 
2134 	// get functions
2135 	descriptor_tag & tag() { return _tag; }
2136 	const descriptor_tag & tag() const { return _tag; }
2137 
2138 	icb_entry_tag& icb_tag() { return _icb_tag; }
2139 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
2140 
2141 	uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); }
2142 	uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); }
2143 	uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); }
2144 	uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
2145 	uint8 record_format() const { return _record_format; }
2146 	uint8 record_display_attributes() const { return _record_display_attributes; }
2147 	uint32 record_length() const { return _record_length; }
2148 	uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); }
2149 	uint64 object_size() const { return B_LENDIAN_TO_HOST_INT64(_object_size); }
2150 	uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
2151 
2152 	timestamp& access_date_and_time() { return _access_date_and_time; }
2153 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
2154 
2155 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
2156 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2157 
2158 	timestamp& creation_date_and_time() { return _creation_date_and_time; }
2159 	const timestamp& creation_date_and_time() const { return _creation_date_and_time; }
2160 
2161 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
2162 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2163 
2164 	uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2165 
2166 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
2167 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2168 
2169 	long_address& stream_directory_icb() { return _stream_directory_icb; }
2170 	const long_address& stream_directory_icb() const { return _stream_directory_icb; }
2171 
2172 	entity_id& implementation_id() { return _implementation_id; }
2173 	const entity_id& implementation_id() const { return _implementation_id; }
2174 
2175 	uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
2176 	uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
2177 	uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
2178 
2179 	uint8* extended_attributes() { return _end(); }
2180 	const uint8* extended_attributes() const { return _end(); }
2181 	uint8* allocation_descriptors() { return _end()+extended_attributes_length(); }
2182 	const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); }
2183 
2184 	// set functions
2185 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
2186 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
2187 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
2188 
2189 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
2190 	void set_record_format(uint8 format) { _record_format = format; }
2191 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
2192 	void set_record_length(uint32 length) { _record_length = B_HOST_TO_LENDIAN_INT32(length); }
2193 
2194 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
2195 	void set_object_size(uint64 size) { _object_size = B_HOST_TO_LENDIAN_INT64(size); }
2196 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
2197 
2198 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
2199 	void set_reserved(uint32 reserved) { _reserved = B_HOST_TO_LENDIAN_INT32(reserved); }
2200 
2201 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
2202 
2203 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
2204 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
2205 
2206 private:
2207 	static const uint32 _descriptor_length = 216;
2208 	uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
2209 	const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
2210 
2211 	descriptor_tag  _tag;
2212 	icb_entry_tag _icb_tag;
2213 	uint32 _uid;
2214 	uint32 _gid;
2215 	/*! \todo List perms in comment and add handy union thingy */
2216 	uint32 _permissions;
2217 	/*! Identifies the number of file identifier descriptors referencing
2218 		this icb.
2219 	*/
2220 	uint16 _file_link_count;
2221 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
2222 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
2223 	uint32 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
2224 	uint64 _information_length;
2225 	uint64 _object_size;
2226 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
2227 	timestamp _access_date_and_time;
2228 	timestamp _modification_date_and_time;
2229 	timestamp _creation_date_and_time;	// <== EXTENDED FILE ENTRY ONLY
2230 	timestamp _attribute_date_and_time;
2231 	/*! \brief Initially 1, may be incremented upon user request. */
2232 	uint32 _checkpoint;
2233 	uint32 _reserved;	// <== EXTENDED FILE ENTRY ONLY
2234 	long_address _extended_attribute_icb;
2235 	long_address _stream_directory_icb;	// <== EXTENDED FILE ENTRY ONLY
2236 	entity_id _implementation_id;
2237 	/*! \brief The unique id identifying this file entry
2238 
2239 		The id of the root directory of a file set shall be 0.
2240 
2241 		\todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
2242 	*/
2243 	uint64 _unique_id;
2244 	uint32 _extended_attributes_length;
2245 	uint32 _allocation_descriptors_length;
2246 
2247 };
2248 
2249 
2250 #endif	// _UDF_DISK_STRUCTURES_H
2251 
2252