latest SDK
This commit is contained in:
103
foobar2000/helpers/filetimetools.cpp
Normal file
103
foobar2000/helpers/filetimetools.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#error PORTME
|
||||
#endif
|
||||
|
||||
#include "filetimetools.h"
|
||||
|
||||
static bool is_spacing(char c) {return c == ' ' || c==10 || c==13 || c == '\t';}
|
||||
|
||||
static bool is_spacing(const char * str, t_size len) {
|
||||
for(t_size walk = 0; walk < len; ++walk) if (!is_spacing(str[walk])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef exception_io_data exception_time_error;
|
||||
|
||||
static unsigned ParseDateElem(const char * ptr, t_size len) {
|
||||
unsigned ret = 0;
|
||||
for(t_size walk = 0; walk < len; ++walk) {
|
||||
const char c = ptr[walk];
|
||||
if (c < '0' || c > '9') throw exception_time_error();
|
||||
ret = ret * 10 + (unsigned)(c - '0');
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
t_filetimestamp foobar2000_io::filetimestamp_from_string(const char * date) {
|
||||
// Accepted format
|
||||
// YYYY-MM-DD HH:MM:SS
|
||||
try {
|
||||
t_size remaining = strlen(date);
|
||||
SYSTEMTIME st = {};
|
||||
st.wDay = 1; st.wMonth = 1;
|
||||
for(;;) {
|
||||
#define ADVANCE(n) { PFC_ASSERT( remaining >= n); date += n; remaining -= n; }
|
||||
#define ADVANCE_TEST(n) { if (remaining < n) throw exception_time_error(); }
|
||||
#define PARSE(var, digits) { ADVANCE_TEST(digits); var = (WORD) ParseDateElem(date, digits); ADVANCE(digits) ; }
|
||||
#define TEST_END( durationIncrement )
|
||||
#define SKIP(c) { ADVANCE_TEST(1); if (date[0] != c) throw exception_time_error(); ADVANCE(1); }
|
||||
#define SKIP_SPACING() {while(remaining > 0 && is_spacing(*date)) ADVANCE(1);}
|
||||
SKIP_SPACING();
|
||||
PARSE( st.wYear, 4 ); if (st.wYear < 1601) throw exception_time_error();
|
||||
TEST_END(wYear); SKIP('-');
|
||||
PARSE( st.wMonth, 2 ); if (st.wMonth < 1 || st.wMonth > 12) throw exception_time_error();
|
||||
TEST_END(wMonth); SKIP('-');
|
||||
PARSE( st.wDay, 2); if (st.wDay < 1 || st.wDay > 31) throw exception_time_error();
|
||||
TEST_END(wDay); SKIP(' ');
|
||||
PARSE( st.wHour, 2); if (st.wHour >= 24) throw exception_time_error();
|
||||
TEST_END(wHour); SKIP(':');
|
||||
PARSE( st.wMinute, 2); if (st.wMinute >= 60) throw exception_time_error();
|
||||
TEST_END(wMinute); SKIP(':');
|
||||
PARSE( st.wSecond, 2); if (st.wSecond >= 60) throw exception_time_error();
|
||||
SKIP_SPACING();
|
||||
TEST_END( wSecond );
|
||||
#undef ADVANCE
|
||||
#undef ADVANCE_TEST
|
||||
#undef PARSE
|
||||
#undef TEST_END
|
||||
#undef SKIP
|
||||
#undef SKIP_SPACING
|
||||
if (remaining > 0) throw exception_time_error();
|
||||
break;
|
||||
}
|
||||
t_filetimestamp base, out;
|
||||
if (!SystemTimeToFileTime(&st, (FILETIME*) &base)) throw exception_time_error();
|
||||
if (!LocalFileTimeToFileTime((const FILETIME*)&base, (FILETIME*)&out)) throw exception_time_error();
|
||||
return out;
|
||||
} catch(exception_time_error) {
|
||||
return filetimestamp_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
static const char g_invalidMsg[] = "<invalid timestamp>";
|
||||
|
||||
format_filetimestamp::format_filetimestamp(t_filetimestamp p_timestamp) {
|
||||
try {
|
||||
SYSTEMTIME st; FILETIME ft;
|
||||
if (FileTimeToLocalFileTime((FILETIME*)&p_timestamp,&ft)) {
|
||||
if (FileTimeToSystemTime(&ft,&st)) {
|
||||
m_buffer
|
||||
<< pfc::format_uint(st.wYear,4) << "-" << pfc::format_uint(st.wMonth,2) << "-" << pfc::format_uint(st.wDay,2) << " "
|
||||
<< pfc::format_uint(st.wHour,2) << ":" << pfc::format_uint(st.wMinute,2) << ":" << pfc::format_uint(st.wSecond,2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch(...) {}
|
||||
m_buffer = g_invalidMsg;
|
||||
}
|
||||
|
||||
format_filetimestamp_utc::format_filetimestamp_utc(t_filetimestamp p_timestamp) {
|
||||
try {
|
||||
SYSTEMTIME st;
|
||||
if (FileTimeToSystemTime((const FILETIME*)&p_timestamp,&st)) {
|
||||
m_buffer
|
||||
<< pfc::format_uint(st.wYear,4) << "-" << pfc::format_uint(st.wMonth,2) << "-" << pfc::format_uint(st.wDay,2) << " "
|
||||
<< pfc::format_uint(st.wHour,2) << ":" << pfc::format_uint(st.wMinute,2) << ":" << pfc::format_uint(st.wSecond,2);
|
||||
return;
|
||||
}
|
||||
} catch(...) {}
|
||||
m_buffer = g_invalidMsg;
|
||||
}
|
||||
Reference in New Issue
Block a user