From 9b438e897ccab84da0cb475334620c73dfd18207 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Sun, 7 Dec 2003 08:22:11 +0000 Subject: [PATCH] - Added implementation_id_suffix struct. - Added operating system class and identifier enums - Fixed timestamp::timezone() for negative timezones. - Added timestamp(time_t) constructor. - Added Udf::kImplementationId constant. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5604 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/udf/UdfStructures.cpp | 134 +++++++++++++++++- .../kernel/file_systems/udf/UdfStructures.h | 80 +++++++++-- 2 files changed, 198 insertions(+), 16 deletions(-) diff --git a/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp b/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp index d250330350..beadce6866 100644 --- a/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp +++ b/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp @@ -43,6 +43,7 @@ const char* Udf::kVSDID_ECMA168 = "CDW02"; const entity_id Udf::kMetadataPartitionMapId(0, "*UDF Metadata Partition"); const entity_id Udf::kSparablePartitionMapId(0, "*UDF Sparable Partition"); const entity_id Udf::kVirtualPartitionMapId(0, "*UDF Virtual Partition"); +const entity_id Udf::kImplementationId(0, "*OpenBeOS UDF", implementation_id_suffix(OS_BEOS, BEOS_OPENBEOS)); //! crc 010041 table, as generated by crc_table.cpp const uint16 Udf::kCrcTable[256] = { @@ -191,6 +192,86 @@ charspec::set_character_set_info(const char *info) // timestamp //---------------------------------------------------------------------- +static +int +get_month_length(int month, int year) +{ + if (0 <= month && month < 12 && year >= 1970) { + const int monthLengths[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + int result = monthLengths[month]; + if (month == 1 && ((year - 1968) % 4 == 0)) + result++; + return result; + } else { + DEBUG_INIT_ETC(NULL, ("month: %d, year: %d", month, year)); + PRINT(("Invalid month or year! Returning 0\n")); + return 0; + } +} + +timestamp::timestamp(time_t time) +{ + // real_time_clock() is returning the time offset by -16 hours. + // Considering I'm -8 hours from GMT, this doesn't really make + // sense. For the moment I'm offsetting it manually here, but + // I'm not sure what the freaking deal is, and unfortunately, + // localtime() appears to be broken... + time += 16 * 60 * 60; + + set_microsecond(0); + set_hundred_microsecond(0); + set_centisecond(0); + set_second(time % 60); + time = time / 60; // convert to minutes + set_minute(time % 60); + time = time / 60; // convert to hours + set_hour(time % 24); + time = time / 24; // convert to days + + // From here we start at time == 0 and count up + // by days until we figure out what the day, month, + // and year are. + int year = 0; + int month = 0; + time_t clock = 0; + for (clock = 0; + clock + get_month_length(month, year+1970) < time; + clock += get_month_length(month, year+1970)) + { + month++; + if (month == 12) { + year++; + month = 0; + } + } + int day = time - clock; + set_day(day); + set_month(month+1); + set_year(year+1970); + set_type(1); + set_timezone(-2047); // -2047 == no timezone specified + +/* + // Is it me, or is localtime() broken? + tm *local = localtime(&time); + if (local) { + set_microsecond(0); + set_hundred_microsecond(0); + set_centisecond(0); + set_second(local->tm_sec); + set_minute(local->tm_min); + set_hour(local->tm_hour); + set_day(local->tm_mday); + set_month(local->tm_mon); + set_year(local->tm_year); + set_type(1); + set_timezone(local->tm_gmtoff); + } else { + _clear(); + } +*/ +} + void timestamp::dump() const { @@ -208,30 +289,68 @@ timestamp::dump() const PRINT(("microsecond: %d\n", microsecond())); } +void +timestamp::_clear() +{ + set_microsecond(0); + set_hundred_microsecond(0); + set_centisecond(0); + set_second(0); + set_minute(0); + set_hour(0); + set_day(0); + set_month(0); + set_year(0); + set_type(0); + set_timezone(0); +} + +//---------------------------------------------------------------------- +// implementation_id_suffix +//---------------------------------------------------------------------- + +implementation_id_suffix::implementation_id_suffix(uint8 os_class, + uint8 os_identifier) + : _os_class(os_class) + , _os_identifier(os_identifier) +{ + memset(_implementation_use.data, 0, _implementation_use.size()); +} + //---------------------------------------------------------------------- // entity_id //---------------------------------------------------------------------- -entity_id::entity_id(uint8 flags, char *identifier, char *identifier_suffix) +entity_id::entity_id(uint8 flags, char *identifier, uint8 *identifier_suffix) : _flags(flags) { + memset(_identifier, 0, kIdentifierLength); if (identifier) strncpy(_identifier, identifier, kIdentifierLength); - else - memset(_identifier, 0, kIdentifierLength); if (identifier_suffix) - strncpy(_identifier_suffix, identifier_suffix, kIdentifierSuffixLength); + memcpy(_identifier_suffix.data, identifier_suffix, kIdentifierSuffixLength); else - memset(_identifier_suffix, 0, kIdentifierSuffixLength); + memset(_identifier_suffix.data, 0, kIdentifierSuffixLength); } +entity_id::entity_id(uint8 flags, char *identifier, + const implementation_id_suffix &suffix) + : _flags(flags) +{ + memset(_identifier, 0, kIdentifierLength); + if (identifier) + strncpy(_identifier, identifier, kIdentifierLength); + memcpy(_identifier_suffix.data, &suffix, kIdentifierSuffixLength); +} + void entity_id::dump() const { DUMP_INIT("entity_id"); PRINT(("flags: %d\n", flags())); PRINT(("identifier: `%.23s'\n", identifier())); - PRINT(("identifier_suffix: `%s'\n", identifier_suffix())); + PRINT(("identifier_suffix:\n")); + DUMP(identifier_suffix()); } bool @@ -398,6 +517,9 @@ primary_volume_descriptor::dump() const DUMP(implementation_id()); PRINT(("implementation_use:\n")); DUMP(implementation_use()); + PRINT(("predecessor_vds_location: %ld\n", + predecessor_volume_descriptor_sequence_location())); + PRINT(("flags: %d\n", flags())); } diff --git a/src/add-ons/kernel/file_systems/udf/UdfStructures.h b/src/add-ons/kernel/file_systems/udf/UdfStructures.h index 3190739b86..b582489b2d 100644 --- a/src/add-ons/kernel/file_systems/udf/UdfStructures.h +++ b/src/add-ons/kernel/file_systems/udf/UdfStructures.h @@ -89,6 +89,9 @@ private: }; public: + timestamp() { _clear(); } + timestamp(time_t time); + void dump() const; // Get functions @@ -101,7 +104,11 @@ public: int16 timezone() const { type_and_timezone_accessor t; t.type_and_timezone = type_and_timezone(); - return t.bits.timezone; + int16 result = t.bits.timezone; + // Fill the lefmost bits with ones if timezone is negative + result <<= 4; + result >>= 4; + return result; } uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); } uint8 month() const { return _month; } @@ -121,7 +128,7 @@ public: t.bits.type = type; set_type_and_timezone(t.type_and_timezone); } - void set_timezone(uint8 timezone) { + void set_timezone(int16 timezone) { type_and_timezone_accessor t; t.type_and_timezone = type_and_timezone(); t.bits.timezone = timezone; @@ -137,6 +144,8 @@ public: void set_hundred_microsecond(uint8 hundred_microsecond) { _hundred_microsecond = hundred_microsecond; } void set_microsecond(uint8 microsecond) { _microsecond = microsecond; } private: + void _clear(); + uint16 _type_and_timezone; uint16 _year; uint8 _month; @@ -151,6 +160,51 @@ private: } __attribute__((packed)); +/*! \brief Implementation ID Identify Suffix + + See also: UDF 2.50 2.1.5.3 +*/ +struct implementation_id_suffix { +public: + implementation_id_suffix(uint8 os_class, uint8 os_identifier); + + uint8 os_class() const { return _os_class; } + uint8 os_identifier() const { return _os_identifier; } + + void set_os_class(uint8 os_class) { _os_class = os_class; } + void set_os_identifier(uint8 identifier) { _os_identifier = identifier; } +private: + uint8 _os_class; + uint8 _os_identifier; + array _implementation_use; +}; + +/*! \brief Operating system classes for implementation_id_suffixes + + See also: Udf 2.50 6.3 +*/ +enum { + OS_UNDEFINED = 0, + OS_DOS, + OS_OS2, + OS_MACOS, + OS_UNIX, + OS_WIN9X, + OS_WINNT, + OS_OS400, + OS_BEOS, + OS_WINCE +}; + +/*! \brief BeOS operating system classes identifiers for implementation_id_suffixes + + See also: Udf 2.50 6.3 +*/ +enum { + BEOS_GENERIC = 0, + BEOS_OPENBEOS = 1 // not part of the standard, but perhaps someday. :-) +}; + /*! \brief Identifier used to designate the implementation responsible for writing associated data structures on the medium. @@ -158,8 +212,13 @@ private: */ struct entity_id { public: + static const int kIdentifierLength = 23; + static const int kIdentifierSuffixLength = 8; + entity_id(uint8 flags = 0, char *identifier = NULL, - char *identifier_suffix = NULL); + uint8 *identifier_suffix = NULL); + entity_id(uint8 flags, char *identifier, + const implementation_id_suffix &suffix); void dump() const; bool matches(const entity_id &id) const; @@ -168,23 +227,21 @@ public: uint8 flags() const { return _flags; } const char* identifier() const { return _identifier; } char* identifier() { return _identifier; } - const char* identifier_suffix() const { return _identifier_suffix; } - char* identifier_suffix() { return _identifier_suffix; } + const array& identifier_suffix() const { return _identifier_suffix; } + array& identifier_suffix() { return _identifier_suffix; } // Set functions void set_flags(uint8 flags) { _flags = flags; } - - static const int kIdentifierLength = 23; - static const int kIdentifierSuffixLength = 8; private: uint8 _flags; char _identifier[kIdentifierLength]; - char _identifier_suffix[kIdentifierSuffixLength]; + array _identifier_suffix; } __attribute__((packed)); extern const entity_id kMetadataPartitionMapId; extern const entity_id kSparablePartitionMapId; extern const entity_id kVirtualPartitionMapId; +extern const entity_id kImplementationId; //---------------------------------------------------------------------- // ECMA-167 Part 2 @@ -601,6 +658,9 @@ public: uint32 predecessor_volume_descriptor_sequence_location() const { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); } uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); } + + const array& reserved() const { return _reserved; } + array& reserved() { return _reserved; } // Set functions void set_vds_number(uint32 number) @@ -660,7 +720,7 @@ private: array _implementation_use; uint32 _predecessor_volume_descriptor_sequence_location; uint16 _flags; - char _reserved[22]; + array _reserved; } __attribute__((packed));