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*/
55struct charspec {
56public:
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);
67private:
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
72extern 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*/
78class timestamp {
79private:
80	union type_and_timezone_accessor {
81		uint16 type_and_timezone;
82		struct {
83			uint16 timezone:12,
84			       type:4;
85		} bits;
86	};
87
88public:
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; }
145private:
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*/
166struct udf_id_suffix {
167public:
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; }
177private:
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*/
188struct implementation_id_suffix {
189public:
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; }
197private:
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*/
207enum {
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*/
224enum {
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*/
233struct domain_id_suffix {
234public:
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; }
243private:
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*/
253enum {
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*/
263struct entity_id {
264public:
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; }
289private:
290	uint8 _flags;
291	char _identifier[kIdentifierLength];
292	array<uint8, kIdentifierSuffixLength> _identifier_suffix;
293} __attribute__((packed));
294
295extern entity_id kMetadataPartitionMapId;
296extern entity_id kSparablePartitionMapId;
297extern entity_id kVirtualPartitionMapId;
298extern entity_id kImplementationId;
299extern entity_id kPartitionContentsId1xx;
300extern entity_id kPartitionContentsId2xx;
301extern entity_id kUdfId;
302extern entity_id kLogicalVolumeInfoId150;
303extern entity_id kLogicalVolumeInfoId201;
304extern entity_id kDomainId150;
305extern entity_id kDomainId201;
306extern 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*/
338struct volume_structure_descriptor_header {
339public:
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
350extern const char* kVSDID_BEA;
351extern const char* kVSDID_TEA;
352extern const char* kVSDID_BOOT;
353extern const char* kVSDID_ISO;
354extern const char* kVSDID_ECMA167_2;
355extern const char* kVSDID_ECMA167_3;
356extern 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*/
369struct extent_address {
370public:
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); }
380private:
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*/
390struct logical_block_address {
391public:
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
401private:
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*/
411enum 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*/
423struct short_address {
424private:
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
435public:
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); }
463private:
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*/
476struct long_address {
477private:
478	union type_and_length_accessor {
479		uint32 type_and_length;
480		struct {
481			uint32 length:30,
482			       type:2;
483		} bits;
484	};
485
486public:
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
541private:
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*/
570struct descriptor_tag {
571public:
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	}
630private:
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*/
659enum 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
690const char *tag_id_to_string(tag_id id);
691
692extern const uint16 kCrcTable[256];
693
694/*! \brief Primary volume descriptor
695*/
696struct primary_volume_descriptor {
697public:
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
772private:
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*/
827struct anchor_volume_descriptor {
828public:
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; }
840private:
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*/
854struct 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*/
867struct logical_volume_info {
868public:
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; }
891private:
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*/
903struct implementation_use_descriptor {
904public:
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); }
925private:
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*/
936const 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*/
944struct partition_descriptor {
945private:
946	union partition_flags_accessor {
947		uint16 partition_flags;
948		struct {
949			uint16 allocated:1,
950			       reserved:15;
951		} bits;
952	};
953
954public:
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
1003private:
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
1031enum 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*/
1044struct 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
1095private:
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
1145extern const uint32 kLogicalVolumeDescriptorBaseSize;
1146
1147/*! \brief (Mostly) common portion of various partition maps
1148
1149	See also: ECMA-167 3/10.7.1
1150*/
1151struct partition_map_header {
1152public:
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; }
1165private:
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*/
1176struct physical_partition_map {
1177public:
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); }
1194private:
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*/
1210struct 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*/
1242struct sparable_partition_map {
1243public:
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); }
1279private:
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*/
1309struct metadata_partition_map {
1310public:
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
1352private:
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*/
1382struct 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); }
1395private:
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*/
1407struct 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; }
1414private:
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*/
1424struct logical_volume_integrity_descriptor {
1425public:
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
1483private:
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*/
1515enum {
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*/
1544struct 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); }
1601private:
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*/
1640struct 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*/
1661struct file_id_descriptor {
1662public:
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
1769private:
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*/
1801struct 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*/
1815enum 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*/
1842enum 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*/
1853enum 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*/
1865struct icb_entry_tag {
1866public:
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
1886public:
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
1925private:
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*/
1943struct icb_header {
1944public:
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; }
1952private:
1953	descriptor_tag  _tag;
1954	icb_entry_tag _icb_tag;
1955};
1956
1957/*! \brief Indirect ICB entry
1958*/
1959struct 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*/
1968struct terminal_icb_entry {
1969	descriptor_tag  tag;
1970	icb_entry_tag icb_tag;
1971} __attribute__((packed));
1972
1973enum 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*/
1997struct 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
2077private:
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*/
2128struct 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
2206private:
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