- 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:
parent
cd0f0e996d
commit
9b438e897c
@ -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()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user