mirror of
https://github.com/holub/mame
synced 2025-05-28 08:33:05 +03:00
Created a more flexible imgtool::datetime structure for use within Imgtool (#2263)
* Created a more flexible imgtool::datetime structure for use within Imgtool This is intended to replace most usage of time_t * Changing the granularity of imgtool_clock from 1ms to 100ns, as per Vas' suggestion * Created arbitrary_datetime in timeconv.h to facilitate interpretation of datetime info I concluded that invoking std::mktime on manually assembled std::tm is bad, because it is indeterminate how the std::tm members may be "dominant". This required that I go further in imgtool, and update a number of drivers and eliminate the parameter of imgtool::datetime that takes std::tm.
This commit is contained in:
parent
78c658c7a2
commit
86f50b0d65
@ -34,6 +34,21 @@ extern std::chrono::system_clock::duration system_clock_adjustment;
|
||||
typedef std::chrono::duration<std::uint64_t, std::ratio<1, 10000000> > ntfs_duration;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// arbitrary_datetime
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct arbitrary_datetime
|
||||
{
|
||||
int year; // absolute year (1900 AD = 1900)
|
||||
int month; // month (1-12)
|
||||
int day_of_month; // day of month (1-31)
|
||||
int hour; // hour (0-23)
|
||||
int minute; // minute (0-59)
|
||||
int second; // second (0-59)
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// arbitrary_clock - an std::chrono clock that "knows" the
|
||||
// date of the epoch's begining
|
||||
@ -54,6 +69,17 @@ public:
|
||||
static constexpr int base_minute = N;
|
||||
static constexpr int base_second = S;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// from_arbitrary_datetime - converts an
|
||||
// from_arbitrary_datetime to this arbitrary_clock's scale
|
||||
//---------------------------------------------------------
|
||||
|
||||
static time_point from_arbitrary_datetime(const arbitrary_datetime &dt, bool clamp)
|
||||
{
|
||||
return time_point(duration_from_arbitrary_datetime(dt, clamp));
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// from_arbitrary_time_point - converts an arbitrary_clock
|
||||
// with a different scale to this arbitrary_clock's scale
|
||||
@ -62,13 +88,15 @@ public:
|
||||
template<typename Rep2, int Y2, int M2, int D2, int H2, int N2, int S2, typename Ratio2>
|
||||
static time_point from_arbitrary_time_point(const std::chrono::time_point<arbitrary_clock<Rep2, Y2, M2, D2, H2, N2, S2, Ratio2> > &tp)
|
||||
{
|
||||
const int64_t our_absolute_day = absolute_day(Y, M, D);
|
||||
const int64_t their_absolute_day = absolute_day(Y2, M2, D2);
|
||||
arbitrary_datetime dt;
|
||||
dt.year = Y2;
|
||||
dt.month = M2;
|
||||
dt.day_of_month = D2;
|
||||
dt.hour = H2;
|
||||
dt.minute = N2;
|
||||
dt.second = S2;
|
||||
|
||||
const auto our_fract_day = std::chrono::hours(H) + std::chrono::minutes(N) + std::chrono::seconds(S);
|
||||
const auto their_fract_day = std::chrono::hours(H2) + std::chrono::minutes(N2) + std::chrono::seconds(S2);
|
||||
|
||||
const std::chrono::duration<Rep, Ratio> adjustment(std::chrono::hours(24) * (their_absolute_day - our_absolute_day) + (their_fract_day - our_fract_day));
|
||||
const duration adjustment = duration_from_arbitrary_datetime(dt, false);
|
||||
const duration result_duration = std::chrono::duration_cast<duration>(tp.time_since_epoch() + adjustment);
|
||||
return time_point(result_duration);
|
||||
}
|
||||
@ -142,6 +170,46 @@ private:
|
||||
// end of every quadcentury
|
||||
typedef arbitrary_clock<std::int64_t, 1601, 1, 1, 0, 0, 0, std::ratio<1, 1> > tm_conversion_clock;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// clamp_or_throw
|
||||
//---------------------------------------------------------
|
||||
|
||||
static int clamp_or_throw(int value, int minimum, int maximum, bool clamp, const char *out_of_range_message)
|
||||
{
|
||||
if (value < minimum || value > maximum)
|
||||
{
|
||||
if (clamp)
|
||||
value = std::min(std::max(value, minimum), maximum);
|
||||
else
|
||||
throw std::out_of_range(out_of_range_message);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// duration_from_arbitrary_datetime - converts an
|
||||
// arbitrary_datetime to this arbitrary_clock's duration
|
||||
//---------------------------------------------------------
|
||||
|
||||
static duration duration_from_arbitrary_datetime(const arbitrary_datetime &dt, bool clamp)
|
||||
{
|
||||
// range checking
|
||||
const int month = clamp_or_throw(dt.month, 1, 12, clamp, "invalid dt.month");
|
||||
const int day_of_month = clamp_or_throw(dt.day_of_month, 1, gregorian_days_in_month(month, dt.year), clamp, "invalid dt.day_of_month");
|
||||
const int hour = clamp_or_throw(dt.hour, 0, 23, clamp, "invalid dt.hour");
|
||||
const int minute = clamp_or_throw(dt.minute, 0, 59, clamp, "invalid dt.minute");
|
||||
const int second = clamp_or_throw(dt.second, 0, 59, clamp, "invalid dt.second");
|
||||
|
||||
const int64_t our_absolute_day = absolute_day(Y, M, D);
|
||||
const int64_t their_absolute_day = absolute_day(dt.year, month, day_of_month);
|
||||
|
||||
const auto our_fract_day = std::chrono::hours(H) + std::chrono::minutes(N) + std::chrono::seconds(S);
|
||||
const auto their_fract_day = std::chrono::hours(hour) + std::chrono::minutes(minute) + std::chrono::seconds(second);
|
||||
|
||||
return std::chrono::duration<Rep, Ratio>(std::chrono::hours(24) * (their_absolute_day - our_absolute_day) + (their_fract_day - our_fract_day));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// internal_to_tm - formats a structure of type 'struct tm'
|
||||
// based on a normalized clock
|
||||
|
@ -752,6 +752,77 @@ void imgtool::partition::get_attribute_name(uint32_t attribute, const imgtool_at
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// test_imgtool_datetime - unit test for imgtool::datetime
|
||||
//-------------------------------------------------
|
||||
|
||||
static bool test_imgtool_datetime(int second, int minute, int hour, int day_of_month, int month, int year)
|
||||
{
|
||||
bool error = false;
|
||||
|
||||
util::arbitrary_datetime t;
|
||||
t.second = second;
|
||||
t.minute = minute;
|
||||
t.hour = hour;
|
||||
t.day_of_month = day_of_month;
|
||||
t.month = month;
|
||||
t.year = year;
|
||||
|
||||
imgtool::datetime dt(imgtool::datetime::datetime_type::GMT, t);
|
||||
std::tm t2 = dt.gmtime();
|
||||
|
||||
if (t2.tm_sec != second)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_sec to be %d, instead got %d\n", second, t2.tm_sec);
|
||||
error = true;
|
||||
}
|
||||
if (t2.tm_min != minute)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_min to be %d, instead got %d\n", minute, t2.tm_min);
|
||||
error = true;
|
||||
}
|
||||
if (t2.tm_hour != hour)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_hour to be %d, instead got %d\n", hour, t2.tm_hour);
|
||||
error = true;
|
||||
}
|
||||
if (t2.tm_mday != day_of_month)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mday to be %d, instead got %d\n", day_of_month, t2.tm_mday);
|
||||
error = true;
|
||||
}
|
||||
if (t2.tm_mon != month - 1)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mon to be %d, instead got %d\n", month - 1, t2.tm_mon);
|
||||
error = true;
|
||||
}
|
||||
if (t2.tm_year != year - 1900)
|
||||
{
|
||||
util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mon to be %d, instead got %d\n", year - 1900, t2.tm_year);
|
||||
error = true;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// test_imgtool_datetime - unit tests for imgtool::datetime
|
||||
//-------------------------------------------------
|
||||
|
||||
static bool test_imgtool_datetime()
|
||||
{
|
||||
bool error = false;
|
||||
|
||||
// various test cases for imgtool::datetime
|
||||
if (test_imgtool_datetime(34, 23, 12, 18, 3, 1993)) // March 18th, 1993 12:23:34
|
||||
error = true;
|
||||
if (test_imgtool_datetime(0, 20, 16, 25, 12, 1976)) // December 25th, 1976 16:20:00
|
||||
error = true;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// imgtool_validitychecks - checks the validity
|
||||
// of the imgtool modules
|
||||
@ -764,6 +835,10 @@ bool imgtool_validitychecks(void)
|
||||
imgtool_module_features features;
|
||||
int created_library = false;
|
||||
|
||||
// various test cases for imgtool::datetime
|
||||
if (test_imgtool_datetime())
|
||||
error = true;
|
||||
|
||||
if (!global_imgtool_library)
|
||||
{
|
||||
imgtool_init(false, nullptr);
|
||||
@ -2290,12 +2365,12 @@ imgtoolerr_t imgtool::directory::get_next(imgtool_dirent &ent)
|
||||
}
|
||||
|
||||
// don't trust the module!
|
||||
if (!m_partition.m_supports_creation_time && (ent.creation_time != 0))
|
||||
if (!m_partition.m_supports_creation_time && (ent.creation_time.type() != imgtool::datetime::datetime_type::NONE))
|
||||
{
|
||||
internal_error(nullptr, "next_enum() specified creation_time, which is marked as unsupported by this module");
|
||||
return IMGTOOLERR_UNEXPECTED;
|
||||
}
|
||||
if (!m_partition.m_supports_lastmodified_time && (ent.lastmodified_time != 0))
|
||||
if (!m_partition.m_supports_lastmodified_time && (ent.lastmodified_time.type() != imgtool::datetime::datetime_type::NONE))
|
||||
{
|
||||
internal_error(nullptr, "next_enum() specified lastmodified_time, which is marked as unsupported by this module");
|
||||
return IMGTOOLERR_UNEXPECTED;
|
||||
|
@ -18,6 +18,126 @@
|
||||
|
||||
namespace imgtool {
|
||||
|
||||
datetime::imgtool_clock::duration datetime::s_gmt_offset = datetime::calculate_gmt_offset();
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime ctor
|
||||
//-------------------------------------------------
|
||||
|
||||
datetime::datetime(datetime_type type, std::chrono::time_point<std::chrono::system_clock> tp)
|
||||
: m_type(type)
|
||||
, m_time_point(imgtool_clock::from_system_clock(tp))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime ctor
|
||||
//-------------------------------------------------
|
||||
|
||||
datetime::datetime(datetime_type type, time_t t)
|
||||
: datetime(type, std::chrono::system_clock::from_time_t(t))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime ctor
|
||||
//-------------------------------------------------
|
||||
|
||||
datetime::datetime(datetime_type type, const util::arbitrary_datetime &dt, bool clamp)
|
||||
: m_type(type)
|
||||
, m_time_point(imgtool_clock::from_arbitrary_datetime(dt, clamp))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime::now
|
||||
//-------------------------------------------------
|
||||
|
||||
datetime datetime::now(datetime_type type)
|
||||
{
|
||||
return imgtool::datetime(
|
||||
type,
|
||||
std::chrono::system_clock::now());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime::localtime
|
||||
//-------------------------------------------------
|
||||
|
||||
std::tm datetime::localtime() const
|
||||
{
|
||||
imgtool_clock::time_point tp;
|
||||
|
||||
switch (type())
|
||||
{
|
||||
case datetime_type::LOCAL:
|
||||
tp = time_point();
|
||||
break;
|
||||
case datetime_type::GMT:
|
||||
tp = time_point() + s_gmt_offset;
|
||||
break;
|
||||
default:
|
||||
tp = imgtool_clock::time_point();
|
||||
break;
|
||||
}
|
||||
return imgtool_clock::to_tm(tp);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime::gmtime
|
||||
//-------------------------------------------------
|
||||
|
||||
std::tm datetime::gmtime() const
|
||||
{
|
||||
imgtool_clock::time_point tp;
|
||||
|
||||
switch (type())
|
||||
{
|
||||
case datetime_type::GMT:
|
||||
tp = time_point();
|
||||
break;
|
||||
case datetime_type::LOCAL:
|
||||
tp = time_point() - s_gmt_offset;
|
||||
break;
|
||||
default:
|
||||
tp = imgtool_clock::time_point();
|
||||
break;
|
||||
}
|
||||
return imgtool_clock::to_tm(tp);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime::calculate_gmt_offset
|
||||
//-------------------------------------------------
|
||||
|
||||
datetime::imgtool_clock::duration datetime::calculate_gmt_offset()
|
||||
{
|
||||
time_t t = time(nullptr);
|
||||
std::tm utc_tm = *std::gmtime(&t);
|
||||
time_t utc = mktime(&utc_tm);
|
||||
std::tm local_tm = *std::localtime(&t);
|
||||
time_t local = mktime(&local_tm);
|
||||
double d = difftime(local, utc) * imgtool_clock::period::den / imgtool_clock::period::num;
|
||||
return imgtool_clock::duration((std::int64_t) d);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// datetime::to_time_t
|
||||
//-------------------------------------------------
|
||||
|
||||
time_t datetime::to_time_t() const
|
||||
{
|
||||
auto system_clock_tp = imgtool_clock::to_system_clock(time_point());
|
||||
return std::chrono::system_clock::to_time_t(system_clock_tp);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ctor
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <time.h>
|
||||
#include <list>
|
||||
#include <chrono>
|
||||
|
||||
#include "corestr.h"
|
||||
#include "opresolv.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "unicode.h"
|
||||
#include "charconv.h"
|
||||
#include "pool.h"
|
||||
#include "timeconv.h"
|
||||
|
||||
namespace imgtool
|
||||
{
|
||||
@ -55,15 +57,78 @@ union filterinfo
|
||||
|
||||
typedef void (*filter_getinfoproc)(uint32_t state, union filterinfo *info);
|
||||
|
||||
namespace imgtool
|
||||
{
|
||||
class datetime
|
||||
{
|
||||
public:
|
||||
typedef util::arbitrary_clock<std::int64_t, 1600, 1, 1, 0, 0, 0, std::ratio<1, 10000000> > imgtool_clock;
|
||||
|
||||
enum datetime_type
|
||||
{
|
||||
NONE,
|
||||
LOCAL,
|
||||
GMT
|
||||
};
|
||||
|
||||
datetime()
|
||||
: m_type(datetime_type::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<typename Rep, int Y, int M, int D, int H, int N, int S, typename Ratio>
|
||||
datetime(datetime_type type, std::chrono::time_point<util::arbitrary_clock<Rep, Y, M, D, H, N, S, Ratio> > tp)
|
||||
: m_type(type)
|
||||
, m_time_point(imgtool_clock::from_arbitrary_time_point(tp))
|
||||
{
|
||||
}
|
||||
|
||||
datetime(datetime_type type, std::chrono::time_point<std::chrono::system_clock> tp);
|
||||
datetime(datetime_type type, time_t t);
|
||||
datetime(datetime_type type, const util::arbitrary_datetime &dt, bool clamp = true);
|
||||
datetime(const datetime &that) = default;
|
||||
datetime(datetime &&that) = default;
|
||||
|
||||
// accessors
|
||||
datetime_type type() const { return m_type; }
|
||||
bool empty() const { return type() == datetime_type::NONE; }
|
||||
std::chrono::time_point<imgtool_clock> time_point() const { return m_time_point; }
|
||||
|
||||
// operators
|
||||
datetime &operator =(const datetime &that)
|
||||
{
|
||||
m_type = that.m_type;
|
||||
m_time_point = that.m_time_point;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// returns the current time
|
||||
static datetime now(datetime_type type);
|
||||
|
||||
// returns time structures
|
||||
std::tm localtime() const;
|
||||
std::tm gmtime() const;
|
||||
time_t to_time_t() const;
|
||||
|
||||
private:
|
||||
static imgtool_clock::duration s_gmt_offset;
|
||||
datetime_type m_type;
|
||||
std::chrono::time_point<imgtool_clock> m_time_point;
|
||||
|
||||
static imgtool_clock::duration calculate_gmt_offset();
|
||||
};
|
||||
};
|
||||
|
||||
struct imgtool_dirent
|
||||
{
|
||||
char filename[1024];
|
||||
char attr[64];
|
||||
uint64_t filesize;
|
||||
|
||||
time_t creation_time;
|
||||
time_t lastmodified_time;
|
||||
time_t lastaccess_time;
|
||||
imgtool::datetime creation_time;
|
||||
imgtool::datetime lastmodified_time;
|
||||
imgtool::datetime lastaccess_time;
|
||||
|
||||
char softlink[1024];
|
||||
char comment[256];
|
||||
|
@ -234,9 +234,11 @@ static int cmd_dir(const struct command *c, int argc, char *argv[])
|
||||
? "<DIR>"
|
||||
: string_format("%u", (unsigned int) ent.filesize);
|
||||
|
||||
if (ent.lastmodified_time != 0)
|
||||
strftime(last_modified, sizeof(last_modified), "%d-%b-%y %H:%M:%S",
|
||||
localtime(&ent.lastmodified_time));
|
||||
if (!ent.lastmodified_time.empty())
|
||||
{
|
||||
std::tm t = ent.lastmodified_time.localtime();
|
||||
strftime(last_modified, sizeof(last_modified), "%d-%b-%y %H:%M:%S", &t);
|
||||
}
|
||||
|
||||
if (ent.hardlink)
|
||||
strcat(ent.filename, " <hl>");
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Dirk Best
|
||||
/****************************************************************************
|
||||
|
||||
amiga.c
|
||||
amiga.cpp
|
||||
|
||||
Amiga floppies
|
||||
|
||||
@ -290,15 +290,11 @@ static int is_leap(int year)
|
||||
|
||||
|
||||
/* Convert amiga time to standard time */
|
||||
static time_t amiga_crack_time(amiga_date *date)
|
||||
static imgtool::datetime amiga_crack_time(amiga_date *date)
|
||||
{
|
||||
int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
int year = 1978, month = 1, year_days = 365; /* base date */
|
||||
int day = date->days;
|
||||
struct tm t;
|
||||
|
||||
/* initialize struct */
|
||||
memset(&t, 0, sizeof(t));
|
||||
|
||||
/* first calculate the year */
|
||||
while (day >= year_days)
|
||||
@ -316,15 +312,16 @@ static time_t amiga_crack_time(amiga_date *date)
|
||||
month++;
|
||||
}
|
||||
|
||||
/* fill the struct with our calculated values */
|
||||
t.tm_year = year - 1900;
|
||||
t.tm_mon = month - 1;
|
||||
t.tm_mday = day + 1;
|
||||
t.tm_hour = date->mins / 60;
|
||||
t.tm_min = date->mins % 60;
|
||||
t.tm_sec = date->ticks / 50;
|
||||
// fill the struct with our calculated values
|
||||
util::arbitrary_datetime dt;
|
||||
dt.year = year;
|
||||
dt.month = month;
|
||||
dt.day_of_month = day;
|
||||
dt.hour = date->mins / 60;
|
||||
dt.minute = date->mins % 60;
|
||||
dt.second = date->ticks / 50;
|
||||
|
||||
return mktime(&t);
|
||||
return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
|
||||
}
|
||||
|
||||
|
||||
@ -1785,9 +1782,9 @@ static void amiga_image_info(imgtool::image &img, std::ostream &stream)
|
||||
ret = read_root_block(img, &root);
|
||||
if (ret) return;
|
||||
|
||||
t_c = amiga_crack_time(&root.c);
|
||||
t_v = amiga_crack_time(&root.v);
|
||||
t_r = amiga_crack_time(&root.r);
|
||||
t_c = amiga_crack_time(&root.c).to_time_t();
|
||||
t_v = amiga_crack_time(&root.v).to_time_t();
|
||||
t_r = amiga_crack_time(&root.r).to_time_t();
|
||||
|
||||
strftime(c, sizeof(c), "%d-%b-%y %H:%M:%S", localtime(&t_c));
|
||||
strftime(v, sizeof(v), "%d-%b-%y %H:%M:%S", localtime(&t_v));
|
||||
|
@ -64,15 +64,19 @@ static cybiko_file_system *get_cfs(imgtool::image &image)
|
||||
}
|
||||
|
||||
// 2208988800 is the number of seconds between 1900/01/01 and 1970/01/01
|
||||
typedef util::arbitrary_clock<std::uint32_t, 1900, 1, 1, 0, 0, 0, std::ratio<1, 1> > cybiko_clock;
|
||||
|
||||
static time_t time_crack( uint32_t cfs_time)
|
||||
imgtool::datetime cybiko_time_crack(uint32_t cfs_time)
|
||||
{
|
||||
return (time_t)(cfs_time - 2208988800UL);
|
||||
cybiko_clock::duration d(cfs_time);
|
||||
std::chrono::time_point<cybiko_clock> tp(d);
|
||||
return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, tp);
|
||||
}
|
||||
|
||||
static uint32_t time_setup( time_t ansi_time)
|
||||
uint32_t cybiko_time_setup(const imgtool::datetime &t)
|
||||
{
|
||||
return (uint32_t)(ansi_time + 2208988800UL);
|
||||
auto cybiko_time_point = cybiko_clock::from_arbitrary_time_point(t.time_point());
|
||||
return cybiko_time_point.time_since_epoch().count();
|
||||
}
|
||||
|
||||
static uint32_t buffer_read_32_be( uint8_t *buffer)
|
||||
@ -412,7 +416,7 @@ static imgtoolerr_t cybiko_image_next_enum(imgtool::directory &enumeration, imgt
|
||||
{
|
||||
strcpy(ent.filename, file.name);
|
||||
ent.filesize = file.size;
|
||||
ent.lastmodified_time = time_crack(file.date);
|
||||
ent.lastmodified_time = cybiko_time_crack(file.date);
|
||||
ent.filesize = file.size;
|
||||
}
|
||||
else
|
||||
@ -501,7 +505,7 @@ static imgtoolerr_t cybiko_image_write_file(imgtool::partition &partition, const
|
||||
{
|
||||
buffer[6] = 0;
|
||||
strcpy(BLOCK_FILENAME(buffer), filename);
|
||||
buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, time_setup( time( NULL)));
|
||||
buffer_write_32_be(buffer + 6 + FILE_HEADER_SIZE - 4, cybiko_time_setup(imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL)));
|
||||
sourcef.read(buffer + 6 + FILE_HEADER_SIZE, buffer[1]);
|
||||
}
|
||||
else
|
||||
|
@ -55,17 +55,8 @@ static cybiko_file_system *get_cfs(imgtool::image &image)
|
||||
return (cybiko_file_system*)image.extra_bytes();
|
||||
}
|
||||
|
||||
// 2208988800 is the number of seconds between 1900/01/01 and 1970/01/01
|
||||
|
||||
static time_t time_crack( uint32_t cfs_time)
|
||||
{
|
||||
return (time_t)(cfs_time - 2208988800UL);
|
||||
}
|
||||
|
||||
static uint32_t time_setup( time_t ansi_time)
|
||||
{
|
||||
return (uint32_t)(ansi_time + 2208988800UL);
|
||||
}
|
||||
extern imgtool::datetime cybiko_time_crack(uint32_t cfs_time);
|
||||
extern uint32_t cybiko_time_setup(const imgtool::datetime &t);
|
||||
|
||||
static uint32_t buffer_read_32_be( uint8_t *buffer)
|
||||
{
|
||||
@ -382,7 +373,7 @@ static imgtoolerr_t cybiko_image_next_enum(imgtool::directory &enumeration, imgt
|
||||
{
|
||||
strcpy(ent.filename, file.name);
|
||||
ent.filesize = file.size;
|
||||
ent.lastmodified_time = time_crack(file.date);
|
||||
ent.lastmodified_time = cybiko_time_crack(file.date);
|
||||
ent.filesize = file.size;
|
||||
}
|
||||
else
|
||||
@ -475,7 +466,7 @@ static imgtoolerr_t cybiko_image_write_file(imgtool::partition &partition, const
|
||||
{
|
||||
buffer[6] = 0x20;
|
||||
strcpy(BLOCK_FILENAME(buffer), filename);
|
||||
buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, time_setup( time( NULL)));
|
||||
buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, cybiko_time_setup(imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL)));
|
||||
sourcef.read(buffer + 6 + FILE_HEADER_SIZE, buffer[1]);
|
||||
}
|
||||
else
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Raphael Nabet
|
||||
/****************************************************************************
|
||||
|
||||
fat.c
|
||||
fat.cpp
|
||||
|
||||
PC FAT disk images
|
||||
|
||||
@ -184,8 +184,8 @@ struct fat_dirent
|
||||
uint32_t first_cluster;
|
||||
uint32_t dirent_sector_index;
|
||||
uint32_t dirent_sector_offset;
|
||||
time_t creation_time;
|
||||
time_t lastmodified_time;
|
||||
imgtool::datetime creation_time;
|
||||
imgtool::datetime lastmodified_time;
|
||||
};
|
||||
|
||||
struct fat_freeentry_info
|
||||
@ -1241,33 +1241,25 @@ static void fat_cannonicalize_sfn(char *sfn, const uint8_t *sfn_bytes)
|
||||
|
||||
|
||||
|
||||
static time_t fat_crack_time(uint32_t fat_time)
|
||||
static imgtool::datetime fat_crack_time(uint32_t fat_time)
|
||||
{
|
||||
struct tm t;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
t = *localtime(&now);
|
||||
|
||||
t.tm_sec = ((fat_time >> 0) & 0x001F) * 2;
|
||||
t.tm_min = ((fat_time >> 5) & 0x003F);
|
||||
t.tm_hour = ((fat_time >> 11) & 0x001F);
|
||||
t.tm_mday = ((fat_time >> 16) & 0x001F);
|
||||
t.tm_mon = ((fat_time >> 21) & 0x000F);
|
||||
t.tm_year = ((fat_time >> 25) & 0x007F) + 1980 - 1900;
|
||||
|
||||
return mktime(&t);
|
||||
util::arbitrary_datetime dt;
|
||||
dt.second = ((fat_time >> 0) & 0x001F) * 2;
|
||||
dt.minute = ((fat_time >> 5) & 0x003F);
|
||||
dt.hour = ((fat_time >> 11) & 0x001F);
|
||||
dt.day_of_month = ((fat_time >> 16) & 0x001F);
|
||||
dt.month = ((fat_time >> 21) & 0x000F);
|
||||
dt.year = ((fat_time >> 25) & 0x007F) + 1980;
|
||||
return imgtool::datetime(imgtool::datetime::LOCAL, dt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint32_t fat_setup_time(time_t ansi_time)
|
||||
{
|
||||
struct tm t;
|
||||
std::tm t = *localtime(&ansi_time);
|
||||
|
||||
uint32_t result = 0;
|
||||
|
||||
t = *localtime(&ansi_time);
|
||||
|
||||
result |= (((uint32_t) (t.tm_sec / 2)) & 0x001F) << 0;
|
||||
result |= (((uint32_t) t.tm_min) & 0x003F) << 5;
|
||||
result |= (((uint32_t) t.tm_hour) & 0x001F) << 11;
|
||||
|
@ -5827,10 +5827,10 @@ static imgtoolerr_t mac_image_getattrs(imgtool::partition &partition, const char
|
||||
break;
|
||||
|
||||
case IMGTOOLATTR_TIME_CREATED:
|
||||
values[i].t = mac_crack_time(cat_info.createDate);
|
||||
values[i].t = mac_crack_time(cat_info.createDate).to_time_t();
|
||||
break;
|
||||
case IMGTOOLATTR_TIME_LASTMODIFIED:
|
||||
values[i].t = mac_crack_time(cat_info.modifyDate);
|
||||
values[i].t = mac_crack_time(cat_info.modifyDate).to_time_t();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -323,8 +323,8 @@ static imgtoolerr_t macbinary_writefile(imgtool::partition &partition, const cha
|
||||
return err;
|
||||
|
||||
/* set up attributes */
|
||||
attr_values[0].t = mac_crack_time(creation_time);
|
||||
attr_values[1].t = mac_crack_time(lastmodified_time);
|
||||
attr_values[0].t = mac_crack_time(creation_time).to_time_t();
|
||||
attr_values[1].t = mac_crack_time(lastmodified_time).to_time_t();
|
||||
attr_values[2].i = type_code;
|
||||
attr_values[3].i = creator_code;
|
||||
attr_values[4].i = finder_flags;
|
||||
|
@ -15,32 +15,54 @@
|
||||
|
||||
typedef util::arbitrary_clock<std::uint32_t, 1904, 1, 1, 0, 0, 0, std::ratio<1, 1> > classic_mac_clock;
|
||||
|
||||
time_t mac_crack_time(uint32_t t)
|
||||
//-------------------------------------------------
|
||||
// mac_crack_time
|
||||
//-------------------------------------------------
|
||||
|
||||
imgtool::datetime mac_crack_time(uint32_t t)
|
||||
{
|
||||
classic_mac_clock::duration d(t);
|
||||
std::chrono::time_point<std::chrono::system_clock> tp = classic_mac_clock::to_system_clock(std::chrono::time_point<classic_mac_clock>(d));
|
||||
return std::chrono::system_clock::to_time_t(tp);
|
||||
std::chrono::time_point<classic_mac_clock> tp(d);
|
||||
return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, tp);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mac_setup_time
|
||||
//-------------------------------------------------
|
||||
|
||||
uint32_t mac_setup_time(time_t t)
|
||||
uint32_t mac_setup_time(const imgtool::datetime &t)
|
||||
{
|
||||
auto system_time_point = std::chrono::system_clock::from_time_t(t);
|
||||
auto mac_time_point = classic_mac_clock::from_system_clock(system_time_point);
|
||||
auto mac_time_point = classic_mac_clock::from_arbitrary_time_point(t.time_point());
|
||||
return mac_time_point.time_since_epoch().count();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mac_setup_time
|
||||
//-------------------------------------------------
|
||||
|
||||
uint32_t mac_time_now(void)
|
||||
uint32_t mac_setup_time(time_t t)
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
return mac_setup_time(now);
|
||||
imgtool::datetime dt(imgtool::datetime::datetime_type::LOCAL, t);
|
||||
return mac_setup_time(dt);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mac_time_now
|
||||
//-------------------------------------------------
|
||||
|
||||
uint32_t mac_time_now(void)
|
||||
{
|
||||
imgtool::datetime dt = imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL);
|
||||
return mac_setup_time(dt);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mac_identify_fork
|
||||
//-------------------------------------------------
|
||||
|
||||
imgtoolerr_t mac_identify_fork(const char *fork_string, mac_fork_t *fork_num)
|
||||
{
|
||||
|
@ -29,7 +29,8 @@ enum mac_filecategory_t
|
||||
|
||||
|
||||
/* converting Classic Mac OS time <==> Imgtool time */
|
||||
time_t mac_crack_time(uint32_t t);
|
||||
imgtool::datetime mac_crack_time(uint32_t t);
|
||||
uint32_t mac_setup_time(const imgtool::datetime &t);
|
||||
uint32_t mac_setup_time(time_t t);
|
||||
uint32_t mac_time_now(void);
|
||||
|
||||
|
@ -186,24 +186,19 @@ enum creation_policy_t
|
||||
|
||||
|
||||
|
||||
static time_t prodos_crack_time(uint32_t prodos_time)
|
||||
static imgtool::datetime prodos_crack_time(uint32_t prodos_time)
|
||||
{
|
||||
struct tm t;
|
||||
time_t now;
|
||||
util::arbitrary_datetime dt;
|
||||
dt.second = 0;
|
||||
dt.minute = ((prodos_time >> 16) & 0x3F);
|
||||
dt.hour = ((prodos_time >> 24) & 0x1F);
|
||||
dt.day_of_month = ((prodos_time >> 0) & 0x1F);
|
||||
dt.month = ((prodos_time >> 5) & 0x0F) + 1;
|
||||
dt.year = ((prodos_time >> 9) & 0x7F) + 1900;
|
||||
if (dt.year <= 1949)
|
||||
dt.year += 100;
|
||||
|
||||
time(&now);
|
||||
t = *localtime(&now);
|
||||
|
||||
t.tm_sec = 0;
|
||||
t.tm_min = (prodos_time >> 16) & 0x3F;
|
||||
t.tm_hour = (prodos_time >> 24) & 0x1F;
|
||||
t.tm_mday = (prodos_time >> 0) & 0x1F;
|
||||
t.tm_mon = (prodos_time >> 5) & 0x0F;
|
||||
t.tm_year = (prodos_time >> 9) & 0x7F;
|
||||
|
||||
if (t.tm_year <= 49)
|
||||
t.tm_year += 100;
|
||||
return mktime(&t);
|
||||
return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
|
||||
}
|
||||
|
||||
|
||||
@ -2039,10 +2034,10 @@ static imgtoolerr_t prodos_diskimage_getattrs(imgtool::partition &partition, con
|
||||
break;
|
||||
|
||||
case IMGTOOLATTR_TIME_CREATED:
|
||||
values[i].t = prodos_crack_time(ent.creation_time);
|
||||
values[i].t = prodos_crack_time(ent.creation_time).to_time_t();
|
||||
break;
|
||||
case IMGTOOLATTR_TIME_LASTMODIFIED:
|
||||
values[i].t = prodos_crack_time(ent.lastmodified_time);
|
||||
values[i].t = prodos_crack_time(ent.lastmodified_time).to_time_t();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -485,24 +485,20 @@ static void thom_conv_filename(const char* s, char name[9], char ext[4])
|
||||
}
|
||||
}
|
||||
|
||||
static time_t thom_crack_time(thom_dirent* d)
|
||||
static imgtool::datetime thom_crack_time(thom_dirent* d)
|
||||
{
|
||||
struct tm t;
|
||||
time_t now;
|
||||
|
||||
/* check */
|
||||
if ( d->day < 1 || d->day > 31 || d->month < 1 || d->month > 12 ) return 0;
|
||||
if ( d->day < 1 || d->day > 31 || d->month < 1 || d->month > 12 ) return imgtool::datetime();
|
||||
|
||||
/* converts */
|
||||
time( &now );
|
||||
t = *localtime( &now );
|
||||
t.tm_sec = 0;
|
||||
t.tm_min = 0;
|
||||
t.tm_hour = 0;
|
||||
t.tm_mday = d->day;
|
||||
t.tm_mon = d->month - 1;
|
||||
t.tm_year = (d->year < 65 ) ? d->year + 100 : d->year;
|
||||
return mktime(&t);
|
||||
util::arbitrary_datetime dt;
|
||||
dt.second = 0;
|
||||
dt.minute = 0;
|
||||
dt.hour = 0;
|
||||
dt.day_of_month = d->day;
|
||||
dt.month = d->month;
|
||||
dt.year = d->year + (d->year < 65 ? 2000 : 1900);
|
||||
return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
|
||||
}
|
||||
|
||||
static void thom_make_time(thom_dirent* d, time_t time)
|
||||
|
Loading…
Reference in New Issue
Block a user