BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / udf / UdfStructures.h
blob3d319fba3b6adda21482d004c1923b7b0301f37b
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
9 #include <string.h>
11 #include <ByteOrder.h>
12 #include <SupportDefs.h>
14 #include "UdfDebug.h"
15 #include "Utils.h"
17 #include "Array.h"
19 /*! \file UdfStructures.h
21 \brief UDF on-disk data structure declarations
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.
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>
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
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>
44 //----------------------------------------------------------------------
45 // ECMA-167 Part 1
46 //----------------------------------------------------------------------
48 /*! \brief Character set specifications
50 The character_set_info field shall be set to the ASCII string
51 "OSTA Compressed Unicode" (padded right with NULL chars).
53 See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
55 struct charspec {
56 public:
57 charspec(uint8 type = 0, const char *info = NULL);
59 void dump() const;
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; }
65 void set_character_set_type(uint8 type) { _character_set_type = type; }
66 void set_character_set_info(const char *info);
67 private:
68 uint8 _character_set_type; //!< to be set to 0 to indicate CS0
69 char _character_set_info[63]; //!< "OSTA Compressed Unicode"
70 } __attribute__((packed));
72 extern const charspec kCs0CharacterSet;
74 /*! \brief Date and time stamp
76 See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
78 class timestamp {
79 private:
80 union type_and_timezone_accessor {
81 uint16 type_and_timezone;
82 struct {
83 uint16 timezone:12,
84 type:4;
85 } bits;
88 public:
89 timestamp() { _clear(); }
90 timestamp(time_t time);
92 void dump() const;
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;
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;
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; }
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);
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);
135 void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
136 void set_month(uint8 month) { _month = month; }
137 void set_day(uint8 day) { _day = day; }
138 void set_hour(uint8 hour) { _hour = hour; }
139 void set_minute(uint8 minute) { _minute = minute; }
140 void set_second(uint8 second) { _second = second; }
141 void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
142 void set_hundred_microsecond(uint8 hundred_microsecond) {
143 _hundred_microsecond = hundred_microsecond; }
144 void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
145 private:
146 void _clear();
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;
159 } __attribute__((packed));
162 /*! \brief UDF ID Identify Suffix
164 See also: UDF 2.50 2.1.5.3
166 struct udf_id_suffix {
167 public:
168 udf_id_suffix(uint16 udfRevision, uint8 os_class, uint8 os_identifier);
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; }
175 void set_os_class(uint8 os_class) { _os_class = os_class; }
176 void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
177 private:
178 uint16 _udf_revision;
179 uint8 _os_class;
180 uint8 _os_identifier;
181 array<uint8, 4> _reserved;
184 /*! \brief Implementation ID Identify Suffix
186 See also: UDF 2.50 2.1.5.3
188 struct implementation_id_suffix {
189 public:
190 implementation_id_suffix(uint8 os_class, uint8 os_identifier);
192 uint8 os_class() const { return _os_class; }
193 uint8 os_identifier() const { return _os_identifier; }
195 void set_os_class(uint8 os_class) { _os_class = os_class; }
196 void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
197 private:
198 uint8 _os_class;
199 uint8 _os_identifier;
200 array<uint8, 6> _implementation_use;
203 /*! \brief Operating system classes for implementation_id_suffixes
205 See also: Udf 2.50 6.3
207 enum {
208 OS_UNDEFINED = 0,
209 OS_DOS,
210 OS_OS2,
211 OS_MACOS,
212 OS_UNIX,
213 OS_WIN9X,
214 OS_WINNT,
215 OS_OS400,
216 OS_BEOS,
217 OS_WINCE
220 /*! \brief BeOS operating system classes identifiers for implementation_id_suffixes
222 See also: Udf 2.50 6.3
224 enum {
225 BEOS_GENERIC = 0,
226 BEOS_OPENBEOS = 1 // not part of the standard, but perhaps someday. :-)
229 /*! \brief Domain ID Identify Suffix
231 See also: UDF 2.50 2.1.5.3
233 struct domain_id_suffix {
234 public:
235 domain_id_suffix(uint16 udfRevision, uint8 domainFlags);
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; }
241 void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); }
242 void set_domain_flags(uint8 flags) { _domain_flags = flags; }
243 private:
244 uint16 _udf_revision;
245 uint8 _domain_flags;
246 array<uint8, 5> _reserved;
249 /*! \brief Domain flags
251 See also: UDF 2.50 2.1.5.3
253 enum {
254 DF_HARD_WRITE_PROTECT = 0x01,
255 DF_SOFT_WRITE_PROTECT = 0x02
258 /*! \brief Identifier used to designate the implementation responsible
259 for writing associated data structures on the medium.
261 See also: ECMA 167 1/7.4, UDF 2.01 2.1.5
263 struct entity_id {
264 public:
265 static const int kIdentifierLength = 23;
266 static const int kIdentifierSuffixLength = 8;
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);
277 void dump() const;
278 bool matches(const entity_id &id) const;
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; }
287 // Set functions
288 void set_flags(uint8 flags) { _flags = flags; }
289 private:
290 uint8 _flags;
291 char _identifier[kIdentifierLength];
292 array<uint8, kIdentifierSuffixLength> _identifier_suffix;
293 } __attribute__((packed));
295 extern entity_id kMetadataPartitionMapId;
296 extern entity_id kSparablePartitionMapId;
297 extern entity_id kVirtualPartitionMapId;
298 extern entity_id kImplementationId;
299 extern entity_id kPartitionContentsId1xx;
300 extern entity_id kPartitionContentsId2xx;
301 extern entity_id kUdfId;
302 extern entity_id kLogicalVolumeInfoId150;
303 extern entity_id kLogicalVolumeInfoId201;
304 extern entity_id kDomainId150;
305 extern entity_id kDomainId201;
306 extern void init_entities(void);
308 //----------------------------------------------------------------------
309 // ECMA-167 Part 2
310 //----------------------------------------------------------------------
313 /*! \brief Header for volume structure descriptors
315 Each descriptor consumes an entire block. All unused trailing
316 bytes in the descriptor should be set to 0.
318 The following descriptors contain no more information than
319 that contained in the header:
321 - BEA01:
322 - type: 0
323 - id: "BEA01"
324 - version: 1
326 - TEA01:
327 - type: 0
328 - id: "TEA01"
329 - version: 1
331 - NSR03:
332 - type: 0
333 - id: "NSR03"
334 - version: 1
336 See also: ECMA 167 2/9.1
338 struct volume_structure_descriptor_header {
339 public:
340 volume_structure_descriptor_header(uint8 type, const char *id, uint8 version);
342 uint8 type;
343 char id[5];
344 uint8 version;
346 bool id_matches(const char *id);
347 } __attribute__((packed));
349 // Volume structure descriptor ids
350 extern const char* kVSDID_BEA;
351 extern const char* kVSDID_TEA;
352 extern const char* kVSDID_BOOT;
353 extern const char* kVSDID_ISO;
354 extern const char* kVSDID_ECMA167_2;
355 extern const char* kVSDID_ECMA167_3;
356 extern const char* kVSDID_ECMA168;
358 //----------------------------------------------------------------------
359 // ECMA-167 Part 3
360 //----------------------------------------------------------------------
363 /*! \brief Location and length of a contiguous chunk of data on the volume.
365 \c _location is an absolute block address.
367 See also: ECMA 167 3/7.1
369 struct extent_address {
370 public:
371 extent_address(uint32 location = 0, uint32 length = 0);
373 void dump() const;
375 uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
376 uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
378 void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
379 void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
380 private:
381 uint32 _length;
382 uint32 _location;
383 } __attribute__((packed));
386 /*! \brief Location of a logical block within a logical volume.
388 See also: ECMA 167 4/7.1
390 struct logical_block_address {
391 public:
392 void dump() const;
393 logical_block_address(uint16 partition = 0, uint32 block = 0);
395 uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
396 uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); }
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); }
401 private:
402 uint32 _block; //!< Block location relative to start of corresponding partition
403 uint16 _partition; //!< Numeric partition id within logical volume
404 } __attribute__((packed));
406 /*! \brief Extent types used in short_address, long_address,
407 and extended_address.
409 See also: ECMA-167 4/14.14.1.1
411 enum extent_type {
412 EXTENT_TYPE_RECORDED = 0, //!< Allocated and recorded
413 EXTENT_TYPE_ALLOCATED, //!< Allocated but unrecorded
414 EXTENT_TYPE_UNALLOCATED, //!< Unallocated and unrecorded
415 EXTENT_TYPE_CONTINUATION, //!< Specifies next extent of descriptors
419 /*! \brief Allocation descriptor.
421 See also: ECMA 167 4/14.14.1
423 struct short_address {
424 private:
425 union type_and_length_accessor {
426 uint32 type_and_length;
427 struct {
428 uint32 length:30,
429 type:2;
430 // uint32 type:2,
431 // length:30;
432 } bits;
435 public:
436 void dump() const;
438 uint8 type() const {
439 type_and_length_accessor t;
440 t.type_and_length = type_and_length();
441 return t.bits.type;
443 uint32 length() const {
444 type_and_length_accessor t;
445 t.type_and_length = type_and_length();
446 return t.bits.length;
448 uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
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);
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);
462 void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
463 private:
464 uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
465 void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
467 uint32 _type_and_length;
468 uint32 _block;
469 } __attribute__((packed));
472 /*! \brief Allocation descriptor w/ 6 byte implementation use field.
474 See also: ECMA 167 4/14.14.2
476 struct long_address {
477 private:
478 union type_and_length_accessor {
479 uint32 type_and_length;
480 struct {
481 uint32 length:30,
482 type:2;
483 } bits;
486 public:
487 long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0,
488 uint8 type = 0);
490 void dump() const;
492 uint8 type() const {
493 type_and_length_accessor t;
494 t.type_and_length = type_and_length();
495 return t.bits.type;
497 uint32 length() const {
498 type_and_length_accessor t;
499 t.type_and_length = type_and_length();
500 return t.bits.length;
503 uint32 block() const { return _location.block(); }
504 uint16 partition() const { return _location.partition(); }
506 const array<uint8, 6>& implementation_use() const { return _implementation_use; }
507 array<uint8, 6>& implementation_use() { return _implementation_use; }
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); }
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);
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);
524 void set_block(uint32 block) { _location.set_block(block); }
525 void set_partition(uint16 partition) { _location.set_partition(partition); }
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); }
530 void set_to(uint32 block, uint16 partition, uint32 length = 1,
531 uint8 type = EXTENT_TYPE_RECORDED, uint16 flags = 0, uint32 unique_id = 0)
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);
541 private:
542 //! See UDF-2.50 2.3.4.3
543 struct _implementation_use_accessor {
544 uint16 flags;
545 uint32 unique_id;
546 } __attribute__((packed));
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); }
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); }
556 uint32 _type_and_length;
557 logical_block_address _location;
558 array<uint8, 6> _implementation_use;
559 } __attribute__((packed));
561 /*! \brief Common tag found at the beginning of most udf descriptor structures.
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
568 See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
570 struct descriptor_tag {
571 public:
572 void dump() const;
574 status_t init_check(uint32 block, bool calculateCrc = true);
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); }
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); }
592 /*! \brief Calculates and sets the crc length, crc checksumm, and
593 checksum for the tag.
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).
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).
606 template <class Descriptor>
607 void
608 set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
611 // check that this tag is actually owned by
612 // the given descriptor
613 if (this == &descriptor.tag())
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);
630 private:
631 uint16 _id;
632 uint16 _version;
633 uint8 _checksum; //!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
634 uint8 _reserved; //!< Set to #00.
635 uint16 _serial_number;
636 uint16 _crc; //!< May be 0 if \c crc_length field is 0.
637 /*! \brief Length of the data chunk used to calculate CRC.
639 If 0, no CRC was calculated, and the \c crc field must be 0.
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:
644 <code>(descriptor length) - (descriptor tag length)</code>
646 uint16 _crc_length;
647 /*! \brief Address of this tag within its partition (for error checking).
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.
652 uint32 _location;
654 } __attribute__((packed));
657 /*! \c descriptor_tag ::id values
659 enum tag_id {
660 TAGID_UNDEFINED = 0,
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,
673 TAGID_CUSTOM_START = 65280,
674 TAGID_CUSTOM_END = 65535,
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,
690 const char *tag_id_to_string(tag_id id);
692 extern const uint16 kCrcTable[256];
694 /*! \brief Primary volume descriptor
696 struct primary_volume_descriptor {
697 public:
698 void dump() const;
700 // Get functions
701 const descriptor_tag & tag() const { return _tag; }
702 descriptor_tag & tag() { return _tag; }
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); }
707 const array<char, 32>& volume_identifier() const { return _volume_identifier; }
708 array<char, 32>& volume_identifier() { return _volume_identifier; }
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); }
717 const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
718 array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
720 const charspec& descriptor_character_set() const { return _descriptor_character_set; }
721 charspec& descriptor_character_set() { return _descriptor_character_set; }
723 const charspec& explanatory_character_set() const { return _explanatory_character_set; }
724 charspec& explanatory_character_set() { return _explanatory_character_set; }
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; }
731 const entity_id& application_id() const { return _application_id; }
732 entity_id& application_id() { return _application_id; }
734 const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
735 timestamp& recording_date_and_time() { return _recording_date_and_time; }
737 const entity_id& implementation_id() const { return _implementation_id; }
738 entity_id& implementation_id() { return _implementation_id; }
740 const array<uint8, 64>& implementation_use() const { return _implementation_use; }
741 array<uint8, 64>& implementation_use() { return _implementation_use; }
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); }
747 const array<uint8, 22>& reserved() const { return _reserved; }
748 array<uint8, 22>& reserved() { return _reserved; }
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); }
772 private:
773 descriptor_tag _tag;
774 uint32 _vds_number;
775 uint32 _primary_volume_descriptor_number;
776 array<char, 32> _volume_identifier;
777 uint16 _volume_sequence_number;
778 uint16 _max_volume_sequence_number;
779 uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
780 uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
781 uint32 _character_set_list;
782 uint32 _max_character_set_list;
783 array<char, 128> _volume_set_identifier;
785 /*! \brief Identifies the character set for the \c volume_identifier
786 and \c volume_set_identifier fields.
788 To be set to CS0.
790 charspec _descriptor_character_set;
792 /*! \brief Identifies the character set used in the \c volume_abstract
793 and \c volume_copyright_notice extents.
795 To be set to CS0.
797 charspec _explanatory_character_set;
799 extent_address _volume_abstract;
800 extent_address _volume_copyright_notice;
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;
810 } __attribute__((packed));
813 /*! \brief Anchor Volume Descriptor Pointer
815 vd recorded at preset locations in the partition, used as a reference
816 point to the main vd sequences
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
825 See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
827 struct anchor_volume_descriptor {
828 public:
829 anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
830 void dump() const;
832 descriptor_tag & tag() { return _tag; }
833 const descriptor_tag & tag() const { return _tag; }
835 extent_address& main_vds() { return _main_vds; }
836 const extent_address& main_vds() const { return _main_vds; }
838 extent_address& reserve_vds() { return _reserve_vds; }
839 const extent_address& reserve_vds() const { return _reserve_vds; }
840 private:
841 descriptor_tag _tag;
842 extent_address _main_vds; //!< min length of 16 sectors
843 extent_address _reserve_vds; //!< min length of 16 sectors
844 array<uint8, 480> _reserved;
845 } __attribute__((packed));
848 /*! \brief Volume Descriptor Pointer
850 Used to chain extents of volume descriptor sequences together.
852 See also: ECMA 167 3/10.3
854 struct descriptor_pointer {
855 descriptor_tag tag;
856 uint32 vds_number;
857 extent_address next;
858 } __attribute__((packed));
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"
865 See also: UDF 2.50 2.2.7
867 struct logical_volume_info {
868 public:
869 void dump() const;
871 charspec& character_set() { return _character_set; }
872 const charspec& character_set() const { return _character_set; }
874 array<char, 128>& logical_volume_id() { return _logical_volume_id; }
875 const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
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]; }
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]; }
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]; }
886 entity_id& implementation_id() { return _implementation_id; }
887 const entity_id& implementation_id() const { return _implementation_id; }
889 array<uint8, 128>& implementation_use() { return _implementation_use; }
890 const array<uint8, 128>& implementation_use() const { return _implementation_use; }
891 private:
892 charspec _character_set;
893 array<char, 128> _logical_volume_id; // d-string
894 array<array<char, 36>, 3> _logical_volume_info; // d-strings
895 entity_id _implementation_id;
896 array<uint8, 128> _implementation_use;
897 } __attribute__((packed));
899 /*! \brief Implementation Use Volume Descriptor
901 See also: ECMA 167 3/10.4
903 struct implementation_use_descriptor {
904 public:
905 void dump() const;
907 // Get functions
908 const descriptor_tag & tag() const { return _tag; }
909 descriptor_tag & tag() { return _tag; }
911 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
913 const entity_id& implementation_id() const { return _implementation_id; }
914 entity_id& implementation_id() { return _implementation_id; }
916 const array<uint8, 460>& implementation_use() const { return _implementation_use; }
917 array<uint8, 460>& implementation_use() { return _implementation_use; }
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); }
923 // Set functions
924 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
925 private:
926 descriptor_tag _tag;
927 uint32 _vds_number;
928 entity_id _implementation_id;
929 array<uint8, 460> _implementation_use;
930 } __attribute__((packed));
933 /*! \brief Maximum number of partition descriptors to be found in volume
934 descriptor sequence, per UDF-2.50
936 const uint8 kMaxPartitionDescriptors = 2;
937 #define UDF_MAX_PARTITION_MAPS 2
938 #define UDF_MAX_PARTITION_MAP_SIZE 64
940 /*! \brief Partition Descriptor
942 See also: ECMA 167 3/10.5
944 struct partition_descriptor {
945 private:
946 union partition_flags_accessor {
947 uint16 partition_flags;
948 struct {
949 uint16 allocated:1,
950 reserved:15;
951 } bits;
954 public:
955 void dump() const;
957 // Get functions
958 const descriptor_tag & tag() const { return _tag; }
959 descriptor_tag & tag() { return _tag; }
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;
968 uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
970 const entity_id& partition_contents() const { return _partition_contents; }
971 entity_id& partition_contents() { return _partition_contents; }
973 const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
974 array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
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); }
980 const entity_id& implementation_id() const { return _implementation_id; }
981 entity_id& implementation_id() { return _implementation_id; }
983 const array<uint8, 128>& implementation_use() const { return _implementation_use; }
984 array<uint8, 128>& implementation_use() { return _implementation_use; }
986 const array<uint8, 156>& reserved() const { return _reserved; }
987 array<uint8, 156>& reserved() { return _reserved; }
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);
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); }
1003 private:
1004 descriptor_tag _tag;
1005 uint32 _vds_number;
1006 /*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
1007 shall mean volume space has been allocated.
1009 uint16 _partition_flags;
1010 uint16 _partition_number;
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
1017 entity_id _partition_contents;
1018 array<uint8, 128> _partition_contents_use;
1020 /*! See \c partition_access_type enum
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));
1031 enum partition_access_type {
1032 ACCESS_UNSPECIFIED,
1033 ACCESS_READ_ONLY,
1034 ACCESS_WRITE_ONCE,
1035 ACCESS_REWRITABLE,
1036 ACCESS_OVERWRITABLE,
1040 /*! \brief Logical volume descriptor
1042 See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
1044 struct logical_volume_descriptor {
1045 void dump() const;
1047 // Get functions
1048 const descriptor_tag & tag() const { return _tag; }
1049 descriptor_tag & tag() { return _tag; }
1051 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1053 const charspec& character_set() const { return _character_set; }
1054 charspec& character_set() { return _character_set; }
1056 const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
1057 array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
1059 uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
1061 const entity_id& domain_id() const { return _domain_id; }
1062 entity_id& domain_id() { return _domain_id; }
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; }
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); }
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); }
1073 const entity_id& implementation_id() const { return _implementation_id; }
1074 entity_id& implementation_id() { return _implementation_id; }
1076 const array<uint8, 128>& implementation_use() const { return _implementation_use; }
1077 array<uint8, 128>& implementation_use() { return _implementation_use; }
1079 const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
1080 extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
1082 const uint8* partition_maps() const { return _partition_maps; }
1083 uint8* partition_maps() { return _partition_maps; }
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); }
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); }
1092 // Other functions
1093 logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
1095 private:
1096 descriptor_tag _tag;
1097 uint32 _vds_number;
1099 /*! \brief Identifies the character set for the
1100 \c logical_volume_identifier field.
1102 To be set to CS0.
1104 charspec _character_set;
1105 array<char, 128> _logical_volume_identifier;
1106 uint32 _logical_block_size;
1108 /*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
1110 entity_id _domain_id;
1112 /*! \brief For UDF, shall contain a \c long_address which identifies
1113 the location of the logical volume's first file set.
1115 array<uint8, 16> _logical_volume_contents_use;
1117 uint32 _map_table_length;
1118 uint32 _partition_map_count;
1119 entity_id _implementation_id;
1120 array<uint8, 128> _implementation_use;
1122 /*! \brief Logical volume integrity sequence location.
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).
1129 extent_address _integrity_sequence_extent;
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.
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.
1139 See UDF-2.01 2.2.8, 2.2.9
1141 uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1142 } __attribute__((packed));
1144 //! Base size (excluding partition maps) of lvd
1145 extern const uint32 kLogicalVolumeDescriptorBaseSize;
1147 /*! \brief (Mostly) common portion of various partition maps
1149 See also: ECMA-167 3/10.7.1
1151 struct partition_map_header {
1152 public:
1153 uint8 type() const { return _type; }
1154 uint8 length() const { return _length; }
1155 uint8 *map_data() { return _map_data; }
1156 const uint8 *map_data() const { return _map_data; }
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]); }
1163 void set_type(uint8 type) { _type = type; }
1164 void set_length(uint8 length) { _length = length; }
1165 private:
1166 uint8 _type;
1167 uint8 _length;
1168 uint8 _map_data[0];
1169 };// __attribute__((packed));
1172 /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
1174 See also: ECMA-167 3/10.7.2
1176 struct physical_partition_map {
1177 public:
1178 void dump();
1180 uint8 type() const { return _type; }
1181 uint8 length() const { return _length; }
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); }
1188 void set_type(uint8 type) { _type = type; }
1189 void set_length(uint8 length) { _length = length; }
1190 void set_volume_sequence_number(uint16 number) {
1191 _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1192 void set_partition_number(uint16 number) {
1193 _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1194 private:
1195 uint8 _type;
1196 uint8 _length;
1197 uint16 _volume_sequence_number;
1198 uint16 _partition_number;
1199 } __attribute__((packed));
1202 /* ----UDF Specific---- */
1203 /*! \brief Virtual partition map
1205 Note that this map is a customization of the ECMA-167
1206 type 2 partition map.
1208 See also: UDF-2.01 2.2.8
1210 struct virtual_partition_map {
1211 uint8 type;
1212 uint8 length;
1213 uint8 reserved1[2];
1215 /*! - flags: 0
1216 - identifier: "*UDF Virtual Partition"
1217 - identifier_suffix: per UDF-2.01 2.1.5.3
1219 entity_id partition_type_id;
1220 uint16 volume_sequence_number;
1222 /*! corresponding type 1 partition map in same logical volume
1224 uint16 partition_number;
1225 uint8 reserved2[24];
1226 } __attribute__((packed));
1229 /*! \brief Maximum number of redundant sparing tables found in
1230 sparable_partition_map structures.
1232 #define UDF_MAX_SPARING_TABLE_COUNT 4
1234 /* ----UDF Specific---- */
1235 /*! \brief Sparable partition map
1237 Note that this map is a customization of the ECMA-167
1238 type 2 partition map.
1240 See also: UDF-2.01 2.2.9
1242 struct sparable_partition_map {
1243 public:
1244 void dump();
1246 uint8 type() const { return _type; }
1247 uint8 length() const { return _length; }
1249 entity_id& partition_type_id() { return _partition_type_id; }
1250 const entity_id& partition_type_id() const { return _partition_type_id; }
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]); }
1265 void set_type(uint8 type) { _type = type; }
1266 void set_length(uint8 length) { _length = length; }
1267 void set_volume_sequence_number(uint16 number) {
1268 _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1269 void set_partition_number(uint16 number) {
1270 _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1271 void set_packet_length(uint16 length) {
1272 _packet_length = B_HOST_TO_LENDIAN_INT16(length); }
1273 void set_sparing_table_count(uint8 count) {
1274 _sparing_table_count = count; }
1275 void set_sparing_table_size(uint32 size) {
1276 _sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
1277 void set_sparing_table_location(uint8 index, uint32 location) {
1278 _sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
1279 private:
1280 uint8 _type;
1281 uint8 _length;
1282 uint8 _reserved1[2];
1284 /*! - flags: 0
1285 - identifier: "*UDF Sparable Partition"
1286 - identifier_suffix: per UDF-2.01 2.1.5.3
1288 entity_id _partition_type_id;
1289 uint16 _volume_sequence_number;
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));
1301 /* ----UDF Specific---- */
1302 /*! \brief Metadata partition map
1304 Note that this map is a customization of the ECMA-167
1305 type 2 partition map.
1307 See also: UDF-2.50 2.2.10
1309 struct metadata_partition_map {
1310 public:
1311 entity_id& partition_type_id() { return _partition_type_id; }
1312 const entity_id& partition_type_id() const { return _partition_type_id; }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
1349 uint8 flags() const { return _flags; }
1350 void set_flags(uint8 flags) { _flags = flags; }
1352 private:
1353 uint8 type;
1354 uint8 length;
1355 uint8 reserved1[2];
1357 /*! - flags: 0
1358 - identifier: "*UDF Metadata Partition"
1359 - identifier_suffix: per UDF-2.50 2.1.5
1361 entity_id _partition_type_id;
1362 uint16 _volume_sequence_number;
1364 /*! corresponding type 1 or type 2 sparable partition
1365 map in same logical volume
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));
1378 /*! \brief Unallocated space descriptor
1380 See also: ECMA-167 3/10.8
1382 struct unallocated_space_descriptor {
1383 void dump() const;
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; }
1392 // Set functions
1393 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1394 void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1395 private:
1396 descriptor_tag _tag;
1397 uint32 _vds_number;
1398 uint32 _allocation_descriptor_count;
1399 extent_address _allocation_descriptors[0];
1400 } __attribute__((packed));
1403 /*! \brief Terminating descriptor
1405 See also: ECMA-167 3/10.9
1407 struct terminating_descriptor {
1408 terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
1409 void dump() const;
1411 // Get functions
1412 const descriptor_tag & tag() const { return _tag; }
1413 descriptor_tag & tag() { return _tag; }
1414 private:
1415 descriptor_tag _tag;
1416 array<uint8, 496> _reserved;
1417 } __attribute__((packed));
1420 /*! \brief Logical volume integrity descriptor
1422 See also: ECMA-167 3/10.10, UDF-2.50 2.2.6
1424 struct logical_volume_integrity_descriptor {
1425 public:
1426 static const uint32 minimum_implementation_use_length = 46;
1428 void dump() const;
1429 uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length()
1430 + partition_count()*sizeof(uint32)*2; }
1432 descriptor_tag& tag() { return _tag; }
1433 const descriptor_tag& tag() const { return _tag; }
1435 timestamp& recording_time() { return _recording_time; }
1436 const timestamp& recording_time() const { return _recording_time; }
1438 uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); }
1440 extent_address& next_integrity_extent() { return _next_integrity_extent; }
1441 const extent_address& next_integrity_extent() const { return _next_integrity_extent; }
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; }
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()); }
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); }
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)); }
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); }
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); }
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); }
1483 private:
1484 struct _lvid_implementation_use_accessor {
1485 entity_id id;
1486 uint32 file_count;
1487 uint32 directory_count;
1488 uint16 minimum_udf_read_revision;
1489 uint16 minimum_udf_write_revision;
1490 uint16 maximum_udf_write_revision;
1493 _lvid_implementation_use_accessor& _accessor() {
1494 return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use());
1496 const _lvid_implementation_use_accessor& _accessor() const {
1497 return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use());
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); }
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;
1511 } __attribute__((packed));
1513 /*! \brief Logical volume integrity types
1515 enum {
1516 INTEGRITY_OPEN = 0,
1517 INTEGRITY_CLOSED = 1,
1520 /*! \brief Highest currently supported UDF read revision.
1522 #define UDF_MAX_READ_REVISION 0x0250
1524 //----------------------------------------------------------------------
1525 // ECMA-167 Part 4
1526 //----------------------------------------------------------------------
1530 /*! \brief File set descriptor
1532 Contains all the pertinent info about a file set (i.e. a hierarchy of files)
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.
1544 struct file_set_descriptor {
1545 void dump() const;
1547 // Get functions
1548 const descriptor_tag & tag() const { return _tag; }
1549 descriptor_tag & tag() { return _tag; }
1551 const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
1552 timestamp& recording_date_and_time() { return _recording_date_and_time; }
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); }
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; }
1564 const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
1565 array<char, 128>& logical_volume_id() { return _logical_volume_id; }
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; }
1570 const array<char, 32>& file_set_id() const { return _file_set_id; }
1571 array<char, 32>& file_set_id() { return _file_set_id; }
1573 const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
1574 array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1576 const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
1577 array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1579 const long_address& root_directory_icb() const { return _root_directory_icb; }
1580 long_address& root_directory_icb() { return _root_directory_icb; }
1582 const entity_id& domain_id() const { return _domain_id; }
1583 entity_id& domain_id() { return _domain_id; }
1585 const long_address& next_extent() const { return _next_extent; }
1586 long_address& next_extent() { return _next_extent; }
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; }
1591 const array<uint8, 32>& reserved() const { return _reserved; }
1592 array<uint8, 32>& reserved() { return _reserved; }
1594 // Set functions
1595 void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1596 void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1597 void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1598 void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1599 void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
1600 void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1601 private:
1602 descriptor_tag _tag;
1603 timestamp _recording_date_and_time;
1604 uint16 _interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.1)
1605 uint16 _max_interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.2)
1606 uint32 _character_set_list;
1607 uint32 _max_character_set_list;
1608 uint32 _file_set_number;
1609 uint32 _file_set_descriptor_number;
1610 charspec _logical_volume_id_character_set; //!< To be set to kCSOCharspec
1611 array<char, 128> _logical_volume_id;
1612 charspec _file_set_id_character_set;
1613 array<char, 32> _file_set_id;
1614 array<char, 32> _copyright_file_id;
1615 array<char, 32> _abstract_file_id;
1616 long_address _root_directory_icb;
1617 entity_id _domain_id;
1618 long_address _next_extent;
1619 long_address _system_stream_directory_icb;
1620 array<uint8, 32> _reserved;
1621 } __attribute__((packed));
1624 /*! \brief Partition header descriptor
1626 Contains references to unallocated and freed space data structures.
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.
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.
1635 To indicate disuse of a certain field, the fields of the allocation
1636 descriptor shall all be set to 0.
1638 See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1640 struct partition_header_descriptor {
1641 long_address unallocated_space_table;
1642 long_address unallocated_space_bitmap;
1643 /*! Unused, per UDF-2.01 2.2.3 */
1644 long_address partition_integrity_table;
1645 long_address freed_space_table;
1646 long_address freed_space_bitmap;
1647 uint8 reserved[88];
1648 } __attribute__((packed));
1650 #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1652 /*! \brief File identifier descriptor
1654 Identifies the name of a file entry, and the location of its corresponding
1655 ICB.
1657 See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1659 \todo Check pointer arithmetic
1661 struct file_id_descriptor {
1662 public:
1663 uint32 descriptor_size() const { return total_length(); }
1664 void dump() const;
1666 descriptor_tag & tag() { return _tag; }
1667 const descriptor_tag & tag() const { return _tag; }
1669 uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1671 uint8 characteristics() const { return _characteristics; }
1673 bool may_be_hidden() const {
1674 characteristics_accessor c;
1675 c.all = characteristics();
1676 return c.bits.may_be_hidden;
1679 bool is_directory() const {
1680 characteristics_accessor c;
1681 c.all = characteristics();
1682 return c.bits.is_directory;
1685 bool is_deleted() const {
1686 characteristics_accessor c;
1687 c.all = characteristics();
1688 return c.bits.is_deleted;
1691 bool is_parent() const {
1692 characteristics_accessor c;
1693 c.all = characteristics();
1694 return c.bits.is_parent;
1697 bool is_metadata_stream() const {
1698 characteristics_accessor c;
1699 c.all = characteristics();
1700 return c.bits.is_metadata_stream;
1703 uint8 id_length() const { return _id_length; }
1705 long_address& icb() { return _icb; }
1706 const long_address& icb() const { return _icb; }
1708 uint16 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT16(_implementation_use_length); }
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.
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(); }
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(); }
1723 // Set functions
1724 void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1726 void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
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);
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);
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);
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);
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);
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); }
1769 private:
1770 union characteristics_accessor {
1771 uint8 all;
1772 struct {
1773 uint8 may_be_hidden:1,
1774 is_directory:1,
1775 is_deleted:1,
1776 is_parent:1,
1777 is_metadata_stream:1,
1778 reserved_characteristics:3;
1779 } bits;
1782 descriptor_tag _tag;
1783 /*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1785 However, according to UDF-2.01, there shall be exactly one version of
1786 a file, and it shall be 1.
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));
1797 /*! \brief Allocation extent descriptor
1799 See also: ECMA-167 4/14.5
1801 struct allocation_extent_descriptor {
1802 descriptor_tag tag;
1803 uint32 previous_allocation_extent_location;
1804 uint32 length_of_allocation_descriptors;
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));
1811 /*! \brief icb_tag::file_type values
1813 See also ECMA-167 4/14.6.6
1815 enum icb_file_types {
1816 ICB_TYPE_UNSPECIFIED = 0,
1817 ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1818 ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1819 ICB_TYPE_INDIRECT_ENTRY,
1820 ICB_TYPE_DIRECTORY,
1821 ICB_TYPE_REGULAR_FILE,
1822 ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1823 ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1824 ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1825 ICB_TYPE_FIFO,
1826 ICB_TYPE_ISSOCK,
1827 ICB_TYPE_TERMINAL,
1828 ICB_TYPE_SYMLINK,
1829 ICB_TYPE_STREAM_DIRECTORY,
1831 ICB_TYPE_RESERVED_START = 14,
1832 ICB_TYPE_RESERVED_END = 247,
1834 ICB_TYPE_CUSTOM_START = 248,
1835 ICB_TYPE_CUSTOM_END = 255,
1838 /*! \brief idb_entry_tag::_flags::descriptor_flags() values
1840 See also ECMA-167 4/14.6.8
1842 enum icb_descriptor_types {
1843 ICB_DESCRIPTOR_TYPE_SHORT = 0,
1844 ICB_DESCRIPTOR_TYPE_LONG,
1845 ICB_DESCRIPTOR_TYPE_EXTENDED,
1846 ICB_DESCRIPTOR_TYPE_EMBEDDED,
1849 /*! \brief idb_entry_tag::strategy_type() values
1851 See also UDF-2.50 2.3.5.1
1853 enum icb_strategy_types {
1854 ICB_STRATEGY_SINGLE = 4,
1855 ICB_STRATEGY_LINKED_LIST = 4096
1858 /*! \brief ICB entry tag
1860 Common tag found in all ICB entries (in addition to, and immediately following,
1861 the descriptor tag).
1863 See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1865 struct icb_entry_tag {
1866 public:
1867 union flags_accessor {
1868 uint16 all_flags;
1869 struct {
1870 uint16 descriptor_flags:3,
1871 if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4
1872 non_relocatable:1,
1873 archive:1,
1874 setuid:1,
1875 setgid:1,
1876 sticky:1,
1877 contiguous:1,
1878 system:1,
1879 transformed:1,
1880 multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4
1881 is_stream:1,
1882 reserved_icb_entry_flags:2;
1883 } flags;
1886 public:
1887 void dump() const;
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); }
1892 array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
1893 const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
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; }
1901 uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
1902 flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); }
1904 // flags accessor functions
1905 uint8 descriptor_flags() const {
1906 flags_accessor f;
1907 f.all_flags = flags();
1908 return f.flags.descriptor_flags;
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
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); }
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; }
1923 void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1925 private:
1926 uint32 _prior_recorded_number_of_direct_entries;
1927 /*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1929 \todo Describe strategy types here.
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));
1941 /*! \brief Header portion of an ICB entry.
1943 struct icb_header {
1944 public:
1945 void dump() const;
1947 descriptor_tag &tag() { return _tag; }
1948 const descriptor_tag &tag() const { return _tag; }
1950 icb_entry_tag &icb_tag() { return _icb_tag; }
1951 const icb_entry_tag &icb_tag() const { return _icb_tag; }
1952 private:
1953 descriptor_tag _tag;
1954 icb_entry_tag _icb_tag;
1957 /*! \brief Indirect ICB entry
1959 struct indirect_icb_entry {
1960 descriptor_tag tag;
1961 icb_entry_tag icb_tag;
1962 long_address indirect_icb;
1963 } __attribute__((packed));
1966 /*! \brief Terminal ICB entry
1968 struct terminal_icb_entry {
1969 descriptor_tag tag;
1970 icb_entry_tag icb_tag;
1971 } __attribute__((packed));
1973 enum permissions {
1974 OTHER_EXECUTE = 0x0001,
1975 OTHER_WRITE = 0x0002,
1976 OTHER_READ = 0x0004,
1977 OTHER_ATTRIBUTES = 0x0008,
1978 OTHER_DELETE = 0x0010,
1979 GROUP_EXECUTE = 0x0020,
1980 GROUP_WRITE = 0x0040,
1981 GROUP_READ = 0x0080,
1982 GROUP_ATTRIBUTES = 0x0100,
1983 GROUP_DELETE = 0x0200,
1984 USER_EXECUTE = 0x0400,
1985 USER_WRITE = 0x0800,
1986 USER_READ = 0x1000,
1987 USER_ATTRIBUTES = 0x2000,
1988 USER_DELETE = 0x4000,
1991 /*! \brief File ICB entry
1993 See also: ECMA-167 4/14.9
1995 \todo Check pointer math.
1997 struct file_icb_entry {
1998 void dump() const;
1999 uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
2000 +allocation_descriptors_length(); }
2001 const char* descriptor_name() const { return "file_icb_entry"; }
2003 // get functions
2004 descriptor_tag & tag() { return _tag; }
2005 const descriptor_tag & tag() const { return _tag; }
2007 icb_entry_tag& icb_tag() { return _icb_tag; }
2008 const icb_entry_tag& icb_tag() const { return _icb_tag; }
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); }
2020 timestamp& access_date_and_time() { return _access_date_and_time; }
2021 const timestamp& access_date_and_time() const { return _access_date_and_time; }
2023 timestamp& modification_date_and_time() { return _modification_date_and_time; }
2024 const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2026 timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
2027 const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2029 uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2031 long_address& extended_attribute_icb() { return _extended_attribute_icb; }
2032 const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2034 entity_id& implementation_id() { return _implementation_id; }
2035 const entity_id& implementation_id() const { return _implementation_id; }
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); }
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(); }
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); }
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; }
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); }
2059 void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
2061 void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
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); }
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; }
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; }
2077 private:
2078 static const uint32 _descriptor_length = 176;
2079 static long_address _dummy_stream_directory_icb;
2080 uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
2081 const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
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.
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;
2101 // NOTE: data members following this point in the descriptor are in
2102 // different locations in extended file entries
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
2111 The id of the root directory of a file set shall be 0.
2113 \todo Detail the system specific requirements for unique ids from UDF-2.01
2115 uint64 _unique_id;
2116 uint32 _extended_attributes_length;
2117 uint32 _allocation_descriptors_length;
2122 /*! \brief Extended file ICB entry
2124 See also: ECMA-167 4/14.17
2126 \todo Check pointer math.
2128 struct extended_file_icb_entry {
2129 void dump() const;
2130 uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length()
2131 +allocation_descriptors_length(); }
2132 const char* descriptor_name() const { return "extended_file_icb_entry"; }
2134 // get functions
2135 descriptor_tag & tag() { return _tag; }
2136 const descriptor_tag & tag() const { return _tag; }
2138 icb_entry_tag& icb_tag() { return _icb_tag; }
2139 const icb_entry_tag& icb_tag() const { return _icb_tag; }
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); }
2152 timestamp& access_date_and_time() { return _access_date_and_time; }
2153 const timestamp& access_date_and_time() const { return _access_date_and_time; }
2155 timestamp& modification_date_and_time() { return _modification_date_and_time; }
2156 const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
2158 timestamp& creation_date_and_time() { return _creation_date_and_time; }
2159 const timestamp& creation_date_and_time() const { return _creation_date_and_time; }
2161 timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
2162 const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
2164 uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
2166 long_address& extended_attribute_icb() { return _extended_attribute_icb; }
2167 const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
2169 long_address& stream_directory_icb() { return _stream_directory_icb; }
2170 const long_address& stream_directory_icb() const { return _stream_directory_icb; }
2172 entity_id& implementation_id() { return _implementation_id; }
2173 const entity_id& implementation_id() const { return _implementation_id; }
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); }
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(); }
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); }
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); }
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); }
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); }
2201 void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
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); }
2206 private:
2207 static const uint32 _descriptor_length = 216;
2208 uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; }
2209 const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; }
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.
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
2239 The id of the root directory of a file set shall be 0.
2241 \todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
2243 uint64 _unique_id;
2244 uint32 _extended_attributes_length;
2245 uint32 _allocation_descriptors_length;
2250 #endif // _UDF_DISK_STRUCTURES_H