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