pplx::task<Concurrency::streams::streambuf<_CharType>> OPEN_R(const utility::string_t &name) { #if !defined(__cplusplus_winrt) return Concurrency::streams::file_buffer<_CharType>::open(name, std::ios_base::in); #else auto file = pplx::create_task( KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); return Concurrency::streams::file_buffer<_CharType>::open(file, std::ios_base::in); #endif }
pplx::task<concurrency::streams::basic_istream<_CharType>> OPENSTR_R(const utility::string_t &name, std::ios_base::openmode mode = std::ios_base::in) { #if !defined(__cplusplus_winrt) return concurrency::streams::file_stream<_CharType>::open_istream(name, mode); #else auto file = pplx::create_task( KnownFolders::DocumentsLibrary->GetFileAsync( ref new Platform::String(name.c_str()))).get(); return concurrency::streams::file_stream<_CharType>::open_istream(file, mode); #endif }
pplx::task<Concurrency::streams::basic_ostream<_CharType>> OPENSTR_W(const utility::string_t &name, std::ios_base::openmode mode = std::ios_base::out) { #if !defined(__cplusplus_winrt) return Concurrency::streams::file_stream<_CharType>::open_ostream(name, mode); #else auto file = pplx::create_task( KnownFolders::DocumentsLibrary->CreateFileAsync( ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)).get(); return Concurrency::streams::file_stream<_CharType>::open_ostream(file, mode); #endif }
/// <summary> /// Returns a string representation of the datetime. The string is formatted based on RFC 1123 or ISO 8601 /// </summary> datetime __cdecl datetime::from_string(const utility::string_t& dateString, date_format format) { // avoid floating point math to preserve precision uint64_t ufrac_second = 0; #ifdef _MS_WINDOWS datetime result; if ( format == RFC_1123 ) { SYSTEMTIME sysTime = {0}; std::wstring month(3, L'\0'); std::wstring unused(3, L'\0'); const wchar_t * formatString = L"%3c, %2d %3c %4d %2d:%2d:%2d %3c"; auto n = swscanf_s(dateString.c_str(), formatString, unused.data(), unused.size(), &sysTime.wDay, month.data(), month.size(), &sysTime.wYear, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond, unused.data(), unused.size()); if (n == 8) { std::wstring monthnames[12] = {L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"}; auto loc = std::find_if(monthnames, monthnames+12, [&month](const std::wstring& m) { return m == month;}); if (loc != monthnames+12) { sysTime.wMonth = (short) ((loc - monthnames) + 1); if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } } else if ( format == ISO_8601 ) { // Unlike FILETIME, SYSTEMTIME does not have enough precision to hold seconds in 100 nanosecond // increments. Therefore, start with seconds and milliseconds set to 0, then add them separately // Try to extract the fractional second from the timestamp utility::string_t input; extract_fractional_second(dateString, input, ufrac_second); { SYSTEMTIME sysTime = { 0 }; const wchar_t * formatString = L"%4d-%2d-%2dT%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &sysTime.wYear, &sysTime.wMonth, &sysTime.wDay, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 3 || n == 6) { if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } { SYSTEMTIME sysTime = {0}; DWORD date = 0; const wchar_t * formatString = L"%8dT%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &date, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 1 || n == 4) { sysTime.wDay = date % 100; date /= 100; sysTime.wMonth = date % 100; date /= 100; sysTime.wYear = (WORD)date; if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } { SYSTEMTIME sysTime = {0}; GetSystemTime(&sysTime); // Fill date portion with today's information sysTime.wSecond = 0; sysTime.wMilliseconds = 0; const wchar_t * formatString = L"%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 3) { if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } } return datetime(); #else std::string input(dateString); struct tm output = tm(); if ( format == RFC_1123 ) { strptime(input.data(), "%a, %d %b %Y %H:%M:%S GMT", &output); } else { // Try to extract the fractional second from the timestamp utility::string_t input; extract_fractional_second(dateString, input, ufrac_second); auto result = strptime(input.data(), "%Y-%m-%dT%H:%M:%SZ", &output); if ( result == nullptr ) { result = strptime(input.data(), "%Y%m%dT%H:%M:%SZ", &output); } if ( result == nullptr ) { // Fill the date portion with the epoch, // strptime will do the rest memset(&output, 0, sizeof(struct tm)); output.tm_year = 70; output.tm_mon = 1; output.tm_mday = 1; result = strptime(input.data(), "%H:%M:%SZ", &output); } if ( result == nullptr ) { result = strptime(input.data(), "%Y-%m-%d", &output); } if ( result == nullptr ) { result = strptime(input.data(), "%Y%m%d", &output); } if ( result == nullptr ) { return datetime(); } } #if (defined(ANDROID) || defined(__ANDROID__)) // HACK: The (nonportable?) POSIX function timegm is not available in // bionic. As a workaround[1][2], we set the C library timezone to // UTC, call mktime, then set the timezone back. However, the C // environment is fundamentally a shared global resource and thread- // unsafe. We can protect our usage here, however any other code might // manipulate the environment at the same time. // // [1] http://linux.die.net/man/3/timegm // [2] http://www.gnu.org/software/libc/manual/html_node/Broken_002ddown-Time.html time_t time; static boost::mutex env_var_lock; { boost::lock_guard<boost::mutex> lock(env_var_lock); std::string prev_env; auto prev_env_cstr = getenv("TZ"); if (prev_env_cstr != nullptr) { prev_env = prev_env_cstr; } setenv("TZ", "UTC", 1); time = mktime(&output); if (prev_env_cstr) { setenv("TZ", prev_env.c_str(), 1); } else { unsetenv("TZ"); } } #else time_t time = timegm(&output); #endif struct timeval tv = timeval(); tv.tv_sec = time; tv.tv_usec = (unsigned int)ufrac_second; return timeval_to_datetime(tv); #endif }
/// <summary> /// Returns a string representation of the datetime. The string is formatted based on RFC 1123 or ISO 8601 /// </summary> datetime __cdecl datetime::from_string(const utility::string_t& dateString, date_format format) { // avoid floating point math to preserve precision uint64_t ufrac_second = 0; #ifdef _MS_WINDOWS datetime result; if ( format == RFC_1123 ) { SYSTEMTIME sysTime = {0}; std::wstring month(3, L'\0'); std::wstring unused(3, L'\0'); const wchar_t * formatString = L"%3c, %2d %3c %4d %2d:%2d:%2d %3c"; auto n = swscanf_s(dateString.c_str(), formatString, unused.data(), unused.size(), &sysTime.wDay, month.data(), month.size(), &sysTime.wYear, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond, unused.data(), unused.size()); if (n == 8) { std::wstring monthnames[12] = {L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"}; auto loc = std::find_if(monthnames, monthnames+12, [&month](const std::wstring& m) { return m == month;}); if (loc != monthnames+12) { sysTime.wMonth = (short) ((loc - monthnames) + 1); if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } } else if ( format == ISO_8601 ) { // Unlike FILETIME, SYSTEMTIME does not have enough precision to hold seconds in 100 nanosecond // increments. Therefore, start with seconds and milliseconds set to 0, then add them separately // Try to extract the fractional second from the timestamp utility::string_t input; extract_fractional_second(dateString, input, ufrac_second); { SYSTEMTIME sysTime = { 0 }; const wchar_t * formatString = L"%4d-%2d-%2dT%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &sysTime.wYear, &sysTime.wMonth, &sysTime.wDay, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 3 || n == 6) { if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } { SYSTEMTIME sysTime = {0}; DWORD date = 0; const wchar_t * formatString = L"%8dT%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &date, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 1 || n == 4) { sysTime.wDay = date % 100; date /= 100; sysTime.wMonth = date % 100; date /= 100; sysTime.wYear = (WORD)date; if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } { SYSTEMTIME sysTime = {0}; GetSystemTime(&sysTime); // Fill date portion with today's information sysTime.wSecond = 0; sysTime.wMilliseconds = 0; const wchar_t * formatString = L"%2d:%2d:%2dZ"; auto n = swscanf_s(input.c_str(), formatString, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); if (n == 3) { if (system_type_to_datetime(&sysTime, ufrac_second, &result)) { return result; } } } } return datetime(); #else std::string input(dateString); struct tm output = tm(); if ( format == RFC_1123 ) { strptime(input.data(), "%a, %d %b %Y %H:%M:%S GMT", &output); } else { // Try to extract the fractional second from the timestamp utility::string_t input; extract_fractional_second(dateString, input, ufrac_second); auto result = strptime(input.data(), "%Y-%m-%dT%H:%M:%SZ", &output); if ( result == nullptr ) { result = strptime(input.data(), "%Y%m%dT%H:%M:%SZ", &output); } if ( result == nullptr ) { // Fill the date portion with the epoch, // strptime will do the rest memset(&output, 0, sizeof(struct tm)); output.tm_year = 70; output.tm_mon = 1; output.tm_mday = 1; result = strptime(input.data(), "%H:%M:%SZ", &output); } if ( result == nullptr ) { result = strptime(input.data(), "%Y-%m-%d", &output); } if ( result == nullptr ) { result = strptime(input.data(), "%Y%m%d", &output); } if ( result == nullptr ) { return datetime(); } } time_t time = timegm(&output); struct timeval tv = timeval(); tv.tv_sec = time; tv.tv_usec = (unsigned int)ufrac_second; return timeval_to_datetime(tv); #endif }