diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index 5341230c..80f6a50c 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -720,7 +720,7 @@ int CConfigParser::ReadInt(LPCTSTR section, LPCTSTR key, int defValue) return defValue; } -unsigned int CConfigParser::ReadUInt(LPCTSTR section, LPCTSTR key, unsigned int defValue) +uint32_t CConfigParser::ReadUInt(LPCTSTR section, LPCTSTR key, uint32_t defValue) { const std::wstring& result = ReadString(section, key, L""); @@ -733,7 +733,7 @@ unsigned int CConfigParser::ReadUInt(LPCTSTR section, LPCTSTR key, unsigned int const WCHAR* errMsg = MathParser::CheckedParse(string, &dblValue); if (!errMsg) { - return (unsigned int)dblValue; + return (uint32_t)dblValue; } LogWithArgs(LOG_ERROR, L"Formula: %s in key \"%s\" in [%s]", errMsg, key, section); @@ -741,7 +741,7 @@ unsigned int CConfigParser::ReadUInt(LPCTSTR section, LPCTSTR key, unsigned int else if (*string) { errno = 0; - unsigned int uintValue = wcstoul(string, NULL, 10); + uint32_t uintValue = wcstoul(string, NULL, 10); if (errno != ERANGE) { return uintValue; @@ -752,6 +752,38 @@ unsigned int CConfigParser::ReadUInt(LPCTSTR section, LPCTSTR key, unsigned int return defValue; } +uint64_t CConfigParser::ReadUInt64(LPCTSTR section, LPCTSTR key, uint64_t defValue) +{ + const std::wstring& result = ReadString(section, key, L""); + + if (!m_LastDefaultUsed) + { + const WCHAR* string = result.c_str(); + if (*string == L'(') + { + double dblValue; + const WCHAR* errMsg = MathParser::CheckedParse(string, &dblValue); + if (!errMsg) + { + return (uint64_t)dblValue; + } + + LogWithArgs(LOG_ERROR, L"Formula: %s in key \"%s\" in [%s]", errMsg, key, section); + } + else if (*string) + { + errno = 0; + uint64_t uint64Value = _wcstoui64(string, NULL, 10); + if (errno != ERANGE) + { + return uint64Value; + } + } + } + + return defValue; +} + double CConfigParser::ReadFloat(LPCTSTR section, LPCTSTR key, double defValue) { const std::wstring& result = ReadString(section, key, L""); @@ -958,7 +990,7 @@ int CConfigParser::ParseInt(LPCTSTR string, int defValue) ** If the given string is invalid format or causes overflow/underflow, returns given default value. ** */ -unsigned int CConfigParser::ParseUInt(LPCTSTR string, unsigned int defValue) +uint32_t CConfigParser::ParseUInt(LPCTSTR string, uint32_t defValue) { assert(string); @@ -968,7 +1000,7 @@ unsigned int CConfigParser::ParseUInt(LPCTSTR string, unsigned int defValue) const WCHAR* errMsg = MathParser::CheckedParse(string, &dblValue); if (!errMsg) { - return (unsigned int)dblValue; + return (uint32_t)dblValue; } LogWithArgs(LOG_ERROR, L"Formula: %s: %s", errMsg, string); @@ -976,7 +1008,7 @@ unsigned int CConfigParser::ParseUInt(LPCTSTR string, unsigned int defValue) else if (*string) { errno = 0; - unsigned int uintValue = wcstoul(string, NULL, 10); + uint32_t uintValue = wcstoul(string, NULL, 10); if (errno != ERANGE) { return uintValue; @@ -986,6 +1018,39 @@ unsigned int CConfigParser::ParseUInt(LPCTSTR string, unsigned int defValue) return defValue; } +/* +** Helper method that parses the 64bit unsigned integer value from the given string. +** If the given string is invalid format or causes overflow/underflow, returns given default value. +** +*/ +uint64_t CConfigParser::ParseUInt64(LPCTSTR string, uint64_t defValue) +{ + assert(string); + + if (*string == L'(') + { + double dblValue; + const WCHAR* errMsg = MathParser::CheckedParse(string, &dblValue); + if (!errMsg) + { + return (uint64_t)dblValue; + } + + LogWithArgs(LOG_ERROR, L"Formula: %s: %s", errMsg, string); + } + else if (*string) + { + errno = 0; + uint64_t uint64Value = _wcstoui64(string, NULL, 10); + if (errno != ERANGE) + { + return uint64Value; + } + } + + return defValue; +} + /* ** Helper template that parses four comma separated values from the given string. ** diff --git a/Library/ConfigParser.h b/Library/ConfigParser.h index 80472dbd..5fa5e352 100644 --- a/Library/ConfigParser.h +++ b/Library/ConfigParser.h @@ -27,6 +27,7 @@ #include #include #include +#include #include class CRainmeter; @@ -71,7 +72,8 @@ public: bool IsKeyDefined(LPCTSTR section, LPCTSTR key); bool IsValueDefined(LPCTSTR section, LPCTSTR key); int ReadInt(LPCTSTR section, LPCTSTR key, int defValue); - unsigned int ReadUInt(LPCTSTR section, LPCTSTR key, unsigned int defValue); + uint32_t ReadUInt(LPCTSTR section, LPCTSTR key, uint32_t defValue); + uint64_t ReadUInt64(LPCTSTR section, LPCTSTR key, uint64_t defValue); double ReadFloat(LPCTSTR section, LPCTSTR key, double defValue); Gdiplus::ARGB ReadColor(LPCTSTR section, LPCTSTR key, Gdiplus::ARGB defValue); Gdiplus::Rect ReadRect(LPCTSTR section, LPCTSTR key, const Gdiplus::Rect& defValue); @@ -90,7 +92,8 @@ public: static void Shrink(std::vector& vec); static double ParseDouble(LPCTSTR string, double defValue); static int ParseInt(LPCTSTR string, int defValue); - static unsigned int ParseUInt(LPCTSTR string, unsigned int defValue); + static uint32_t ParseUInt(LPCTSTR string, uint32_t defValue); + static uint64_t ParseUInt64(LPCTSTR string, uint64_t defValue); static Gdiplus::ARGB ParseColor(LPCTSTR string); static Gdiplus::Rect ParseRect(LPCTSTR string); static RECT ParseRECT(LPCTSTR string); diff --git a/Library/MeasureNet.cpp b/Library/MeasureNet.cpp index 7d19d608..a251c9d7 100644 --- a/Library/MeasureNet.cpp +++ b/Library/MeasureNet.cpp @@ -571,7 +571,7 @@ void CMeasureNet::ResetStats() */ void CMeasureNet::ReadStats(const WCHAR* iniFile, std::wstring& statsDate) { - WCHAR buffer[64]; + WCHAR buffer[48]; CConfigParser parser; parser.Initialize(iniFile, NULL, NULL, L"Statistics"); @@ -582,92 +582,89 @@ void CMeasureNet::ReadStats(const WCHAR* iniFile, std::wstring& statsDate) statsDate = date; } - int count = parser.ReadInt(L"Statistics", L"NetStatsCount", 0); + uint32_t count = parser.ReadUInt(L"Statistics", L"Count", 0); + if (parser.GetLastDefaultUsed()) + { + count = parser.ReadUInt(L"Statistics", L"NetStatsCount", 0); + } c_StatValues.clear(); c_StatValues.reserve(count * 2); - for (int i = 1; i <= count; ++i) + for (uint32_t i = 1; i <= count; ++i) { ULARGE_INTEGER value; - _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInHigh%i", i); - value.HighPart = parser.ReadUInt(L"Statistics", buffer, 0); - - _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInLow%i", i); - value.LowPart = parser.ReadUInt(L"Statistics", buffer, 0); + _snwprintf_s(buffer, _TRUNCATE, L"In%u", i); + value.QuadPart = parser.ReadUInt64(L"Statistics", buffer, 0); + if (parser.GetLastDefaultUsed()) + { + _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInHigh%u", i); + value.HighPart = parser.ReadUInt(L"Statistics", buffer, 0); + _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInLow%u", i); + value.LowPart = parser.ReadUInt(L"Statistics", buffer, 0); + } c_StatValues.push_back(value.QuadPart); - _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutHigh%i", i); - value.HighPart = parser.ReadUInt(L"Statistics", buffer, 0); - - _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutLow%i", i); - value.LowPart = parser.ReadUInt(L"Statistics", buffer, 0); + _snwprintf_s(buffer, _TRUNCATE, L"Out%u", i); + value.QuadPart = parser.ReadUInt64(L"Statistics", buffer, 0); + if (parser.GetLastDefaultUsed()) + { + _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutHigh%u", i); + value.HighPart = parser.ReadUInt(L"Statistics", buffer, 0); + _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutLow%u", i); + value.LowPart = parser.ReadUInt(L"Statistics", buffer, 0); + } c_StatValues.push_back(value.QuadPart); } } -/* -** Appends "key=value\0" to given string. -** -*/ -inline void AppendStatsValue(std::wstring& data, const WCHAR* key, size_t key_len, const WCHAR* value, size_t value_len) -{ - data.append(key, key_len); - data += L'='; - data.append(value, value_len); - data += L'\0'; -} - /* ** Writes statistics. ** */ void CMeasureNet::WriteStats(const WCHAR* iniFile, const std::wstring& statsDate) { - WCHAR buffer[64]; - WCHAR buffer2[32]; - size_t len, len2; + WCHAR buffer[48]; + int len; - size_t statsSize = c_StatValues.size() / 2; + uint32_t count = c_StatValues.size() / 2; // Reserve sufficient buffer for statistics std::wstring data; - data.reserve((64 * 2) + 128 * statsSize); + data.reserve(48 * (2 + count)); // Add date - AppendStatsValue(data, L"Since", 5, statsDate.c_str(), statsDate.size()); + data = L"Since="; + data += statsDate; + data += L'\0'; + + auto appendStatsValue = [&]() + { + data.append(buffer, len); + data += L'\0'; + }; // Add stats count - len = _snwprintf_s(buffer, _TRUNCATE, L"%i", (int)statsSize); - AppendStatsValue(data, L"NetStatsCount", 13, buffer, len); + len = _snwprintf_s(buffer, _TRUNCATE, L"Count=%u", count); + appendStatsValue(); // Add stats - for (size_t i = 0; i < statsSize; ++i) + for (uint32_t i = 0; i < count; ++i) { - ULARGE_INTEGER value; + if (c_StatValues[i * 2] > 0) + { + len = _snwprintf_s(buffer, _TRUNCATE, L"In%u=%llu", i + 1, c_StatValues[i * 2]); + appendStatsValue(); + } - value.QuadPart = c_StatValues[i * 2]; - - len = _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInHigh%i", (int)i + 1); - len2 = _snwprintf_s(buffer2, _TRUNCATE, L"%u", value.HighPart); - AppendStatsValue(data, buffer, len, buffer2, len2); - - len = _snwprintf_s(buffer, _TRUNCATE, L"NetStatsInLow%i", (int)i + 1); - len2 = _snwprintf_s(buffer2, _TRUNCATE, L"%u", value.LowPart); - AppendStatsValue(data, buffer, len, buffer2, len2); - - value.QuadPart = c_StatValues[i * 2 + 1]; - - len = _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutHigh%i", (int)i + 1); - len2 = _snwprintf_s(buffer2, _TRUNCATE, L"%u", value.HighPart); - AppendStatsValue(data, buffer, len, buffer2, len2); - - len = _snwprintf_s(buffer, _TRUNCATE, L"NetStatsOutLow%i", (int)i + 1); - len2 = _snwprintf_s(buffer2, _TRUNCATE, L"%u", value.LowPart); - AppendStatsValue(data, buffer, len, buffer2, len2); + if (c_StatValues[i * 2 + 1] > 0) + { + len = _snwprintf_s(buffer, _TRUNCATE, L"Out%u=%llu", i + 1, c_StatValues[i * 2 + 1]); + appendStatsValue(); + } } // Write statistics diff --git a/Library/StdAfx.h b/Library/StdAfx.h index 1988ad72..48485c5b 100644 --- a/Library/StdAfx.h +++ b/Library/StdAfx.h @@ -55,6 +55,7 @@ #include #include #include +#include // RUNTIME #include