diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 72890014c..9806a8362 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -3,10 +3,11 @@ # The list of modules is ordered so that each library occurs after any others # that it depends on set( LIBRARIES + "lib-string-utils" ) foreach( LIBRARY ${LIBRARIES} ) - add_subdirectory("${LIBRARY}") + add_subdirectory( "${LIBRARY}" ) endforeach() set( GRAPH_EDGES "${GRAPH_EDGES}" PARENT_SCOPE ) diff --git a/libraries/lib-string-utils/CMakeLists.txt b/libraries/lib-string-utils/CMakeLists.txt new file mode 100644 index 000000000..60408eccc --- /dev/null +++ b/libraries/lib-string-utils/CMakeLists.txt @@ -0,0 +1,27 @@ +set(TARGET lib-string-utils) +set(TARGET_ROOT ${CMAKE_CURRENT_SOURCE_DIR} ) + +def_vars() + +set(SOURCES + HexHelpers.h + + UrlEncode.h + UrlEncode.cpp + + UrlDecode.h + UrlDecode.cpp + + CodeConversions.h + CodeConversions.cpp + + DateTimeConversions.h + DateTimeConversions.cpp +) + +set( LIBRARIES + PRIVATE + wxwidgets::base +) + +audacity_library( ${TARGET} "${SOURCES}" "${LIBRARIES}" "" "" ) diff --git a/libraries/lib-string-utils/CodeConversions.cpp b/libraries/lib-string-utils/CodeConversions.cpp new file mode 100644 index 000000000..54fc4d748 --- /dev/null +++ b/libraries/lib-string-utils/CodeConversions.cpp @@ -0,0 +1,59 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file CodeConversions.cpp + @brief Define functions to preform UTF-8 to std::wstring conversions. + + Dmitry Vedenko + **********************************************************************/ + +#include "CodeConversions.h" + +#include +#include + +namespace audacity +{ + +std::string ToUTF8 (const std::wstring& wstr) +{ + return std::wstring_convert> ().to_bytes (wstr); +} + +std::string ToUTF8 (const wchar_t* wstr) +{ + return std::wstring_convert> ().to_bytes (wstr); +} + +std::string ToUTF8 (const wxString& wstr) +{ + return wstr.ToStdString (wxGet_wxConvUTF8 ()); +} + +std::wstring ToWString (const std::string& str) +{ + return std::wstring_convert> ().from_bytes (str); +} + +std::wstring ToWString (const char* str) +{ + return std::wstring_convert> ().from_bytes (str); +} + +std::wstring ToWString (const wxString& str) +{ + return str.ToStdWstring (); +} + +wxString ToWXString (const std::string& str) +{ + return wxString::FromUTF8 (str); +} + +wxString ToWXString (const std::wstring& str) +{ + return wxString (str); +} + +} diff --git a/libraries/lib-string-utils/CodeConversions.h b/libraries/lib-string-utils/CodeConversions.h new file mode 100644 index 000000000..96cfc7d0d --- /dev/null +++ b/libraries/lib-string-utils/CodeConversions.h @@ -0,0 +1,31 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file CodeConversions.h + @brief Declare functions to preform UTF-8 to std::wstring conversions. + + Dmitry Vedenko + **********************************************************************/ + +#pragma once + +#include +#include + +namespace audacity +{ + +STRING_UTILS_API std::string ToUTF8 (const std::wstring& wstr); +STRING_UTILS_API std::string ToUTF8 (const wchar_t* wstr); +STRING_UTILS_API std::string ToUTF8 (const wxString& wstr); + +// std::wstring is UTF16 on windows and UTF32 elsewhere. +STRING_UTILS_API std::wstring ToWString (const std::string& str); +STRING_UTILS_API std::wstring ToWString (const char* str); +STRING_UTILS_API std::wstring ToWString (const wxString& str); + +STRING_UTILS_API wxString ToWXString (const std::string& str); +STRING_UTILS_API wxString ToWXString (const std::wstring& str); + +} diff --git a/libraries/lib-string-utils/DateTimeConversions.cpp b/libraries/lib-string-utils/DateTimeConversions.cpp new file mode 100644 index 000000000..57ad65082 --- /dev/null +++ b/libraries/lib-string-utils/DateTimeConversions.cpp @@ -0,0 +1,44 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file DateTimeConversions.cpp + @brief Define functions to work with date and time string representations. + + Dmitry Vedenko + **********************************************************************/ + +#include "DateTimeConversions.h" + +#include + +#include "CodeConversions.h" + +namespace audacity +{ + +bool ParseRFC822Date (const std::string& dateString, SystemTime* time) +{ + wxDateTime dt; + wxString::const_iterator end; + + if (!dt.ParseRfc822Date (dateString, &end)) + return false; + + if (time != nullptr) + *time = std::chrono::system_clock::from_time_t (dt.GetTicks ()); + + return true; +} + +std::string SerializeRFC822Date (SystemTime timePoint) +{ + const wxDateTime dt ( + time_t (std::chrono::duration_cast ( + timePoint.time_since_epoch () + ).count ())); + + return ToUTF8 (dt.Format("%a, %d %b %Y %H:%M:%S %z")); +} + +} diff --git a/libraries/lib-string-utils/DateTimeConversions.h b/libraries/lib-string-utils/DateTimeConversions.h new file mode 100644 index 000000000..875bfe6de --- /dev/null +++ b/libraries/lib-string-utils/DateTimeConversions.h @@ -0,0 +1,24 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file DateTimeConversions.h + @brief Declare functions to work with date and time string representations. + + Dmitry Vedenko + **********************************************************************/ + +#pragma once + +#include +#include + +namespace audacity +{ + +using SystemTime = std::chrono::system_clock::time_point; + +STRING_UTILS_API bool ParseRFC822Date (const std::string& dateString, SystemTime* time); +STRING_UTILS_API std::string SerializeRFC822Date (SystemTime timePoint); + +} diff --git a/libraries/lib-string-utils/HexHelpers.h b/libraries/lib-string-utils/HexHelpers.h new file mode 100644 index 000000000..32c5a0407 --- /dev/null +++ b/libraries/lib-string-utils/HexHelpers.h @@ -0,0 +1,34 @@ +#pragma once + +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file HexHelpers.h + @brief Define helper functions for hex-to-num conversion. + + Dmitry Vedenko + **********************************************************************/ + +#include +#include +#include + +namespace audacity +{ + +inline uint8_t HexCharToNum (char c) noexcept +{ + assert (std::isxdigit (c) != 0); + + if ('0' <= c && c <= '9') + return c - '0'; + else if ('A' <= c && c <= 'F') + return c - 'A' + 10; + else if ('a' <= c && c <= 'f') + return c - 'a' + 10; + + return 0; +} + +} diff --git a/libraries/lib-string-utils/UrlDecode.cpp b/libraries/lib-string-utils/UrlDecode.cpp new file mode 100644 index 000000000..da44737c1 --- /dev/null +++ b/libraries/lib-string-utils/UrlDecode.cpp @@ -0,0 +1,51 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file UrlDecode.cpp + @brief Define a function to decode an URL encode string. + + Dmitry Vedenko + **********************************************************************/ + +#include "UrlDecode.h" + +#include "HexHelpers.h" + +namespace audacity +{ + +std::string UrlDecode (const std::string& url) +{ + std::string result; + + const size_t length = url.length (); + + for (auto it = url.begin (), end = url.end (); it != end; ++it) + { + const char c = *it; + + if (c != '%') + { + result.push_back (c); + } + else + { + if (++it == url.end ()) + break; // Malformed input string + + const char c1 = *it; + + if (++it == url.end ()) + break; // Malformed input string + + const char c2 = *it; + + result.push_back (HexCharToNum (c1) << 4 | HexCharToNum (c2)); + } + } + + return result; +} + +} diff --git a/libraries/lib-string-utils/UrlDecode.h b/libraries/lib-string-utils/UrlDecode.h new file mode 100644 index 000000000..b3860ef4d --- /dev/null +++ b/libraries/lib-string-utils/UrlDecode.h @@ -0,0 +1,20 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file UrlDecode.h + @brief Declare a function to decode an URL encode string. + + Dmitry Vedenko + **********************************************************************/ + +#pragma once + +#include + +namespace audacity +{ + +STRING_UTILS_API std::string UrlDecode (const std::string& url); + +} diff --git a/libraries/lib-string-utils/UrlEncode.cpp b/libraries/lib-string-utils/UrlEncode.cpp new file mode 100644 index 000000000..64916e25c --- /dev/null +++ b/libraries/lib-string-utils/UrlEncode.cpp @@ -0,0 +1,44 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file UrlEncode.cpp + @brief Define a function to perfom URL encoding of a string. + + Dmitry Vedenko + **********************************************************************/ + +#include "UrlEncode.h" + +namespace audacity +{ + +std::string UrlEncode (const std::string& url) +{ + std::string escaped; + + for (char c : url) + { + if (('0' <= c && c <= '9') || + ('A' <= c && c <= 'Z') || + ('a' <= c && c <= 'z') || + (c == '~' || c == '-' || c == '_' || c == '.') + ) + { + escaped.push_back (c); + } + else + { + static const char symbolLookup[] = "0123456789ABCDEF"; + + escaped.push_back ('%'); + + escaped.push_back (symbolLookup[(c & 0xF0) >> 4]); + escaped.push_back (symbolLookup[(c & 0x0F) >> 0]); + } + } + + return escaped; +} + +} diff --git a/libraries/lib-string-utils/UrlEncode.h b/libraries/lib-string-utils/UrlEncode.h new file mode 100644 index 000000000..a3c3cd02d --- /dev/null +++ b/libraries/lib-string-utils/UrlEncode.h @@ -0,0 +1,20 @@ +/*!******************************************************************** + + Audacity: A Digital Audio Editor + + @file UrlEncode.h + @brief Declare a function to perfom URL encoding of a string. + + Dmitry Vedenko + **********************************************************************/ + +#pragma once + +#include + +namespace audacity +{ + +STRING_UTILS_API std::string UrlEncode (const std::string& url); + +}