void CXmlParser::GetTagAttributes(CXmlNode& Node, const _tstring& sTag) { // У узла нет атрибутов if (sTag.find('=') == _tstring::npos) return; TCHAR * itStart = const_cast< TCHAR * > (&sTag[0]); const TCHAR * itEnd = &sTag[sTag.size()]; while (itStart < itEnd) { // Ищем начало имени const TCHAR * itNameStart = std::find(static_cast< const TCHAR * > (itStart), itEnd, ' ') + 1; // Ищем разделитель "=" const TCHAR * itSplitter = std::find(static_cast< const TCHAR * > (itStart), itEnd, '='); // Ищем окончание значения const TCHAR * itValueEnd = std::find(itSplitter + 2, itEnd, '\"'); Node.Data[_tstring(itNameStart, itSplitter)] = _tstring(itSplitter + 2, itValueEnd); itStart = const_cast< TCHAR * > (itValueEnd + 1); } }
// Get field as string _tstring field_impl::as_string() const { if (is_null_flag != -1) return str_buf; SQLLEN sz_needed = 0; SQLTCHAR small_buff[256]; RETCODE rc; // Try with small buffer is_null_flag = 0; rc = SQLGetData(stmt_h, col_num, SQL_C_TCHAR, small_buff, sizeof(small_buff), &sz_needed); if (TIODBC_SUCCESS_CODE(rc)) { if (sz_needed == SQL_NULL_DATA) { is_null_flag = 1; return _tstring(); } str_buf = sqltchar2ybstring(small_buff, ""); return str_buf; } else if (sz_needed > 0) { // A bigger buffer is needed SQLINTEGER sz_buff = sz_needed + 1; SQLTCHAR_buf buff(sz_buff); SQLGetData(stmt_h, col_num, SQL_C_TCHAR, buff.data, sz_buff, &sz_needed); str_buf = sqltchar2ybstring(buff.data, ""); return str_buf; } return _tstring(); // Empty }
_tstring strutils::trim_string(LPCTSTR text, UINT nLimit /*= 256*/) { _tstring res(text); boost::trim(res); _tstring::size_type pos = res.find(_tstring(_T("\r\n"))); if (pos != _tstring::npos) { res.erase(pos); } pos = res.find(_tstring(_T("\n"))); if (pos != _tstring::npos) { res.erase(pos); } if (res.size() > nLimit) { pos = res.rfind(_tstring(_T(" ")), nLimit); if (pos == _tstring::npos) { pos = nLimit; } res.erase(pos); boost::trim_right(res); } return res; }
/** * converts int to string */ _tstring strutils::to_string(int val, size_t size/* = 20*/, int radix/* = 10*/) { _tstring res; res.resize(size); _itot_s(val, &res[0], size, radix); return _tstring(&res[0]); // need for adjusting of the result string size }
//--------------------------------------------------------------------- // PathRenameExtensionのラッパー //--------------------------------------------------------------------- _tstring kjm::util::path_rename_extension(const _tstring& pszPath, const _tstring& pszExt) { TCHAR buffer[MAX_PATH]; if (PathRenameExtension(lstrcpy(buffer, pszPath.c_str()), pszExt.c_str()) == FALSE) { return _tstring(); // 関数失敗の時は、空文字列を返す } return buffer; }
//--------------------------------------------------------------------- // PathRemoveFileSpecのラッパー //--------------------------------------------------------------------- _tstring kjm::util::path_remove_filespec(const _tstring& path) { TCHAR buffer[MAX_PATH]; if (PathRemoveFileSpec(lstrcpy(buffer, path.c_str())) == FALSE) { return _tstring(); // 関数失敗のときは、空文字列を返す } return buffer; }
//--------------------------------------------------------------------- // PathAppend関数のラッパー //--------------------------------------------------------------------- _tstring kjm::util::path_append(const _tstring& pPath, const _tstring& pMore) { TCHAR buffer[MAX_PATH]; if (PathAppend(lstrcpy(buffer, pPath.c_str()), pMore.c_str()) == FALSE) { return _tstring(); // 関数失敗の時は、空文字列を返す } return buffer; }
//--------------------------------------------------------------------- // GetEnvironmentVariable関数のラッパー //--------------------------------------------------------------------- _tstring kjm::util::get_environment_variable(const _tstring& lpName) { // 必要な文字数を求める DWORD dwRet = GetEnvironmentVariable(lpName.c_str(), NULL, 0); if (dwRet == 0) { return _tstring(); // 環境変数なしの時は、空文字列を返す } std::vector<TCHAR> buffer(dwRet); // 必要なバッファを確保 GetEnvironmentVariable(lpName.c_str(), &buffer[0], buffer.size()); return &buffer[0]; }
_tstring strutils::ExtractCaption(LPCTSTR text, UINT nLimit /*= 256*/) { _tstring res(text); boost::trim(res); _tstring::size_type pos = res.find(_tstring(_T("\r\n"))); if (pos != _tstring::npos) { res.erase(pos); } if (res.size() > nLimit) { pos = res.rfind(_tstring(_T(" ")), nLimit); if (pos == _tstring::npos) { pos = nLimit - 3; } res.erase(pos > nLimit - 3 ? nLimit - 3 : pos); boost::trim_right(res); res += (_T("...")); } return res; }
//--------------------------------------------------------------------- // LoadString関数のラッパー //--------------------------------------------------------------------- _tstring kjm::util::load_string(UINT uID, HINSTANCE hInstance) { std::vector<TCHAR> buffer(512); while (1) { int nRet = LoadString(hInstance, uID, &buffer[0], buffer.size()); if (nRet == 0) { return _tstring(); // 文字列リソースが無い時は、空文字列を返す } else if (buffer.size() - 1 > nRet) { // バッファのサイズ - 1が、戻り値よりも大きいときは、 // すべての文字を読み込んだことが確実なので、ループを抜ける。 break; } buffer.resize(buffer.size() * 2); } return &buffer[0]; }
void testMyDateTimeStore() { __int64 tmp; fielddefs* fds = fielddefs::create(); fielddef f; memset(&f, 0, sizeof(fielddef)); f.len = 8; f.pos = 0; //timestamp f.type = ft_mytimestamp; f.decimals = 6; field fd((unsigned char* )&tmp, f, fds); myTimeStamp dt(f.decimals, true); dt = "2010-10-10 00:00:00.123456"; fd = dt.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt.i64, "ft_mytimestamp7 value = " << fd.i64()); //Legacy format myTimeStamp dtl(f.decimals, false); dtl = "2010-10-10 00:00:00"; fd = dtl.i64; BOOST_CHECK_MESSAGE(fd.i64() == dtl.i64, "ft_mytimestamp legacy value = " << fd.i64()); f.decimals = 4; f.len = 7; myTimeStamp dt2(f.decimals, true); dt2 = "2010-10-10 00:00:12.9988"; fd = dt2.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt2.i64, "ft_mytimestamp6 value = " << fd.i64()); f.decimals = 2; f.len = 6; myTimeStamp dt3(f.decimals, true); dt3 = "2010-10-10 00:00:12.23"; fd = dt3.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt3.i64, "ft_mytimestamp5 value = " << fd.i64()); f.decimals = 0; f.len = 5; myTimeStamp dt4(f.decimals, true); dt4 = "2010-10-10 00:00:12"; fd = dt4.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt4.i64, "ft_mytimestamp4 value = " << fd.i64()); //datetime f.decimals = 6; f.len = 8; f.type = ft_mydatetime; myDateTime dt5(f.decimals, true); dt5 = "2015-10-10 00:00:12.445566"; fd = dt5.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt5.i64, "ft_mydatetime8 value = " << fd.i64()); //Legacy format myDateTime dt5l(f.decimals, true); dt5l = "2015-10-10 00:00:12"; fd = dt5l.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt5l.i64, "ft_mydatetime Legacy value = " << fd.i64()); f.decimals = 4; f.len = 7; myDateTime dt6(f.decimals, true); dt6 = "2015-10-10 00:00:12.7788"; fd = dt6.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt6.i64, "ft_mydatetime7 value = " << fd.i64()); f.decimals = 2; f.len = 6; myDateTime dt7(f.decimals, true); dt7 = "2015-10-10 00:00:12.00"; fd = dt7.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt7.i64, "ft_mydatetime6 value = " << fd.i64()); f.decimals = 0; f.len = 5; myDateTime dt71(f.decimals, true); dt71 = "2015-10-10 00:00:12"; fd = dt71.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt71.i64, "ft_mydatetime5 value = " << fd.i64()); //mariadb datetime f.setOptions(FIELD_OPTION_MARIADB); f.decimals = 6; f.len = 8; f.type = ft_mydatetime; maDateTime dta(f.decimals, true); dta = "2015-10-10 00:00:12.445566"; fd = dta.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta.i64, "ft_mydatetime8 maridb value = " << fd.i64()); f.decimals = 4; f.len = 7; maDateTime dta1(f.decimals, true); dta1 = "2015-10-10 00:00:12.7788"; fd = dta1.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta1.i64, "ft_mydatetime7 maridb value = " << fd.i64()); f.decimals = 2; f.len = 6; maDateTime dta2(f.decimals, true); dta2 = "2015-10-10 00:00:12.00"; fd = dta2.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta2.i64, "ft_mydatetime6 maridb value = " << fd.i64()); f.decimals = 0; f.len = 5; maDateTime dta20(f.decimals, true); dta20 = "2015-10-10 00:00:12"; fd = dta20.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta20.i64, "ft_mydatetime6 maridb value = " << fd.i64()); // mariadb time f.decimals = 6; f.len = 6; f.type = ft_mytime; maTime dtma1(f.decimals, true); dtma1 = "00:00:12.123456"; fd = dtma1.i64; BOOST_CHECK_MESSAGE(fd.i64() == dtma1.i64, "ft_mytime6 maridb value = " << fd.i64()); f.decimals = 4; f.len = 5; maTime dtma2(f.decimals, true); dtma2 = "00:00:12.1234"; fd = dtma2.i64; BOOST_CHECK_MESSAGE(fd.i64() == dtma2.i64, "ft_mytime5 maridb value = " << fd.i64()); f.decimals = 2; f.len = 4; maTime dta3(f.decimals, true); dta3 = "00:00:12.12"; fd = dta3.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta3.i64, "ft_mytime4 maridb value = " << fd.i64()); f.decimals = 0; f.len = 3; maTime dta4(f.decimals, true); dta4 = "00:00:12"; fd = dta4.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta4.i64, "ft_mytime3 maridb value = " << fd.i64()); maTime dta5(f.decimals, false); dta5 = "00:00:12"; fd = dta5.i64; BOOST_CHECK_MESSAGE(fd.i64() == dta5.i64, "ft_mytime Legacy maridb value = " << fd.i64()); // MySQl time f.setOptions(0); f.decimals = 6; f.len = 6; f.type = ft_mytime; myTime dt10(f.decimals, true); dt10 = "00:00:12.123456"; fd = dt10.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt10.i64, "ft_mytime6 value = " << fd.i64()); f.decimals = 4; f.len = 5; myTime dt11(f.decimals, true); dt11 = "00:00:12.1234"; fd = dt11.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt11.i64, "ft_mytime5 value = " << fd.i64()); f.decimals = 2; f.len = 4; myTime dt12(f.decimals, true); dt12 = "00:00:12.12"; fd = dt12.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt12.i64, "ft_mytime4 value = " << fd.i64()); f.decimals = 0; f.len = 3; myTime dt13(f.decimals, true); dt13 = "00:00:12"; fd = dt13.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt13.i64, "ft_mytime3 value = " << fd.i64()); myTime dt13l(f.decimals, false); dt13l = "00:00:12"; fd = dt13l.i64; BOOST_CHECK_MESSAGE(fd.i64() == dt13l.i64, "ft_mytime Legacy value = " << fd.i64()); //print f.type = ft_mydatetime; f.decimals = 6; f.len = 8; fd = _T("2015-10-01 20:50:36.002000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.002000")) , "ft_mydatetime string8 = " << fd.c_str()); f.decimals = 4; f.len = 7; fd = _T("2015-10-01 20:50:36.002000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.0020")) , "ft_mydatetime string7 = " << fd.c_str()); f.decimals = 2; f.len = 6; fd = _T("2015-10-01 20:50:36.052000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.05")) , "ft_mydatetime string6 = " << fd.c_str()); f.decimals = 0; f.len = 5; fd = _T("2015-10-01 20:50:36.002000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36")) , "ft_mydatetime string5 = " << fd.c_str()); f.type = ft_mytimestamp; f.decimals = 6; f.len = 7; fd = _T("2015-10-01 20:50:36.052001"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.052001")) , "ft_mytimestamp string7 = " << fd.c_str()); f.decimals = 4; f.len = 6; fd = _T("2015-10-01 20:50:36.052001"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.0520")) , "ft_mytimestamp string6 = " << fd.c_str()); f.decimals = 2; f.len = 5; fd = _T("2015-10-01 20:50:36.052000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36.05")) , "ft_mytimestamp string5 = " << fd.c_str()); f.decimals = 0; f.len = 4; fd = _T("2015-10-01 20:50:36.952000"); BOOST_CHECK_MESSAGE(fd.c_str() == _tstring(_T("2015-10-01 20:50:36")) , "ft_mytimestamp string4 = " << fd.c_str()); fds->release(); }
const TCHAR * CXmlParser::ParseTag(CXmlNode& Node, TCHAR * pStart, const TCHAR * pEnd) { while (pStart < pEnd) { // Ищем начало открывающего тэга const TCHAR * itStartTag = std::find(static_cast< const TCHAR * > (pStart), pEnd, '<'); const TCHAR * itStartTagName = std::find_if(itStartTag, pEnd, boost::algorithm::is_alnum()); // Нашли закрывающий тэг if (itStartTag == itStartTagName || *(itStartTag + 1) == '/') return std::find(const_cast< const TCHAR * > (pStart), pEnd, '>') + 1; // Ищем окончание открывающего тэга const TCHAR * itEndOpenTag = std::find(itStartTag, pEnd, '>'); // Ищем имя тэга const TCHAR * itEndName = std::find_if(itStartTagName, itEndOpenTag, !boost::algorithm::is_alnum()); _tstring sTagName = _tstring(itStartTagName, itEndName); Node.Data[TAG_NAME] = sTagName; // Ищем тип тэга (?, <--) _tstring sTagType = _tstring(itStartTag + 1, itStartTagName); //Находим все атрибуты тэга _tstring sTagData(itStartTagName, itEndOpenTag); if (!sTagType.empty()) // Удаляем тип тэга из строки атрибутов boost::algorithm::replace_all(sTagData, sTagType, ""); GetTagAttributes(Node, sTagData); /*if (!sTagType.empty()) { std::find(const_cast< const TCHAR * > (pStart), pEnd, '>') + 1; }*/ // У тэга нет значения и вложенных тэгов if (*(itEndOpenTag - 1) == '/') { return itEndOpenTag + 1; } else { // Ищем вложенные узлы pStart = const_cast< TCHAR * > (std::find(itStartTagName, pEnd, '>')); while (true) { // Находим вложенные узлы и добавляем в Childs CXmlNode Child; pStart = const_cast< TCHAR * > (ParseTag(Child, pStart, pEnd)); if (!Child.Data.empty()) Node.Childs.push_back(Child); if (pStart >= pEnd) break; // Ищем закрывающий тэг </tag_name> TCHAR * itTagEnd = 0; while (true) { itTagEnd = const_cast< TCHAR * > (std::find(static_cast< const TCHAR * > (pStart), pEnd, '/')); if (*(itTagEnd - 1) == '<' || itTagEnd >= pEnd) break; } const TCHAR * itCloseTagNameEnd = std::find(static_cast< const TCHAR * > (itTagEnd), pEnd, '>'); _tstring sCloseTagName; if (itTagEnd < itCloseTagNameEnd) sCloseTagName.assign(itTagEnd + 1, itCloseTagNameEnd); if (!sCloseTagName.empty() && sCloseTagName == sTagName) { _tstring sValue(pStart, itTagEnd - 1); if (!sValue.empty() && sValue != _T("\n")) Node.Data[TAG_VALUE] = sValue; break; } } } } return pEnd; }
// Set parameter as NULL void param_impl::set_as_null() { set_as_string(_tstring(), true); }
tstring::tstring() { *PSTRING = _tstring(); }