bool CArtist::Save(TiXmlNode *node, const CStdString &tag, const CStdString& strPath) { if (!node) return false; // we start with a <tag> tag TiXmlElement artistElement(tag.c_str()); TiXmlNode *artist = node->InsertEndChild(artistElement); if (!artist) return false; XMLUtils::SetString(artist, "name", strArtist); CStdStringArray array; StringUtils::SplitString(strGenre, g_advancedSettings.m_musicItemSeparator,array); for (unsigned int i=0;i<array.size();++i) XMLUtils::SetString(artist, "genre", array[i]); array.clear(); StringUtils::SplitString(strStyles, g_advancedSettings.m_musicItemSeparator,array); for (unsigned int i=0;i<array.size();++i) XMLUtils::SetString(artist, "style", array[i]); array.clear(); StringUtils::SplitString(strMoods, g_advancedSettings.m_musicItemSeparator,array); for (unsigned int i=0;i<array.size();++i) XMLUtils::SetString(artist, "mood", array[i]); array.clear(); StringUtils::SplitString(strYearsActive, g_advancedSettings.m_musicItemSeparator,array); for (unsigned int i=0;i<array.size();++i) XMLUtils::SetString(artist, "yearsactive", array[i]); XMLUtils::SetString(artist, "born", strBorn); XMLUtils::SetString(artist, "formed", strFormed); XMLUtils::SetString(artist, "instruments", strInstruments); XMLUtils::SetString(artist, "biography", strBiography); XMLUtils::SetString(artist, "died", strDied); XMLUtils::SetString(artist, "disbanded", strDisbanded); XMLUtils::SetString(artist, "thumbs", thumbURL.m_xml); XMLUtils::SetString(artist, "path", strPath); if (fanart.m_xml.size()) { TiXmlDocument doc; doc.Parse(fanart.m_xml); artist->InsertEndChild(*doc.RootElement()); } // albums for (vector< pair<CStdString,CStdString> >::const_iterator it = discography.begin(); it != discography.end(); ++it) { // add a <album> tag TiXmlElement cast("album"); TiXmlNode *node = artist->InsertEndChild(cast); TiXmlElement title("title"); TiXmlNode *titleNode = node->InsertEndChild(title); TiXmlText name(it->first); titleNode->InsertEndChild(name); TiXmlElement year("year"); TiXmlNode *yearNode = node->InsertEndChild(year); TiXmlText name2(it->second); yearNode->InsertEndChild(name2); } return true; }
TEST(TestStringUtils, JoinString) { CStdString refstr, varstr; CStdStringArray strarray; strarray.push_back("a"); strarray.push_back("b"); strarray.push_back("c"); strarray.push_back("de"); strarray.push_back(","); strarray.push_back("fg"); strarray.push_back(","); refstr = "a,b,c,de,,,fg,,"; StringUtils::JoinString(strarray, ",", varstr); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); strarray.clear(); varstr.clear(); strarray.push_back("g"); strarray.push_back("h"); strarray.push_back("i"); strarray.push_back("jk,"); strarray.push_back(","); strarray.push_back("lmn,,"); strarray.push_back(","); refstr = "g,h,i,jk,,,,lmn,,,,"; varstr = StringUtils::JoinString(strarray, ","); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); }
TEST(TestStringUtils, SplitString) { CStdStringArray varresults; EXPECT_EQ(9, StringUtils::SplitString("a,b,c,de,,,fg,,", ",", varresults)); EXPECT_STREQ("a", varresults.at(0).c_str()); EXPECT_STREQ("b", varresults.at(1).c_str()); EXPECT_STREQ("c", varresults.at(2).c_str()); EXPECT_STREQ("de", varresults.at(3).c_str()); EXPECT_STREQ("", varresults.at(4).c_str()); EXPECT_STREQ("", varresults.at(5).c_str()); EXPECT_STREQ("fg", varresults.at(6).c_str()); EXPECT_STREQ("", varresults.at(7).c_str()); EXPECT_STREQ("", varresults.at(8).c_str()); varresults.clear(); varresults = StringUtils::SplitString("g,h,ij,k,lm,,n", ","); EXPECT_STREQ("g", varresults.at(0).c_str()); EXPECT_STREQ("h", varresults.at(1).c_str()); EXPECT_STREQ("ij", varresults.at(2).c_str()); EXPECT_STREQ("k", varresults.at(3).c_str()); EXPECT_STREQ("lm", varresults.at(4).c_str()); EXPECT_STREQ("", varresults.at(5).c_str()); EXPECT_STREQ("n", varresults.at(6).c_str()); }
// Splits the string input into pieces delimited by delimiter. // if 2 delimiters are in a row, it will include the empty string between them. // added MaxStrings parameter to restrict the number of returned substrings (like perl and python) int StringUtils::SplitString(const CStdString& input, const CStdString& delimiter, CStdStringArray &results, unsigned int iMaxStrings /* = 0 */) { int iPos = -1; int newPos = -1; int sizeS2 = delimiter.GetLength(); int isize = input.GetLength(); results.clear(); vector<unsigned int> positions; newPos = input.Find (delimiter, 0); if ( newPos < 0 ) { results.push_back(input); return 1; } while ( newPos > iPos ) { positions.push_back(newPos); iPos = newPos; newPos = input.Find (delimiter, iPos + sizeS2); } // numFound is the number of delimiters which is one less // than the number of substrings unsigned int numFound = positions.size(); if (iMaxStrings > 0 && numFound >= iMaxStrings) numFound = iMaxStrings - 1; for ( unsigned int i = 0; i <= numFound; i++ ) { CStdString s; if ( i == 0 ) { if ( i == numFound ) s = input; else s = input.Mid( i, positions[i] ); } else { int offset = positions[i - 1] + sizeS2; if ( offset < isize ) { if ( i == numFound ) s = input.Mid(offset); else if ( i > 0 ) s = input.Mid( positions[i - 1] + sizeS2, positions[i] - positions[i - 1] - sizeS2 ); } } results.push_back(s); } // return the number of substrings return results.size(); }
// Splits the string input into pieces delimited by delimiter. // if 2 delimiters are in a row, it will include the empty string between them. int StringUtils::SplitString(const CStdString& input, const CStdString& delimiter, CStdStringArray &results) { int iPos = -1; int newPos = -1; int sizeS2 = delimiter.GetLength(); int isize = input.GetLength(); results.clear(); //CArray positions; vector<unsigned int> positions; newPos = input.Find (delimiter, 0); if ( newPos < 0 ) { results.push_back(input); return 1; } int numFound = 1; while ( newPos > iPos ) { numFound++; positions.push_back(newPos); iPos = newPos; newPos = input.Find (delimiter, iPos + sizeS2); } for ( unsigned int i = 0; i <= positions.size(); i++ ) { CStdString s; if ( i == 0 ) { if (i == positions.size()) s = input; else s = input.Mid( i, positions[i] ); } else { int offset = positions[i - 1] + sizeS2; if ( offset < isize ) { if ( i == positions.size() ) s = input.Mid(offset); else if ( i > 0 ) s = input.Mid( positions[i - 1] + sizeS2, positions[i] - positions[i - 1] - sizeS2 ); } } results.push_back(s); } return numFound; }
bool CASCIIManager::readFile_using_std_stream(CStdString strFileName, CStdStringArray &aRighe /*, UV_MFC::CDlg_Progresso *pDlg*/) ///< Leggo da file. { std::wifstream myfile(strFileName); std::streampos pos_begin = std::ios::beg; std::streampos pos_curr; std::wstring line; CStdString strLine; int fileLen = 0; int nI = 0, nCont = 3500; ULONGLONG nPosition; double dPerc, dPerc1; CStdString strFase; if (myfile.is_open()) { // get length of file: myfile.seekg(0, myfile.end); fileLen = (int)myfile.tellg(); myfile.seekg(0, myfile.beg); pos_curr = myfile.tellg(); aRighe.clear(); while (getline(myfile, line)) { pos_curr = myfile.tellg(); // std::cout << line << '\n'; strLine.Format(_T("%s"), line.c_str()); aRighe.push_back(strLine); nI++; //if (pDlg && nI > nCont) //{ // nPosition = pos_curr.seekpos(); // dPerc = nPosition / (double)fileLen; // dPerc = max(0, min(1, dPerc)); // dPerc1 = pDlg->m_dPercMin + dPerc*(pDlg->m_dPercMax - pDlg->m_dPercMin); // pDlg->SetPos(dPerc1); // strFase.Format(_T("[%d/%d] Reading rows (%.1lf%%)"), pDlg->m_nFaseCurr, pDlg->m_nFaseTot, 100.0*dPerc); // pDlg->SetFase(strFase); // nI = 0; // if (!pDlg->m_bContinua) // { // myfile.close(); // return false; // } //} } myfile.close(); } return true; }
void CAdvancedSettings::GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings) { TiXmlElement *pElement = pRootElement; while (pElement) { int iAction = 0; // overwrite // for backward compatibility const char* szAppend = pElement->Attribute("append"); if ((szAppend && stricmp(szAppend, "yes") == 0)) iAction = 1; // action takes precedence if both attributes exist const char* szAction = pElement->Attribute("action"); if (szAction) { iAction = 0; // overwrite if (stricmp(szAction, "append") == 0) iAction = 1; // append else if (stricmp(szAction, "prepend") == 0) iAction = 2; // prepend } if (iAction == 0) settings.clear(); TiXmlNode* pRegExp = pElement->FirstChild("regexp"); int i = 0; while (pRegExp) { if (pRegExp->FirstChild()) { CStdString regExp = pRegExp->FirstChild()->Value(); regExp.MakeLower(); if (iAction == 2) settings.insert(settings.begin() + i++, 1, regExp); else settings.push_back(regExp); } pRegExp = pRegExp->NextSibling("regexp"); } pElement = pElement->NextSiblingElement(pRootElement->Value()); } }
void CExternalPlayer::GetCustomRegexpReplacers(TiXmlElement *pRootElement, CStdStringArray& settings) { int iAction = 0; // overwrite // for backward compatibility const char* szAppend = pRootElement->Attribute("append"); if ((szAppend && stricmp(szAppend, "yes") == 0)) iAction = 1; // action takes precedence if both attributes exist const char* szAction = pRootElement->Attribute("action"); if (szAction) { iAction = 0; // overwrite if (stricmp(szAction, "append") == 0) iAction = 1; // append else if (stricmp(szAction, "prepend") == 0) iAction = 2; // prepend } if (iAction == 0) settings.clear(); TiXmlElement* pReplacer = pRootElement->FirstChildElement("replacer"); int i = 0; while (pReplacer) { if (pReplacer->FirstChild()) { const char* szGlobal = pReplacer->Attribute("global"); const char* szStop = pReplacer->Attribute("stop"); bool bGlobal = szGlobal && stricmp(szGlobal, "true") == 0; bool bStop = szStop && stricmp(szStop, "true") == 0; CStdString strMatch; CStdString strPat; CStdString strRep; XMLUtils::GetString(pReplacer,"match",strMatch); XMLUtils::GetString(pReplacer,"pat",strPat); XMLUtils::GetString(pReplacer,"rep",strRep); if (!strPat.IsEmpty() && !strRep.IsEmpty()) { CLog::Log(LOGDEBUG," Registering replacer:"); CLog::Log(LOGDEBUG," Match:[%s] Pattern:[%s] Replacement:[%s]", strMatch.c_str(), strPat.c_str(), strRep.c_str()); CLog::Log(LOGDEBUG," Global:[%s] Stop:[%s]", bGlobal?"true":"false", bStop?"true":"false"); // keep literal commas since we use comma as a seperator strMatch.Replace(",",",,"); strPat.Replace(",",",,"); strRep.Replace(",",",,"); CStdString strReplacer = strMatch + " , " + strPat + " , " + strRep + " , " + (bGlobal ? "g" : "") + (bStop ? "s" : ""); if (iAction == 2) settings.insert(settings.begin() + i++, 1, strReplacer); else settings.push_back(strReplacer); } else { // error message about missing tag if (strPat.IsEmpty()) CLog::Log(LOGERROR," Missing <Pat> tag"); else CLog::Log(LOGERROR," Missing <Rep> tag"); } } pReplacer = pReplacer->NextSiblingElement("replacer"); } }
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!dialog) return 0; CFileItemList items; CStdString heading; int iTypes = 0; for (vector<ADDON::TYPE>::const_iterator it = types.begin(); it != types.end(); ++it) { if (*it == ADDON_UNKNOWN) continue; ADDON::VECADDONS addons; iTypes++; if (*it == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (*it == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (*it == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (*it == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(*it, addons); for (ADDON::IVECADDONS it2 = addons.begin() ; it2 != addons.end() ; ++it2) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*it2, "")); if (!items.Contains(item->GetPath())) items.Add(item); } if (!heading.IsEmpty()) heading += ", "; heading += TranslateType(*it, true); } if (iTypes == 0) return 0; dialog->SetHeading(heading); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) showNone = false; if (multipleSelection || iTypes > 1) dialog->EnableButton(true, 186); else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SORT_METHOD_LABEL, SortOrderAscending); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && iTypes == 1 && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(types[0],false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
int CGUIWindowAddonBrowser::SelectAddonID(ADDON::TYPE type, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (type == ADDON_UNKNOWN || !dialog) return 0; ADDON::VECADDONS addons; if (type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(type, addons); CFileItemList items; for (ADDON::IVECADDONS i = addons.begin(); i != addons.end(); ++i) items.Add(CAddonsDirectory::FileItemFromAddon(*i, "")); dialog->SetHeading(TranslateType(type, true)); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) { showNone = false; dialog->EnableButton(true, 186); } else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SORT_ON_TOP); items.Add(item); } items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(type,false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!multipleSelection && dialog->GetSelectedLabel() == -1) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
void CMusikSourcesCtrl::DoDrag( CMusikPropTreeItem* pItem ) { if ( !pItem ) return; COleDataSource datasrc; HGLOBAL hgDrop; DROPFILES* pDrop; CStringList lsDraggedFiles; POSITION pos; CString sFile; UINT uBuffSize = 0; TCHAR* pszBuff; FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; // get a list of filenames with the currently // selected items... CStdStringArray files; int nMode = pItem->GetPlaylistType(); // standard playlist dragged if ( nMode == MUSIK_PLAYLIST_TYPE_STANDARD ) m_Library->GetStdPlaylistFns( pItem->GetPlaylistID(), files, false ); // now playing dragged.. else if ( nMode == MUSIK_SOURCES_TYPE_NOWPLAYING ) { if ( m_Player->GetPlaylist() ) { m_Library->BeginTransaction(); for ( size_t i = 0; i < m_Player->GetPlaylist()->GetCount(); i++ ) files.push_back( m_Player->GetPlaylist()->GetField( i, MUSIK_LIBRARY_TYPE_FILENAME ) ); m_Library->EndTransaction(); } } // library playlist dragged else if ( nMode == MUSIK_SOURCES_TYPE_LIBRARY ) { CMainFrame* pMain = (CMainFrame*)m_Parent; if ( pMain->m_LibPlaylist ) { m_Library->BeginTransaction(); for ( size_t i = 0; i < pMain->m_LibPlaylist->GetCount(); i++ ) files.push_back( pMain->m_LibPlaylist->GetField( i, MUSIK_LIBRARY_TYPE_FILENAME ) ); m_Library->EndTransaction(); } } else if ( nMode == MUSIK_PLAYLIST_TYPE_DYNAMIC ) MessageBox( "This operation is not supported yet.", "Musik", MB_ICONINFORMATION | MB_OK ); if ( !files.size() ) return; // CStringList containing files for ( size_t i = 0; i < files.size(); i++ ) { lsDraggedFiles.AddTail( files.at( i ) ); uBuffSize += files.at( i ).GetLength() + 1; } files.clear(); // Add 1 extra for the final null char, and the size of the DROPFILES struct. uBuffSize = sizeof(DROPFILES) + sizeof(TCHAR) * (uBuffSize + 1); // Allocate memory from the heap for the DROPFILES struct. hgDrop = GlobalAlloc ( GHND | GMEM_SHARE, uBuffSize ); if ( !hgDrop ) return; pDrop = (DROPFILES*) GlobalLock ( hgDrop ); if ( !pDrop ) { GlobalFree ( hgDrop ); return; } // Fill in the DROPFILES struct. pDrop->pFiles = sizeof(DROPFILES); // If we're compiling for Unicode, set the Unicode flag in the struct to // indicate it contains Unicode strings. #ifdef _UNICODE pDrop->fWide = TRUE; #endif; // Copy all the filenames into memory after the end of the DROPFILES struct. pos = lsDraggedFiles.GetHeadPosition(); pszBuff = (TCHAR*) (LPBYTE(pDrop) + sizeof(DROPFILES)); while ( pos ) { lstrcpy ( pszBuff, (LPCTSTR) lsDraggedFiles.GetNext ( pos ) ); pszBuff = 1 + _tcschr ( pszBuff, '\0' ); } GlobalUnlock ( hgDrop ); // Put the data in the data source. datasrc.CacheGlobalData ( CF_HDROP, hgDrop, &etc ); // Add in our own custom data, so we know that the drag originated from our // window. CMyDropTarget::DragEnter() checks for this custom format, and // doesn't allow the drop if it's present. This is how we prevent the user // from dragging and then dropping in our own window. // The data will just be a dummy bool. HGLOBAL hgBool; hgBool = GlobalAlloc ( GHND | GMEM_SHARE, sizeof(bool) ); if ( NULL == hgBool ) { GlobalFree ( hgDrop ); return; } // Put the data in the data source. etc.cfFormat = m_DropID; datasrc.CacheGlobalData ( m_DropID, hgBool, &etc ); // Start the drag 'n' drop! DROPEFFECT dwEffect = datasrc.DoDragDrop ( DROPEFFECT_COPY | DROPEFFECT_MOVE ); // If the DnD completed OK, we remove all of the dragged items from our // list. switch ( dwEffect ) { case DROPEFFECT_COPY: case DROPEFFECT_MOVE: { // the copy completed successfully // do whatever we need to do here TRACE0( "DND from playlist completed successfully. The data has a new owner.\n" ); } break; case DROPEFFECT_NONE: { // This needs special handling, because on NT, DROPEFFECT_NONE // is returned for move operations, instead of DROPEFFECT_MOVE. // See Q182219 for the details. // So if we're on NT, we check each selected item, and if the // file no longer exists, it was moved successfully and we can // remove it from the list. if ( m_IsWinNT ) { // the copy completed successfully // on a windows nt machine. // do whatever we need to do here bool bDeletedAnything = false; if ( ! bDeletedAnything ) { // The DnD operation wasn't accepted, or was canceled, so we // should call GlobalFree() to clean up. GlobalFree ( hgDrop ); GlobalFree ( hgBool ); TRACE0( "DND had a problem. We had to manually free the data.\n" ); } } // not windows NT else { // We're on 9x, and a return of DROPEFFECT_NONE always means // that the DnD operation was aborted. We need to free the // allocated memory. GlobalFree ( hgDrop ); GlobalFree ( hgBool ); TRACE0( "DND had a problem. We had to manually free the data.\n" ); } } break; } }