mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Merge remote-tracking branch 'origin/release/v7.5.0' into feature/pdfForms
# Conflicts: # DesktopEditor/common/StringExt.h # DesktopEditor/graphics/pro/js/drawingfile.json
This commit is contained in:
210
DesktopEditor/common/ProcessEnv.cpp
Normal file
210
DesktopEditor/common/ProcessEnv.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include "./ProcessEnv.h"
|
||||
#include <map>
|
||||
#include "./StringBuilder.h"
|
||||
#include "./File.h"
|
||||
|
||||
namespace NSProcessEnv
|
||||
{
|
||||
class CProps
|
||||
{
|
||||
public:
|
||||
std::map<std::string, std::string> m_props;
|
||||
|
||||
public:
|
||||
CProps()
|
||||
{
|
||||
}
|
||||
|
||||
static CProps& getInstance()
|
||||
{
|
||||
static CProps props;
|
||||
return props;
|
||||
}
|
||||
|
||||
void Load(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
std::vector<XmlUtils::CXmlNode> childs;
|
||||
if (node.GetChilds(childs))
|
||||
{
|
||||
for (std::vector<XmlUtils::CXmlNode>::iterator iter = childs.begin(); iter != childs.end(); iter++)
|
||||
{
|
||||
m_props.insert(std::make_pair(iter->GetNameA(), iter->GetTextA()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Save()
|
||||
{
|
||||
if (0 == m_props.size())
|
||||
return "";
|
||||
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
oBuilder.WriteString(L"<options>");
|
||||
|
||||
for (std::map<std::string, std::string>::iterator iter = m_props.begin(); iter != m_props.end(); iter++)
|
||||
{
|
||||
std::wstring name = UTF8_TO_U(iter->first);
|
||||
oBuilder.AddCharSafe('<');
|
||||
oBuilder.WriteString(name);
|
||||
oBuilder.AddCharSafe('>');
|
||||
|
||||
const std::string& value = iter->second;
|
||||
oBuilder.WriteEncodeXmlString(UTF8_TO_U(value));
|
||||
|
||||
oBuilder.WriteString(L"</");
|
||||
oBuilder.WriteString(name);
|
||||
oBuilder.AddCharSafe('>');
|
||||
}
|
||||
|
||||
oBuilder.WriteString(L"</options>");
|
||||
|
||||
std::wstring sData = oBuilder.GetData();
|
||||
return U_TO_UTF8(sData);
|
||||
}
|
||||
|
||||
inline bool IsPresent(const char* key)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator iter = m_props.find(std::string(key));
|
||||
return (iter == m_props.end()) ? false : true;
|
||||
}
|
||||
|
||||
inline bool GetBoolValue(const char* key)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator iter = m_props.find(std::string(key));
|
||||
if (iter == m_props.end())
|
||||
return false;
|
||||
|
||||
if ("1" == iter->second || "true" == iter->second)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
inline int GetIntValue(const char* key)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator iter = m_props.find(std::string(key));
|
||||
if (iter == m_props.end())
|
||||
return 0;
|
||||
|
||||
return std::stoi(iter->second);
|
||||
}
|
||||
inline std::string GetStringValueA(const char* key)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator iter = m_props.find(std::string(key));
|
||||
if (iter == m_props.end())
|
||||
return "";
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
inline std::wstring GetStringValue(const char* key)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator iter = m_props.find(std::string(key));
|
||||
if (iter == m_props.end())
|
||||
return L"";
|
||||
|
||||
return UTF8_TO_U(iter->second);
|
||||
}
|
||||
};
|
||||
|
||||
void Load(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
CProps::getInstance().Load(node);
|
||||
}
|
||||
void Load(const std::string& strUtf8)
|
||||
{
|
||||
XmlUtils::CXmlNode node;
|
||||
if (node.FromXmlStringA(strUtf8))
|
||||
Load(node);
|
||||
}
|
||||
void Load(const std::wstring& str)
|
||||
{
|
||||
XmlUtils::CXmlNode node;
|
||||
if (node.FromXmlString(str))
|
||||
Load(node);
|
||||
}
|
||||
|
||||
std::string Save()
|
||||
{
|
||||
return CProps::getInstance().Save();
|
||||
}
|
||||
|
||||
// GET
|
||||
bool IsPresent(const char* key)
|
||||
{
|
||||
return CProps::getInstance().IsPresent(key);
|
||||
}
|
||||
|
||||
bool GetBoolValue(const char* key)
|
||||
{
|
||||
return CProps::getInstance().GetBoolValue(key);
|
||||
}
|
||||
int GetIntValue(const char* key)
|
||||
{
|
||||
return CProps::getInstance().GetIntValue(key);
|
||||
}
|
||||
std::string GetStringValueA(const char* key)
|
||||
{
|
||||
return CProps::getInstance().GetStringValueA(key);
|
||||
}
|
||||
std::wstring GetStringValue(const char* key)
|
||||
{
|
||||
return CProps::getInstance().GetStringValue(key);
|
||||
}
|
||||
|
||||
// SET
|
||||
bool SetBoolValue(const char* key, const bool& value)
|
||||
{
|
||||
bool res = IsPresent(key);
|
||||
CProps::getInstance().m_props.insert(std::make_pair<std::string, std::string>(key, value ? "1" : "0"));
|
||||
return res;
|
||||
}
|
||||
bool SetIntValue(const char* key, const int& value)
|
||||
{
|
||||
bool res = IsPresent(key);
|
||||
CProps::getInstance().m_props.insert(std::make_pair<std::string, std::string>(key, std::to_string(value)));
|
||||
return res;
|
||||
}
|
||||
bool SetStringValueA(const char* key, const char* value)
|
||||
{
|
||||
bool res = IsPresent(key);
|
||||
CProps::getInstance().m_props.insert(std::make_pair<std::string, std::string>(key, value));
|
||||
return res;
|
||||
}
|
||||
bool SetStringValue(const char* key, const wchar_t* value)
|
||||
{
|
||||
bool res = IsPresent(key);
|
||||
std::wstring tmp(value);
|
||||
CProps::getInstance().m_props.insert(std::make_pair<std::string, std::string>(key, U_TO_UTF8(tmp)));
|
||||
return res;
|
||||
}
|
||||
} // namespace NSProcessEnv
|
||||
72
DesktopEditor/common/ProcessEnv.h
Normal file
72
DesktopEditor/common/ProcessEnv.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#ifndef _PROCESS_ENV_H
|
||||
#define _PROCESS_ENV_H
|
||||
|
||||
#include "../../Common/kernel_config.h"
|
||||
#include "../xml/include/xmlutils.h"
|
||||
#include <string>
|
||||
|
||||
namespace NSProcessEnv
|
||||
{
|
||||
namespace Converter
|
||||
{
|
||||
static const char* gc_allowLocalRequest = "allowNetworkRequest";
|
||||
static const char* gc_allowNetworkRequest = "allowNetworkRequest";
|
||||
static const char* gc_allowPrivateIP = "allowPrivateIP";
|
||||
static const char* gc_proxy = "proxy";
|
||||
static const char* gc_proxyUser = "proxyUser";
|
||||
static const char* gc_proxyHeader = "proxyHeader";
|
||||
}
|
||||
|
||||
// serialize
|
||||
KERNEL_DECL void Load(XmlUtils::CXmlNode& node);
|
||||
KERNEL_DECL void Load(const std::string& strUtf8);
|
||||
KERNEL_DECL void Load(const std::wstring& str);
|
||||
KERNEL_DECL std::string Save();
|
||||
|
||||
// props
|
||||
KERNEL_DECL bool IsPresent(const char* key);
|
||||
|
||||
KERNEL_DECL bool GetBoolValue(const char* key);
|
||||
KERNEL_DECL int GetIntValue(const char* key);
|
||||
KERNEL_DECL std::string GetStringValueA(const char* key);
|
||||
KERNEL_DECL std::wstring GetStringValue(const char* key);
|
||||
|
||||
// return is override
|
||||
KERNEL_DECL bool SetBoolValue(const char* key, const bool& value);
|
||||
KERNEL_DECL bool SetIntValue(const char* key, const int& value);
|
||||
KERNEL_DECL bool SetStringValueA(const char* key, const char* value);
|
||||
KERNEL_DECL bool SetStringValue(const char* key, const wchar_t* value);
|
||||
}
|
||||
|
||||
#endif // _PROCESS_ENV_H
|
||||
@ -78,9 +78,9 @@ namespace NSStringUtils
|
||||
{
|
||||
while ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
if (m_lSize > 10485760/*10 * 1024 * 1024*/)
|
||||
if (m_lSize > 10485760/*10 * 1024 * 1024*/)
|
||||
{
|
||||
m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/);
|
||||
m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -218,9 +218,9 @@ namespace NSStringUtils
|
||||
{
|
||||
while ((m_lSizeCur + nSize) > m_lSize)
|
||||
{
|
||||
if (m_lSize > 10485760/*10 * 1024 * 1024*/)
|
||||
if (m_lSize > 10485760/*10 * 1024 * 1024*/)
|
||||
{
|
||||
m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/);
|
||||
m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,17 +252,17 @@ namespace NSStringUtils
|
||||
ClearNoAttack();
|
||||
WriteString(bsText);
|
||||
|
||||
for (size_t i = 0; i < m_lSizeCur; ++i)
|
||||
for (size_t i = 0; i < m_lSizeCur; ++i)
|
||||
{
|
||||
if (WCHAR(8233) == m_pData[i])
|
||||
m_pData[i] = WCHAR(' ');
|
||||
}
|
||||
}
|
||||
|
||||
void CStringBuilder::operator+=(const std::wstring& oTemp)
|
||||
{
|
||||
WriteString(oTemp.c_str(), oTemp.length());
|
||||
}
|
||||
void CStringBuilder::operator+=(const std::wstring& oTemp)
|
||||
{
|
||||
WriteString(oTemp.c_str(), oTemp.length());
|
||||
}
|
||||
|
||||
void CStringBuilder::WriteStringNoSafe(const wchar_t* pString, size_t nLen)
|
||||
{
|
||||
@ -604,17 +604,17 @@ namespace NSStringUtils
|
||||
std::wstring str(m_pData, (int)m_lSizeCur);
|
||||
return str;
|
||||
}
|
||||
std::wstring CStringBuilder::GetSubData(const size_t& start, const size_t& count)
|
||||
{
|
||||
if (start >= m_lSizeCur)
|
||||
return L"";
|
||||
std::wstring CStringBuilder::GetSubData(const size_t& start, const size_t& count)
|
||||
{
|
||||
if (start >= m_lSizeCur)
|
||||
return L"";
|
||||
|
||||
size_t nCountMax = m_lSizeCur - start;
|
||||
if (count != std::wstring::npos && count <= nCountMax)
|
||||
nCountMax = count;
|
||||
size_t nCountMax = m_lSizeCur - start;
|
||||
if (count != std::wstring::npos && count <= nCountMax)
|
||||
nCountMax = count;
|
||||
|
||||
return std::wstring(m_pData + start, nCountMax);
|
||||
}
|
||||
return std::wstring(m_pData + start, nCountMax);
|
||||
}
|
||||
|
||||
wchar_t* CStringBuilder::GetBuffer()
|
||||
{
|
||||
@ -676,14 +676,14 @@ namespace NSStringUtils
|
||||
{
|
||||
if (0 == val)
|
||||
{
|
||||
*m_pDataCur++ = (wchar_t)'0';
|
||||
*m_pDataCur++ = (wchar_t)'0';
|
||||
++m_lSizeCur;
|
||||
return;
|
||||
}
|
||||
if (val < 0)
|
||||
{
|
||||
val = -val;
|
||||
*m_pDataCur++ = (wchar_t)'-';
|
||||
*m_pDataCur++ = (wchar_t)'-';
|
||||
++m_lSizeCur;
|
||||
}
|
||||
|
||||
@ -698,7 +698,7 @@ namespace NSStringUtils
|
||||
oval = 1;
|
||||
while (val > 0)
|
||||
{
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10));
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10));
|
||||
++oval;
|
||||
val /= 10;
|
||||
}
|
||||
@ -711,14 +711,14 @@ namespace NSStringUtils
|
||||
{
|
||||
if (0 == val)
|
||||
{
|
||||
*m_pDataCur++ = (wchar_t)'0';
|
||||
*m_pDataCur++ = (wchar_t)'0';
|
||||
++m_lSizeCur;
|
||||
return;
|
||||
}
|
||||
if (val < 0)
|
||||
{
|
||||
val = -val;
|
||||
*m_pDataCur++ = (wchar_t)'-';
|
||||
*m_pDataCur++ = (wchar_t)'-';
|
||||
++m_lSizeCur;
|
||||
}
|
||||
|
||||
@ -735,9 +735,9 @@ namespace NSStringUtils
|
||||
if (0 != nLastS)
|
||||
{
|
||||
++len;
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + nLastS);
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + nLastS);
|
||||
++oval;
|
||||
m_pDataCur[len - oval] = (wchar_t)('.');
|
||||
m_pDataCur[len - oval] = (wchar_t)('.');
|
||||
++oval;
|
||||
val /= 10;
|
||||
}
|
||||
@ -749,7 +749,7 @@ namespace NSStringUtils
|
||||
|
||||
while (val > 0)
|
||||
{
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10));
|
||||
m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10));
|
||||
++oval;
|
||||
val /= 10;
|
||||
}
|
||||
@ -852,14 +852,14 @@ namespace NSStringUtils
|
||||
WriteHexByteNoSafe((value >> 8) & 0xFF);
|
||||
WriteHexByteNoSafe(value & 0xFF);
|
||||
}
|
||||
void CStringBuilder::WriteHexInt4(const unsigned int& value)
|
||||
{
|
||||
AddSize(8);
|
||||
WriteHexByteNoSafe((value >> 24) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 16) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 8) & 0xFF);
|
||||
WriteHexByteNoSafe(value & 0xFF);
|
||||
}
|
||||
void CStringBuilder::WriteHexInt4(const unsigned int& value)
|
||||
{
|
||||
AddSize(8);
|
||||
WriteHexByteNoSafe((value >> 24) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 16) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 8) & 0xFF);
|
||||
WriteHexByteNoSafe(value & 0xFF);
|
||||
}
|
||||
void CStringBuilder::WriteHexColor3(const unsigned char& r, const unsigned char& g, const unsigned char& b)
|
||||
{
|
||||
AddSize(7);
|
||||
@ -874,16 +874,16 @@ namespace NSStringUtils
|
||||
AddSize(7);
|
||||
*m_pDataCur++ = (wchar_t)'#';
|
||||
++m_lSizeCur;
|
||||
WriteHexByteNoSafe(value & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 8) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 16) & 0xFF);
|
||||
WriteHexByteNoSafe(value & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 8) & 0xFF);
|
||||
WriteHexByteNoSafe((value >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
void CStringBuilder::Skip(int nSkip)
|
||||
{
|
||||
m_pDataCur += nSkip;
|
||||
m_lSizeCur += nSkip;
|
||||
}
|
||||
void CStringBuilder::Skip(int nSkip)
|
||||
{
|
||||
m_pDataCur += nSkip;
|
||||
m_lSizeCur += nSkip;
|
||||
}
|
||||
void CStringBuilder::StartNode(const std::wstring& name)
|
||||
{
|
||||
WriteString(g_bstr_nodeopen);
|
||||
@ -1121,22 +1121,22 @@ namespace NSStringUtils
|
||||
return 0;
|
||||
}
|
||||
|
||||
void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo)
|
||||
{
|
||||
size_t posn = 0;
|
||||
while (std::wstring::npos != (posn = text.find(replaceFrom, posn)))
|
||||
{
|
||||
text.replace(posn, replaceFrom.length(), replaceTo);
|
||||
posn += replaceTo.length();
|
||||
}
|
||||
}
|
||||
void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo)
|
||||
{
|
||||
size_t posn = 0;
|
||||
while (std::string::npos != (posn = text.find(replaceFrom, posn)))
|
||||
{
|
||||
text.replace(posn, replaceFrom.length(), replaceTo);
|
||||
posn += replaceTo.length();
|
||||
}
|
||||
}
|
||||
void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo)
|
||||
{
|
||||
size_t posn = 0;
|
||||
while (std::wstring::npos != (posn = text.find(replaceFrom, posn)))
|
||||
{
|
||||
text.replace(posn, replaceFrom.length(), replaceTo);
|
||||
posn += replaceTo.length();
|
||||
}
|
||||
}
|
||||
void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo)
|
||||
{
|
||||
size_t posn = 0;
|
||||
while (std::string::npos != (posn = text.find(replaceFrom, posn)))
|
||||
{
|
||||
text.replace(posn, replaceFrom.length(), replaceTo);
|
||||
posn += replaceTo.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,12 +32,12 @@
|
||||
#ifndef _BUILD_STRING_CROSSPLATFORM_H_
|
||||
#define _BUILD_STRING_CROSSPLATFORM_H_
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../../Common/kernel_config.h"
|
||||
|
||||
@ -45,330 +45,356 @@
|
||||
#include <stdarg.h>
|
||||
namespace NSStrings
|
||||
{
|
||||
static std::string format(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::vector<char> v(1024);
|
||||
while (true)
|
||||
{
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
int res = vsnprintf(v.data(), v.size(), fmt, args2);
|
||||
if ((res >= 0) && (res < static_cast<int>(v.size())))
|
||||
{
|
||||
va_end(args);
|
||||
va_end(args2);
|
||||
return std::string(v.data());
|
||||
}
|
||||
size_t size;
|
||||
if (res < 0)
|
||||
size = v.size() * 2;
|
||||
else
|
||||
size = static_cast<size_t>(res) + 1;
|
||||
v.clear();
|
||||
v.resize(size);
|
||||
va_end(args2);
|
||||
}
|
||||
}
|
||||
|
||||
static std::wstring format(const wchar_t *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::vector<wchar_t> v(1024);
|
||||
while (true)
|
||||
{
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
int res = vswprintf(v.data(), v.size(), fmt, args2);
|
||||
if ((res >= 0) && (res < static_cast<int>(v.size())))
|
||||
{
|
||||
va_end(args);
|
||||
va_end(args2);
|
||||
return std::wstring(v.data());
|
||||
}
|
||||
size_t size;
|
||||
if (res < 0)
|
||||
size = v.size() * 2;
|
||||
else
|
||||
size = static_cast<size_t>(res) + 1;
|
||||
v.clear();
|
||||
v.resize(size);
|
||||
va_end(args2);
|
||||
}
|
||||
}
|
||||
static std::string format(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::vector<char> v(1024);
|
||||
while (true)
|
||||
{
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
int res = vsnprintf(v.data(), v.size(), fmt, args2);
|
||||
if ((res >= 0) && (res < static_cast<int>(v.size())))
|
||||
{
|
||||
va_end(args);
|
||||
va_end(args2);
|
||||
return std::string(v.data());
|
||||
}
|
||||
size_t size;
|
||||
if (res < 0)
|
||||
size = v.size() * 2;
|
||||
else
|
||||
size = static_cast<size_t>(res) + 1;
|
||||
v.clear();
|
||||
v.resize(size);
|
||||
va_end(args2);
|
||||
}
|
||||
}
|
||||
|
||||
static std::wstring format(const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::vector<wchar_t> v(1024);
|
||||
while (true)
|
||||
{
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
int res = vswprintf(v.data(), v.size(), fmt, args2);
|
||||
if ((res >= 0) && (res < static_cast<int>(v.size())))
|
||||
{
|
||||
va_end(args);
|
||||
va_end(args2);
|
||||
return std::wstring(v.data());
|
||||
}
|
||||
size_t size;
|
||||
if (res < 0)
|
||||
size = v.size() * 2;
|
||||
else
|
||||
size = static_cast<size_t>(res) + 1;
|
||||
v.clear();
|
||||
v.resize(size);
|
||||
va_end(args2);
|
||||
}
|
||||
}
|
||||
} // namespace NSStrings
|
||||
#endif
|
||||
|
||||
namespace NSStringExt
|
||||
{
|
||||
class KERNEL_DECL CConverter
|
||||
class KERNEL_DECL CConverter
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
SINGLE_BYTE_ENCODING_DEFAULT = 0x01, // DEFAULT_CHARSET 1 (x01)
|
||||
SINGLE_BYTE_ENCODING_SYMBOL = 0x02, // SYMBOL_CHARSET 2 (x02)
|
||||
SINGLE_BYTE_ENCODING_CP1252 = 0x00, // ANSI_CHARSET 0 (x00)
|
||||
SINGLE_BYTE_ENCODING_CP1251 = 0xCC, // RUSSIAN_CHARSET 204 (xCC)
|
||||
SINGLE_BYTE_ENCODING_CP1250 = 0xEE, // EASTEUROPE_CHARSET 238 (xEE)
|
||||
SINGLE_BYTE_ENCODING_CP1253 = 0xA1, // GREEK_CHARSET 161 (xA1)
|
||||
SINGLE_BYTE_ENCODING_CP1254 = 0xA2, // TURKISH_CHARSET 162 (xA2)
|
||||
SINGLE_BYTE_ENCODING_CP1257 = 0xBA, // BALTIC_CHARSET 186 (xBA)
|
||||
SINGLE_BYTE_ENCODING_CP1255 = 0xB1, // HEBREW_CHARSET 177 (xB1)
|
||||
SINGLE_BYTE_ENCODING_CP1256 = 0xB2, // ARABIC _CHARSET 178 (xB2)
|
||||
SINGLE_BYTE_ENCODING_CP932 = 0x80, // SHIFTJIS_CHARSET 128 (x80)
|
||||
SINGLE_BYTE_ENCODING_CP949 = 0x81, // HANGEUL_CHARSET 129 (x81)
|
||||
SINGLE_BYTE_ENCODING_CP936 = 0x86, // GB2313_CHARSET 134 (x86)
|
||||
SINGLE_BYTE_ENCODING_CP950 = 0x88, // CHINESEBIG5_CHARSET 136 (x88)
|
||||
SINGLE_BYTE_ENCODING_CP874 = 0xDE, // THAI_CHARSET 222 (xDE)
|
||||
SINGLE_BYTE_ENCODING_CP1361 = 0x82, // JOHAB_CHARSET 130 (x82)
|
||||
SINGLE_BYTE_ENCODING_CP1258 = 0xA3, // VIETNAMESE_CHARSET 163 (xA3)
|
||||
SINGLE_BYTE_ENCODING_CP866 = 0xFF // OEM_CHARSET 255 (xFF) // Проверить, что OEM соответствует CP866
|
||||
} ESingleByteEncoding;
|
||||
SINGLE_BYTE_ENCODING_DEFAULT = 0x01, // DEFAULT_CHARSET 1 (x01)
|
||||
SINGLE_BYTE_ENCODING_SYMBOL = 0x02, // SYMBOL_CHARSET 2 (x02)
|
||||
SINGLE_BYTE_ENCODING_CP1252 = 0x00, // ANSI_CHARSET 0 (x00)
|
||||
SINGLE_BYTE_ENCODING_CP1251 = 0xCC, // RUSSIAN_CHARSET 204 (xCC)
|
||||
SINGLE_BYTE_ENCODING_CP1250 = 0xEE, // EASTEUROPE_CHARSET 238 (xEE)
|
||||
SINGLE_BYTE_ENCODING_CP1253 = 0xA1, // GREEK_CHARSET 161 (xA1)
|
||||
SINGLE_BYTE_ENCODING_CP1254 = 0xA2, // TURKISH_CHARSET 162 (xA2)
|
||||
SINGLE_BYTE_ENCODING_CP1257 = 0xBA, // BALTIC_CHARSET 186 (xBA)
|
||||
SINGLE_BYTE_ENCODING_CP1255 = 0xB1, // HEBREW_CHARSET 177 (xB1)
|
||||
SINGLE_BYTE_ENCODING_CP1256 = 0xB2, // ARABIC _CHARSET 178 (xB2)
|
||||
SINGLE_BYTE_ENCODING_CP932 = 0x80, // SHIFTJIS_CHARSET 128 (x80)
|
||||
SINGLE_BYTE_ENCODING_CP949 = 0x81, // HANGEUL_CHARSET 129 (x81)
|
||||
SINGLE_BYTE_ENCODING_CP936 = 0x86, // GB2313_CHARSET 134 (x86)
|
||||
SINGLE_BYTE_ENCODING_CP950 = 0x88, // CHINESEBIG5_CHARSET 136 (x88)
|
||||
SINGLE_BYTE_ENCODING_CP874 = 0xDE, // THAI_CHARSET 222 (xDE)
|
||||
SINGLE_BYTE_ENCODING_CP1361 = 0x82, // JOHAB_CHARSET 130 (x82)
|
||||
SINGLE_BYTE_ENCODING_CP1258 = 0xA3, // VIETNAMESE_CHARSET 163 (xA3)
|
||||
SINGLE_BYTE_ENCODING_CP866 = 0xFF // OEM_CHARSET 255 (xFF) // Проверить, что OEM соответствует CP866
|
||||
} ESingleByteEncoding;
|
||||
|
||||
static std::wstring GetUnicodeFromSingleByteString(const unsigned char* pData, long lCount, ESingleByteEncoding eType = SINGLE_BYTE_ENCODING_DEFAULT);
|
||||
static std::wstring GetUnicodeFromUTF16(const unsigned short* pData, long lCount);
|
||||
static std::wstring GetUnicodeFromUTF32(const unsigned int* pData, long lCount);
|
||||
static void GetUtf8FromUTF32(const unsigned int* pData, long lCount, unsigned char*& pOutputData, long& lOutputCount);
|
||||
static std::string GetUtf8FromUTF32(const unsigned int* pData, long lCount);
|
||||
static unsigned int* GetUtf32FromUnicode(const std::wstring& wsUnicodeText, unsigned int& unLen);
|
||||
static unsigned short* GetUtf16FromUnicode(const std::wstring& wsUnicodeText, unsigned int& unLen, const bool& isLE = true);
|
||||
};
|
||||
static std::wstring GetUnicodeFromSingleByteString(const unsigned char* pData, long lCount, ESingleByteEncoding eType = SINGLE_BYTE_ENCODING_DEFAULT);
|
||||
static std::wstring GetUnicodeFromUTF16(const unsigned short* pData, long lCount);
|
||||
static std::wstring GetUnicodeFromUTF32(const unsigned int* pData, long lCount);
|
||||
static void GetUtf8FromUTF32(const unsigned int* pData, long lCount, unsigned char*& pOutputData, long& lOutputCount);
|
||||
static std::string GetUtf8FromUTF32(const unsigned int* pData, long lCount);
|
||||
static unsigned int* GetUtf32FromUnicode(const std::wstring& wsUnicodeText, unsigned int& unLen);
|
||||
static unsigned short* GetUtf16FromUnicode(const std::wstring& wsUnicodeText, unsigned int& unLen, const bool& isLE = true);
|
||||
};
|
||||
|
||||
class CStringUnicodeIterator_private;
|
||||
class KERNEL_DECL CStringUnicodeIterator
|
||||
{
|
||||
private:
|
||||
CStringUnicodeIterator_private* m_internal;
|
||||
class CStringUnicodeIterator_private;
|
||||
class KERNEL_DECL CStringUnicodeIterator
|
||||
{
|
||||
private:
|
||||
CStringUnicodeIterator_private* m_internal;
|
||||
|
||||
public:
|
||||
CStringUnicodeIterator(const std::wstring& string);
|
||||
~CStringUnicodeIterator();
|
||||
bool Check();
|
||||
void Next();
|
||||
unsigned int Value();
|
||||
};
|
||||
}
|
||||
public:
|
||||
CStringUnicodeIterator(const std::wstring& string);
|
||||
~CStringUnicodeIterator();
|
||||
bool Check();
|
||||
void Next();
|
||||
unsigned int Value();
|
||||
};
|
||||
} // namespace NSStringExt
|
||||
|
||||
namespace NSStringExt
|
||||
{
|
||||
static std::vector<std::wstring>& Split(const std::wstring& wsString, wchar_t nDelim, std::vector<std::wstring> &arrElements)
|
||||
static std::vector<std::wstring>& Split(const std::wstring& wsString, wchar_t nDelim, std::vector<std::wstring>& arrElements)
|
||||
{
|
||||
std::wstringstream wStringStream(wsString);
|
||||
std::wstring wsItem;
|
||||
while (std::getline(wStringStream, wsItem, nDelim))
|
||||
{
|
||||
std::wstringstream wStringStream(wsString);
|
||||
std::wstring wsItem;
|
||||
while (std::getline(wStringStream, wsItem, nDelim))
|
||||
{
|
||||
arrElements.push_back(wsItem);
|
||||
}
|
||||
return arrElements;
|
||||
arrElements.push_back(wsItem);
|
||||
}
|
||||
static std::vector<std::wstring> Split(const std::wstring& wsString, wchar_t nDelim)
|
||||
{
|
||||
std::vector<std::wstring> wsElements;
|
||||
Split(wsString, nDelim, wsElements);
|
||||
return wsElements;
|
||||
}
|
||||
static std::vector<std::wstring>& Split(const std::wstring& wsString, const std::wstring wsDelim, std::vector<std::wstring> &arrElements)
|
||||
{
|
||||
size_t nDelimLen = wsDelim.length();
|
||||
size_t nPrevPos = 0;
|
||||
return arrElements;
|
||||
}
|
||||
static std::vector<std::wstring> Split(const std::wstring& wsString, wchar_t nDelim)
|
||||
{
|
||||
std::vector<std::wstring> wsElements;
|
||||
Split(wsString, nDelim, wsElements);
|
||||
return wsElements;
|
||||
}
|
||||
static std::vector<std::wstring>& Split(const std::wstring& wsString, const std::wstring wsDelim, std::vector<std::wstring>& arrElements)
|
||||
{
|
||||
size_t nDelimLen = wsDelim.length();
|
||||
size_t nPrevPos = 0;
|
||||
|
||||
if (nDelimLen > 0)
|
||||
if (nDelimLen > 0)
|
||||
{
|
||||
size_t nPos = wsString.find(wsDelim);
|
||||
while (std::wstring::npos != nPos)
|
||||
{
|
||||
size_t nPos = wsString.find(wsDelim);
|
||||
while (std::wstring::npos != nPos)
|
||||
{
|
||||
if (nPrevPos != nPos)
|
||||
arrElements.push_back(wsString.substr(nPrevPos, nPos - nPrevPos));
|
||||
if (nPrevPos != nPos)
|
||||
arrElements.push_back(wsString.substr(nPrevPos, nPos - nPrevPos));
|
||||
|
||||
nPrevPos = nPos + nDelimLen;
|
||||
nPos = wsString.find(wsDelim, nPrevPos);
|
||||
}
|
||||
nPrevPos = nPos + nDelimLen;
|
||||
nPos = wsString.find(wsDelim, nPrevPos);
|
||||
}
|
||||
|
||||
if (nPrevPos < wsString.length())
|
||||
arrElements.push_back(wsString.substr(nPrevPos));
|
||||
|
||||
return arrElements;
|
||||
}
|
||||
static std::vector<std::wstring> Split(const std::wstring& wsString, const std::wstring& wsDelim, bool bWholeString = true)
|
||||
{
|
||||
std::vector<std::wstring> arrElements;
|
||||
|
||||
if (bWholeString)
|
||||
{
|
||||
int nDelimLen = (int)wsDelim.length();
|
||||
if (0 == nDelimLen)
|
||||
arrElements.push_back(wsString);
|
||||
else if (1 == nDelimLen)
|
||||
Split(wsString, wchar_t(wsDelim[0]), arrElements);
|
||||
else
|
||||
Split(wsString, wsDelim, arrElements);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::wstring> arrCurrent;
|
||||
arrCurrent.push_back(wsString);
|
||||
if (nPrevPos < wsString.length())
|
||||
arrElements.push_back(wsString.substr(nPrevPos));
|
||||
|
||||
return arrElements;
|
||||
}
|
||||
static std::vector<std::wstring> Split(const std::wstring& wsString, const std::wstring& wsDelim, bool bWholeString = true)
|
||||
{
|
||||
std::vector<std::wstring> arrElements;
|
||||
|
||||
if (bWholeString)
|
||||
{
|
||||
int nDelimLen = (int)wsDelim.length();
|
||||
if (0 == nDelimLen)
|
||||
arrElements.push_back(wsString);
|
||||
int nPos = 0;
|
||||
int nLen = (int)wsDelim.length();
|
||||
while (nPos < nLen)
|
||||
else if (1 == nDelimLen)
|
||||
Split(wsString, wchar_t(wsDelim[0]), arrElements);
|
||||
else
|
||||
Split(wsString, wsDelim, arrElements);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::wstring> arrCurrent;
|
||||
arrCurrent.push_back(wsString);
|
||||
arrElements.push_back(wsString);
|
||||
int nPos = 0;
|
||||
int nLen = (int)wsDelim.length();
|
||||
while (nPos < nLen)
|
||||
{
|
||||
wchar_t wChar = wsDelim.at(nPos++);
|
||||
arrElements.clear();
|
||||
for (size_t nIndex = 0, nCount = arrCurrent.size(); nIndex < nCount; nIndex++)
|
||||
{
|
||||
wchar_t wChar = wsDelim.at(nPos++);
|
||||
arrElements.clear();
|
||||
for (size_t nIndex = 0, nCount = arrCurrent.size(); nIndex < nCount; nIndex++)
|
||||
{
|
||||
std::vector<std::wstring> arrTemp = Split(arrCurrent.at(nIndex), wChar);
|
||||
arrElements.insert(arrElements.end(), arrTemp.begin(), arrTemp.end());
|
||||
}
|
||||
arrCurrent = arrElements;
|
||||
std::vector<std::wstring> arrTemp = Split(arrCurrent.at(nIndex), wChar);
|
||||
arrElements.insert(arrElements.end(), arrTemp.begin(), arrTemp.end());
|
||||
}
|
||||
}
|
||||
|
||||
return arrElements;
|
||||
}
|
||||
static inline void ToLower(std::string& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::tolower);
|
||||
}
|
||||
static inline void ToUpper(std::string& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::toupper);
|
||||
}
|
||||
static inline void ToLower(std::wstring& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::towlower);
|
||||
}
|
||||
static inline void ToUpper(std::wstring& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::towupper);
|
||||
}
|
||||
static inline void Replace(std::wstring& wsString, const std::wstring& wsFrom, const std::wstring& wsTo)
|
||||
{
|
||||
int nFromLen = (int)wsFrom.length();
|
||||
int nToLen = (int)wsTo.length();
|
||||
size_t nPos = -nToLen;
|
||||
|
||||
while (std::wstring::npos != (nPos = wsString.find(wsFrom, nPos + nToLen)))
|
||||
{
|
||||
wsString.replace(nPos, nFromLen, wsTo);
|
||||
arrCurrent = arrElements;
|
||||
}
|
||||
}
|
||||
static inline void LTrim(std::wstring &str, const wchar_t* chars)
|
||||
|
||||
return arrElements;
|
||||
}
|
||||
static inline void ToLower(std::string& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::tolower);
|
||||
}
|
||||
static inline void ToUpper(std::string& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::toupper);
|
||||
}
|
||||
static inline void ToLower(std::wstring& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::towlower);
|
||||
}
|
||||
static inline void ToUpper(std::wstring& wsString)
|
||||
{
|
||||
std::transform(wsString.begin(), wsString.end(), wsString.begin(), ::towupper);
|
||||
}
|
||||
static inline void Replace(std::wstring& wsString, const std::wstring& wsFrom, const std::wstring& wsTo)
|
||||
{
|
||||
int nFromLen = (int)wsFrom.length();
|
||||
int nToLen = (int)wsTo.length();
|
||||
size_t nPos = -nToLen;
|
||||
|
||||
while (std::wstring::npos != (nPos = wsString.find(wsFrom, nPos + nToLen)))
|
||||
{
|
||||
str.erase(0, str.find_first_not_of(chars));
|
||||
}
|
||||
static inline void RTrim(std::wstring &str, const wchar_t* chars)
|
||||
{
|
||||
str.erase(str.find_last_not_of(chars) + 1);
|
||||
}
|
||||
static inline long FindFirstNotOfA(const char* str, const char* chars)
|
||||
{
|
||||
long res = 0;
|
||||
while('\0' != str[res])
|
||||
{
|
||||
long index = 0;
|
||||
while('\0' != chars[index] && chars[index] != str[res])
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if('\0' == chars[index])
|
||||
{
|
||||
break;
|
||||
}
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
static inline long FindLastNotOf(const wchar_t* str, unsigned int unLen, const wchar_t* chars)
|
||||
{
|
||||
long res = unLen;
|
||||
res--;
|
||||
while(res >= 0)
|
||||
{
|
||||
long index = 0;
|
||||
while('\0' != chars[index] && chars[index] != str[res])
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if('\0' == chars[index])
|
||||
{
|
||||
break;
|
||||
}
|
||||
res--;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
static bool FromHumanReadableByteCount(const std::wstring& wsString, long long& res)
|
||||
{
|
||||
res = 0;
|
||||
long long coeff = 0;
|
||||
int unit = 1000;
|
||||
int exp = 0;
|
||||
// Parse leading numeric factor
|
||||
std::size_t pos = 0;
|
||||
try
|
||||
{
|
||||
coeff = std::stoll(wsString, &pos);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip any intermediate white space
|
||||
while (pos < wsString.length() && isspace(wsString[pos])) ++pos;
|
||||
|
||||
// Read off first character which should be an SI prefix
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
switch (toupper(wsString[pos])) {
|
||||
case 'B': exp = 0; break;
|
||||
case 'K': exp = 3; break;
|
||||
case 'M': exp = 6; break;
|
||||
case 'G': exp = 9; break;
|
||||
case 'T': exp = 12; break;
|
||||
case 'E': exp = 15; break;
|
||||
case 'Z': exp = 18; break;
|
||||
case 'Y': exp = 21; break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
|
||||
// If an 'i' or 'I' is present use IEC standard 1024 units
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
if (toupper(wsString[pos]) == 'I') {
|
||||
++pos;
|
||||
unit = 1024;
|
||||
}
|
||||
}
|
||||
|
||||
// Next character must be one of B/empty/whitespace
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
switch (toupper(wsString[pos])) {
|
||||
case 'B':
|
||||
case ' ':
|
||||
case '\t': ++pos; break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip any remaining white space
|
||||
while (pos < wsString.length() && isspace(wsString[pos])) ++pos;
|
||||
|
||||
// Parse error on anything but a null terminator
|
||||
if (pos < wsString.length()) return false;
|
||||
|
||||
res = exp ? (long long)(coeff * pow(unit, exp / 3)) : coeff;
|
||||
return true;
|
||||
wsString.replace(nPos, nFromLen, wsTo);
|
||||
}
|
||||
}
|
||||
static inline void LTrim(std::wstring& str, const wchar_t* chars)
|
||||
{
|
||||
str.erase(0, str.find_first_not_of(chars));
|
||||
}
|
||||
static inline void RTrim(std::wstring& str, const wchar_t* chars)
|
||||
{
|
||||
str.erase(str.find_last_not_of(chars) + 1);
|
||||
}
|
||||
static inline long FindFirstNotOfA(const char* str, const char* chars)
|
||||
{
|
||||
long res = 0;
|
||||
while ('\0' != str[res])
|
||||
{
|
||||
long index = 0;
|
||||
while ('\0' != chars[index] && chars[index] != str[res])
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if ('\0' == chars[index])
|
||||
{
|
||||
break;
|
||||
}
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
static inline long FindLastNotOf(const wchar_t* str, unsigned int unLen, const wchar_t* chars)
|
||||
{
|
||||
long res = unLen;
|
||||
res--;
|
||||
while (res >= 0)
|
||||
{
|
||||
long index = 0;
|
||||
while ('\0' != chars[index] && chars[index] != str[res])
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if ('\0' == chars[index])
|
||||
{
|
||||
break;
|
||||
}
|
||||
res--;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
static bool FromHumanReadableByteCount(const std::wstring& wsString, long long& res)
|
||||
{
|
||||
res = 0;
|
||||
long long coeff = 0;
|
||||
int unit = 1000;
|
||||
int exp = 0;
|
||||
// Parse leading numeric factor
|
||||
std::size_t pos = 0;
|
||||
try
|
||||
{
|
||||
coeff = std::stoll(wsString, &pos);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip any intermediate white space
|
||||
while (pos < wsString.length() && isspace(wsString[pos]))
|
||||
++pos;
|
||||
|
||||
// Read off first character which should be an SI prefix
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
switch (toupper(wsString[pos]))
|
||||
{
|
||||
case 'B':
|
||||
exp = 0;
|
||||
break;
|
||||
case 'K':
|
||||
exp = 3;
|
||||
break;
|
||||
case 'M':
|
||||
exp = 6;
|
||||
break;
|
||||
case 'G':
|
||||
exp = 9;
|
||||
break;
|
||||
case 'T':
|
||||
exp = 12;
|
||||
break;
|
||||
case 'E':
|
||||
exp = 15;
|
||||
break;
|
||||
case 'Z':
|
||||
exp = 18;
|
||||
break;
|
||||
case 'Y':
|
||||
exp = 21;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
|
||||
// If an 'i' or 'I' is present use IEC standard 1024 units
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
if (toupper(wsString[pos]) == 'I')
|
||||
{
|
||||
++pos;
|
||||
unit = 1024;
|
||||
}
|
||||
}
|
||||
|
||||
// Next character must be one of B/empty/whitespace
|
||||
if (pos < wsString.length())
|
||||
{
|
||||
switch (toupper(wsString[pos]))
|
||||
{
|
||||
case 'B':
|
||||
case ' ':
|
||||
case '\t':
|
||||
++pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip any remaining white space
|
||||
while (pos < wsString.length() && isspace(wsString[pos]))
|
||||
++pos;
|
||||
|
||||
// Parse error on anything but a null terminator
|
||||
if (pos < wsString.length())
|
||||
return false;
|
||||
|
||||
res = exp ? (long long)(coeff * pow(unit, exp / 3)) : coeff;
|
||||
return true;
|
||||
}
|
||||
} // namespace NSStringExt
|
||||
|
||||
#endif // _BUILD_STRING_CROSSPLATFORM_H_
|
||||
|
||||
Reference in New Issue
Block a user