Files
core/ASCOfficeXlsFile2/source/XlsFormat/Auxiliary/HelpFunc.cpp
Elen.Subbotina 12dcf40ffe .....
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@67034 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:49:09 +03:00

652 lines
16 KiB
C++

#include "HelpFunc.h"
#ifndef _ASC_USE_UNICODE_CONVERTER_
#if defined (_WIN32) || defined (_WIN64)
#include "shlwapi.h"
#else
#include <iconv.h>
#endif
#else
#include "../../../../UnicodeConverter/UnicodeConverter.h"
#endif
#include <Logic/Biff_structures/CellRangeRef.h>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
namespace AUX
{
const int normalizeColumn(const int column)
{
int norm_col = column;
while(norm_col > 255)
{
norm_col -= 0x100;
}
while(norm_col < 0)
{
norm_col += 0x100; // It is correct. must be on the second place after 255
}
return norm_col;
}
const std::wstring column2str(const int column)
{
int column_value = normalizeColumn(column);
const int radix = L'Z' - L'A' + 1;
std::wstring ret_val;
++column_value;
while(column_value)
{
wchar_t sym = (column_value - 1) % radix + L'A';
ret_val = sym + ret_val;
column_value = (column_value - 1) / radix;
}
return ret_val;
}
const int normalizeRow(const int row)
{
int norm_row = row;
while(norm_row > 65535)
{
norm_row -= 0x10000;
}
while(norm_row < 0)
{
norm_row += 0x10000; // It is correct. must be on the second place after 65535
}
return norm_row;
}
const std::wstring row2str(const int row)
{
int row_value = normalizeRow(row);
return STR::int2wstr(row_value + 1, 10);
}
const std::wstring loc2str(const int row, const bool row_rel, const int column, const bool col_rel)
{
return (col_rel ? L"" : L"$") + column2str(column) + (row_rel ? L"" : L"$") + row2str(row);
}
const int str2column(std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end)
{
const int radix = L'Z' - L'A' + 1;
int column = -1;
for(; str_begin != str_end; ++str_begin)
{
const wchar_t symb = *str_begin;
if(L'A' > symb || L'Z' < symb)
{
break;
}
column = (column + 1) * radix + (symb - L'A');
}
if(column > 255)
{
column = 255;
}
return column;
}
const int str2row(std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end)
{
int row = 0;
for(; str_begin != str_end; ++str_begin)
{
const wchar_t symb = *str_begin;
if(L'0' > symb || L'9' < symb)
{
break;
}
row = row * 10 + (symb - L'0');
}
--row;
if(row > 65535)
{
row = 65535;
}
return row;
}
const bool str2rel(std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end)
{
if(str_begin != str_end && L'$' == *str_begin)
{
++str_begin;
return false;
}
return true;
}
void str2loc(std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end, int& row, bool& row_rel, int& column, bool& col_rel)
{
col_rel = str2rel (str_begin, str_end);
column = str2column (str_begin, str_end);
row_rel = str2rel (str_begin, str_end);
row = str2row (str_begin, str_end);
}
void str2loc(const std::wstring& str, int& row, bool& row_rel, int& column, bool& col_rel)
{
std::wstring::const_iterator str_begin = str.begin();
std::wstring::const_iterator str_end = str.end();
str2loc(str_begin, str_end, row, row_rel, column, col_rel);
}
void str2refs(const std::wstring& str, std::vector<XLS::CellRangeRef>& vec)
{
std::wstring str_left(str);
do
{
XLS::CellRangeRef ref1(str_left);
vec.push_back(ref1);
size_t next_pos = str_left.find_first_of(L' ');
if(std::wstring::npos == next_pos)
{
break;
}
str_left = str_left.substr(next_pos + 1, str_left.length() - next_pos - 1);
}
while(str_left.length());
}
} //namespace AUX
namespace STR
{;
const std::string int2str(const int val, const int radix)
{
static char num_buf[10]={};
#if defined(_WIN32) || defined(_WIN64)
_itoa_s(val, num_buf, 9, radix);
#else
sprintf( num_buf, "%d", val);
#endif
return num_buf;
}
const std::wstring int2wstr(const int val, const int radix)
{
#if defined(_WIN32) || defined(_WIN64)
static wchar_t num_buf[20]={};
_itow_s(val, num_buf, 19, radix);
return std::wstring(num_buf);
#else
static char num_buf[20]={};
sprintf( num_buf, "%d", val);
std::string a_str(num_buf);
return std::wstring(a_str.begin(), a_str.end());
#endif
}
const std::wstring double2str(const double val)
{
return boost::lexical_cast<std::wstring>(val);
}
const std::string bin2str(const char* buf, const size_t nbuf)
{
static const char hex[17] = "0123456789ABCDEF";
std::vector<char> code_string(nbuf * 3 + 1);
size_t idx = 0;
for(size_t i = 0; i < nbuf; ++i)
{
code_string[idx++] = '%';
code_string[idx++] = hex[(buf[i] & 0xf0) >> 4];
code_string[idx++] = hex[buf[i] & 0x0f];
}
code_string[idx] = 0;
return &code_string[0];
}
const std::wstring guid2bstr(const _GUID_ guid)
{
std::wstring guid_ret;
#if defined(_WIN32) || defined(_WIN64)
LPOLESTR guid_str;
GUID guid1={};
memcpy(&guid1, &guid, sizeof(GUID));
if(S_OK != StringFromIID(guid1,&guid_str))
{
// The only case is E_OUTOFMEMORY, so just throw anything
throw;// EXCEPT::LE::WhatIsTheFuck("StringFromIID failed.", "guid2bstr");
}
guid_ret = guid_str;
CoTaskMemFree(guid_str);
#else
//todooooo
#endif
return guid_ret;
}
const std::string guid2str(const _GUID_ guid)
{
std::wstring s = guid2bstr(guid);
return std::string(s.begin(),s.end());
}
const bool bstr2guid(const std::wstring & guid_str, _GUID_& guid)
{
#if defined(_WIN32) || defined(_WIN64)
GUID guid1={};
HRESULT res = IIDFromString((LPWSTR)(guid_str.c_str()), &guid1);
if(S_OK != res)
{
switch(res)
{
case E_INVALIDARG:
return false;
case E_OUTOFMEMORY:
throw;// EXCEPT::LE::WhatIsTheFuck("IIDFromString failed.", "bstr2guid");
}
}
else memcpy(&guid, &guid1, sizeof(guid1));
#else
//todooooo
#endif
return true;
}
const std::wstring int2hex_wstr(const int val, const size_t size_of)
{
if(size_of > 4) return L"";
#if defined(_WIN32) || defined(_WIN64)
static wchar_t num_buf[10]={};
std::wstring wstr = STR::int2wstr(size_of << 1, 10);
swprintf_s(num_buf, 9, (L"%0" + wstr + L"X").c_str(), val);
return std::wstring(num_buf);
#else
char num_buf[10]={};
std::string str = STR::int2str(size_of << 1, 10);
snprintf(num_buf, 9, ("%0" + str + "X").c_str(), val);
std::string res(num_buf);
return std::wstring(res.begin(), res.end());
#endif
}
const std::wstring wchar_t2hex_str(const wchar_t val)
{
static const wchar_t hex[17] = L"0123456789ABCDEF";
wchar_t code_string[5];
code_string[0] = hex[(val & 0xf000) >> 12];
code_string[1] = hex[(val & 0x0f00) >> 8];
code_string[2] = hex[(val & 0x00f0) >> 4];
code_string[3] = hex[(val & 0x000f)];
code_string[4] = 0;
return code_string;
}
static boost::wregex match_hex(L"^_x[0-9A-F]{4}_");
const std::wstring escape_ST_Xstring(const std::wstring& wstr)
{
std::wstring ret_val = L"";
for (size_t i = 0; i < wstr.length(); i++)
{
wchar_t in_symb = wstr[i];
if (in_symb < 0x0009 || in_symb == 0x000B || in_symb == 0x000C || in_symb > 0x000D && in_symb < 0x0020 ||
in_symb > 0xD7FF && in_symb < 0xE000 || in_symb > 0xFFFD)
{
ret_val += L"_x" + wchar_t2hex_str(in_symb) + L"_";
}
else if(L'_' == in_symb && boost::regex_search(std::wstring(wstr, i, 7), match_hex))
{
ret_val += L"_x005F_";
}
else
{
ret_val += in_symb;
}
}
return ret_val;
}
const std::wstring unescape_ST_Xstring(const std::wstring& wstr)
{
std::wstring::const_iterator x_pos_noncopied = wstr.begin();
std::wstring::const_iterator x_pos_next;// = wstr.begin();
std::wstring::const_iterator wstr_end = wstr.end();
std::wstring ret_val = L"";
while(true)
{
#if defined(__linux__) || defined(_MAC)
const auto it_range = boost::make_iterator_range(x_pos_noncopied, wstr_end);
x_pos_next = boost::algorithm::find_first(it_range, L"_x").begin();
#else
x_pos_next = boost::algorithm::find_first(boost::make_iterator_range(x_pos_noncopied, wstr_end), L"_x").begin();
#endif
if ( wstr_end == x_pos_next) break;
if(!boost::regex_search(x_pos_next, wstr_end, match_hex))
{
x_pos_next += 2;
ret_val.append(x_pos_noncopied, x_pos_next);
x_pos_noncopied = x_pos_next;
}
else
{
ret_val += static_cast<wchar_t>(hex_str2int(x_pos_next + 2, x_pos_next + 6));
x_pos_noncopied = x_pos_next + 7;
}
}
ret_val.append(x_pos_noncopied, x_pos_next);
return ret_val;
}
const std::wstring toARGB(const unsigned int rgba)
{
return toARGB(static_cast<unsigned char>(rgba & 0xff), static_cast<unsigned char>((rgba >> 8) & 0xff),
static_cast<unsigned char>((rgba >> 16) & 0xff), static_cast<unsigned char>((rgba >> 24) & 0xff));
}
const std::wstring toRGB(const unsigned int rgba)
{
unsigned char R = static_cast<unsigned char>((rgba >> 16) & 0xff);
unsigned char G = static_cast<unsigned char>((rgba >> 8) & 0xff);
unsigned char B = static_cast<unsigned char>(rgba & 0xff);
return toRGB(R, G ,B);
}
const std::wstring toARGB(const unsigned char red, const unsigned char green, const unsigned char blue, const unsigned char alpha)
{
return int2hex_wstr(alpha, sizeof(alpha)) + toRGB(red, green, blue);
}
const std::wstring toRGB(const unsigned char red, const unsigned char green, const unsigned char blue)
{
return int2hex_wstr(red, sizeof(red)) + int2hex_wstr(green,sizeof(green)) + int2hex_wstr(blue,sizeof(blue));
}
const bool fromARGB(const std::wstring& argb, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha)
{
if(argb.length() < 8)
{
return false;
}
alpha = static_cast<unsigned char> (hex_str2int(argb.substr(0, 2)));
red = static_cast<unsigned char> (hex_str2int(argb.substr(2, 2)));
green = static_cast<unsigned char> (hex_str2int(argb.substr(4, 2)));
blue = static_cast<unsigned char> (hex_str2int(argb.substr(6, 2)));
return true;
}
const int HexChar2Int(const char value)
{
if (value >= '0' && value <= '9')
return value - '0';
if (value >= 'a' && value <= 'f')
return 10 + value - 'a';
if (value >= 'A' && value <= 'F')
return 10 + value - 'A';
return 0;
}
const size_t hex_str2int(const std::wstring& hex)
{
size_t summa = 0;
for (int i = 0; i != hex.length(); ++i)
summa += HexChar2Int((char)hex[i]) << (4 * (hex.length() - i - 1));
return summa;
}
const size_t hex_str2int(const std::wstring::const_iterator& it_begin, const std::wstring::const_iterator& it_end)
{
static const std::wstring hex_digits(L"0123456789ABCDEF");
size_t numeric = 0;
for(std::wstring::const_iterator it = it_begin, itEnd = it_end; it != itEnd; ++it)
{
size_t pos = hex_digits.find_first_of(*it);
if(std::wstring::npos == pos)
{
break;
}
numeric = numeric * 16 + pos;
}
return numeric;
}
#ifdef _ASC_USE_UNICODE_CONVERTER_
const std::wstring toStdWString(std::string ansi_string, const unsigned int code_page)
{
std::string sCodePage;
for (int i = 0; i < UNICODE_CONVERTER_ENCODINGS_COUNT; ++i)
{
if (code_page == NSUnicodeConverter::Encodings[i].WindowsCodePage)
{
sCodePage = NSUnicodeConverter::Encodings[i].Name;
break;
}
}
if (sCodePage.empty())
sCodePage = "CP" + std::to_string(code_page);
NSUnicodeConverter::CUnicodeConverter oConverter;
return oConverter.toUnicode(ansi_string, sCodePage.c_str());
}
const std::string toStdString(std::wstring wide_string, const unsigned int code_page)
{
std::string sCodePage;
for (int i = 0; i < UNICODE_CONVERTER_ENCODINGS_COUNT; ++i)
{
if (code_page == NSUnicodeConverter::Encodings[i].WindowsCodePage)
{
sCodePage = NSUnicodeConverter::Encodings[i].Name;
break;
}
}
if (sCodePage.empty())
sCodePage = "CP" + std::to_string(code_page);
NSUnicodeConverter::CUnicodeConverter oConverter;
return oConverter.fromUnicode(wide_string, sCodePage.c_str());
}
#else
const std::string toStdString(std::wstring wide_string, const unsigned int code_page)
{
#if defined (_WIN32) || defined (_WIN64)
const int nSize = WideCharToMultiByte(code_page, 0, wide_string.c_str(), wide_string.length(), NULL, 0, NULL, NULL);
char *sTemp = new char[nSize];
if (!sTemp)
return std::string();
int size = WideCharToMultiByte(code_page, 0, wide_string.c_str(), wide_string.length(), sTemp, nSize, NULL, NULL);
std::string sResult(sTemp, size);
delete []sTemp;
return sResult;
#else
std::string out;
bool ansi = true;
size_t insize = wide_string.length();
out.reserve(insize);
char *inptr = (char*)wide_string.c_str();
char* outptr = (char*)out.c_str();
if (code_page >= 0)
{
std::string sCodepage = "CP" + std::to_string(code_page);
iconv_t ic= iconv_open(sCodepage.c_str(), "WCHAR_T");
if (ic != (iconv_t) -1)
{
size_t nconv = 0, avail = insize * sizeof(wchar_t);
nconv = iconv (ic, &inptr, &insize, &outptr, &avail);
if (nconv == 0) ansi = false;
iconv_close(ic);
}
}
if (ansi)
out = std::string(wide_string.begin(), wide_string.end());
return out;
#endif
}
const std::wstring toStdWString(std::string ansi_string, const unsigned int code_page)
{
#if defined (_WIN32) || defined (_WIN64)
const int nSize = MultiByteToWideChar(code_page, 0, ansi_string.c_str(), ansi_string.size(), NULL, 0);
wchar_t *sTemp = new wchar_t[nSize];
if (!sTemp)
return std::wstring();
int size = MultiByteToWideChar(code_page, 0, ansi_string.c_str(), ansi_string.size(), sTemp, nSize);
std::wstring sResult(sTemp, size);
delete []sTemp;
return sResult;
#else
bool ansi = true;
size_t insize = ansi_string.length();
std::wstring w_out;
char *inptr = (char*)ansi_string.c_str();
if (code_page >= 0)
{
std::string sCodepage = "CP" + std::to_string(code_page);
iconv_t ic= iconv_open("WCHAR_T", sCodepage.c_str());
if (ic != (iconv_t) -1)
{
size_t nconv = 0, avail = (insize + 1) * sizeof(wchar_t);
char* out_str = new char[avail];
char* outptr = out_str;
nconv = iconv (ic, &inptr, &insize, &outptr, &avail);
if (nconv == 0)
{
insize = ansi_string.length();
((wchar_t*)out_str)[insize] = 0;
w_out = std::wstring((wchar_t*)out_str, insize);
ansi = false;
}
iconv_close(ic);
delete []out_str;
}
}
if (ansi)
w_out = std::wstring(ansi_string.begin(), ansi_string.end());
return w_out;
#endif
}
#endif
} // namespace STR
namespace XMLSTUFF
{;
const std::wstring tab2sheet_name(const short tabid, std::vector<std::wstring>& sheets_names)
{
if(tabid >= 0 && static_cast<unsigned short>(tabid) < sheets_names.size())
{
return sheets_names[tabid];
}
return L"#REF!";
}
//
const std::wstring xti2sheets(const unsigned short ixti, std::vector<std::wstring>& xti_parsed)
{
if(ixti >= 0 && static_cast<unsigned short>(ixti) < xti_parsed.size())
{
return xti_parsed[ixti];
}
return L"#REF!";
}
//
const std::wstring xti_indexes2sheet_name(const short itabFirst, const short itabLast, std::vector<std::wstring>& sheets_names)
{
if(-1 == itabFirst)
{
return L"#REF!";
}
std::wstring sheets_prefix = tab2sheet_name(itabFirst, sheets_names) + ((itabLast == itabFirst) ? L"" : L':' + tab2sheet_name(itabLast, sheets_names));
std::wstring escaped_prefix(boost::algorithm::replace_all_copy(sheets_prefix, L"'", L"''"));
static boost::wregex correct_sheet_name(L"^\\w[\\w\\d.]*(:\\w[\\w\\d.]*)?$");
if(!boost::regex_search(escaped_prefix.begin(), escaped_prefix.end(), correct_sheet_name))
{
return L'\'' + escaped_prefix + L'\'';
}
return escaped_prefix;
}
const std::wstring make3dRef(const unsigned short ixti, const std::wstring cell_ref, std::vector<std::wstring>& xti_parsed)
{
std::wstring sheets_prefix = xti2sheets(ixti, xti_parsed);
if(L"#REF!" == sheets_prefix)
{
return sheets_prefix;
}
return sheets_prefix + L'!' + cell_ref;
}
} //namespace XMLSTUFF