- 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
This commit is contained in:
Tyler Dauwalder 2003-12-07 08:22:11 +00:00
parent cd0f0e996d
commit 9b438e897c
2 changed files with 198 additions and 16 deletions

View File

@ -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()));
}

View File

@ -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<uint8, 6> _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<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; }
array<uint8, kIdentifierSuffixLength>& 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<uint8, kIdentifierSuffixLength> _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<uint8, 22>& reserved() const { return _reserved; }
array<uint8, 22>& reserved() { return _reserved; }
// Set functions
void set_vds_number(uint32 number)
@ -660,7 +720,7 @@ private:
array<uint8, 64> _implementation_use;
uint32 _predecessor_volume_descriptor_sequence_location;
uint16 _flags;
char _reserved[22];
array<uint8, 22> _reserved;
} __attribute__((packed));