From: <arn...@us...> - 2008-04-14 20:10:55
|
Revision: 1143 http://dcplusplus.svn.sourceforge.net/dcplusplus/?rev=1143&view=rev Author: arnetheduck Date: 2008-04-14 13:10:48 -0700 (Mon, 14 Apr 2008) Log Message: ----------- multiple shares with same name Modified Paths: -------------- dcplusplus/trunk/changelog.txt dcplusplus/trunk/dcpp/ShareManager.cpp dcplusplus/trunk/dcpp/ShareManager.h dcplusplus/trunk/win32/UploadPage.cpp Property Changed: ---------------- dcplusplus/trunk/ Property changes on: dcplusplus/trunk ___________________________________________________________________ Name: bzr:revision-info - timestamp: 2008-04-06 18:48:35.145999908 +0200 committer: poy <po...@12...> properties: branch-nick: bzr + timestamp: 2008-04-06 23:02:37.905999899 +0200 committer: Jacek Sieka <arn...@gm...> properties: branch-nick: dcplusplus Name: bzr:revision-id:v3-trunk1 - 1027 arn...@gm...-20080323183926-schknwnkgeo7ivdn 1028 zouzou123gen-20080323220411-r8usuc3qxwuh7zsn 1029 zouzou123gen-20080323221249-0su72zaj13e706mk 1030 arn...@gm...-20080324140623-muba1dl46m000o8c 1031 zouzou123gen-20080324141933-qbgr93ugpe0297m6 1032 arn...@gm...-20080324153706-siidja05n84i00b1 1033 arn...@gm...-20080324153823-lhn3awurnu77riln 1034 arn...@gm...-20080324165650-zapppziji67yf5a2 1035 zouzou123gen-20080324175936-4mqc2kh0lo5wtdu2 1036 zouzou123gen-20080325004602-6wdsoym95mjuhwd3 1037 arn...@gm...-20080325100659-8fqy6q65itmghlep 1038 zouzou123gen-20080325175216-s297sdiucukfvijh 1039 arn...@gm...-20080325210137-3dfqyoi8ykosy087 1040 arn...@gm...-20080325211747-nwwy1eb33r071sca 1041 arn...@gm...-20080326084110-qbselrjckku275xi 1042 zouzou123gen-20080326123631-35642mgbk2i4ty32 1043 zouzou123gen-20080326124345-f4xwn2d3ty8ubd6r 1044 arn...@gm...-20080326162031-il0nyms30w0mky43 1045 arn...@gm...-20080326164801-8dru8mjc06xgzjpv 1046 arn...@gm...-20080326170438-uzl2rx8fqnohak7g 1047 zouzou123gen-20080326172821-d6uqcbmfb0c6rwlv 1048 arn...@gm...-20080326213257-qlgdh7m2712p2l0q 1049 arn...@gm...-20080326214313-ktnoekgk3s0wmatz 1050 arn...@gm...-20080326215256-0j1iqrf286b9g7zf 1051 arn...@gm...-20080327082121-hoi22wh1gwjdfbyd 1052 arn...@gm...-20080327120639-um3tukdt374rwvgm 1053 zouzou123gen-20080327130703-6vtek6uxy3vua543 1054 arn...@gm...-20080327215831-dmg5mkufskabwkro 1055 arn...@gm...-20080327231459-cdztcv25alsuyqmf 1056 arn...@gm...-20080328085925-gceybsr53oml1p24 1057 arn...@gm...-20080328200512-1sjuu6bcnl2dyd2a 1058 arn...@gm...-20080328210347-bussqjrm5mfswh7o 1059 arn...@gm...-20080329055630-braiir1dskv7a4qm 1060 arn...@gm...-20080329061558-rck8dz60wpj3c5ja 1061 arn...@gm...-20080329081253-if6o5jn329mbzfpl 1062 arn...@gm...-20080329081619-cb4x930j8sp55cs0 1063 arn...@gm...-20080329103216-hgjzo7ra2zixbztd 1064 arn...@gm...-20080329124042-q3aw4iodmo5kafyp 1065 arn...@gm...-20080329124926-2je1z18p0272zpua 1066 arn...@gm...-20080329150901-ehj9t32en7eps2dp 1067 zouzou123gen-20080329153653-36xlvpik2ns9r84r 1068 zouzou123gen-20080329162703-51xr8hg073pg7wq5 1069 zouzou123gen-20080329234706-8ddipdqu0xeudkql 1070 arn...@gm...-20080330081232-ubqr1171ewalrd4q 1071 zouzou123gen-20080330131607-yppbs3mgyjef1cux 1072 zouzou123gen-20080330134835-yv1nogy77ib1uehd 1073 zouzou123gen-20080331124549-alyw7vugdn30piqy 1074 zouzou123gen-20080331135108-q8frtqsin5bosfzm 1075 zouzou123gen-20080331140757-u94q52yccl5lsifk 1076 zouzou123gen-20080331152513-ue1x5qhigcw51348 1077 arn...@gm...-20080331184436-a8g6chibmg8nswls 1078 arn...@gm...-20080331220648-81485k28qmwruwz6 1079 zouzou123gen-20080401081001-2yjn07cf8s5sxr3a 1080 zouzou123gen-20080401081247-f3p4hdjojnd460jw 1081 zouzou123gen-20080401084117-24a454g8o0x656kg 1082 zouzou123gen-20080401133146-jabb5i8870fg6f66 1083 zouzou123gen-20080401154610-mxdqoo5bksru93e6 1084 arn...@gm...-20080401185530-lqj4tflt5ldmx46f 1085 arn...@gm...-20080401212616-ffl7m0xm8gt15knk 1086 arn...@gm...-20080402084515-ofmnwihzv159jton 1087 arn...@gm...-20080402133105-y70soi38owzl76i9 1088 arn...@gm...-20080402142417-rn2dbkx19wfz3vae 1089 arn...@gm...-20080402144459-u3z3hqvl8aqjc4a0 1090 zouzou123gen-20080402145051-zi8tmvy8u3r2mzu8 1091 arn...@gm...-20080402152137-f397uz1yp9qjvfwh 1092 zouzou123gen-20080402170355-29wda40wk3cy7lu5 1093 arn...@gm...-20080402180628-ipos9li0c4bsmq1h 1094 arn...@gm...-20080402181235-s2a6f4ww4lzayl46 1095 arn...@gm...-20080402193851-6mu64vgep6tijith 1096 arn...@gm...-20080402203810-86zpxsx69q83zf3r 1097 arn...@gm...-20080402204331-so2e8n892o23pejr 1098 poy-20080402224153-225qylr2cfwhqrg7 1099 mrmikejj-20080403125112-o8polh8rkn62umyh 1100 arn...@gm...-20080403125139-8xub76j1xazhfxna 1101 po...@12...-20080403140544-13kockkjho883nb4 1102 po...@12...-20080403143012-bxghtoodiolugpbs 1103 arn...@gm...-20080403190809-bbi4bz5rfcvjnt20 1104 arn...@gm...-20080403205410-czxru1vcg1s4wcws 1105 arn...@gm...-20080403213124-54spdrwszgyimd90 1106 po...@12...-20080404002406-aj74x5tngi6mmmj1 1107 arn...@gm...-20080404122415-mjy07qzbaxyhagra 1108 po...@12...-20080404145445-84lyk5tyy3b3br14 1109 po...@12...-20080404231417-v4v8x7u3f0hm0ejc 1110 po...@12...-20080405001107-14d1ojjof8xhvcj8 1111 arn...@gm...-20080405071929-jmnrul21sxx04kky 1112 arn...@gm...-20080405080105-9qbda7be0pi7y1ai 1113 po...@12...-20080405154555-yuj2n5kyndfjlpsf 1114 po...@12...-20080405220250-8y09d0samsj8ja94 1115 po...@12...-20080406134101-4860ytb61sbu3yhg 1116 po...@12...-20080406155849-2wzxzuzs5m8zpk0g 1117 po...@12...-20080406164835-bv5dydhm3qqydsty + 1027 arn...@gm...-20080323183926-schknwnkgeo7ivdn 1028 zouzou123gen-20080323220411-r8usuc3qxwuh7zsn 1029 zouzou123gen-20080323221249-0su72zaj13e706mk 1030 arn...@gm...-20080324140623-muba1dl46m000o8c 1031 zouzou123gen-20080324141933-qbgr93ugpe0297m6 1032 arn...@gm...-20080324153706-siidja05n84i00b1 1033 arn...@gm...-20080324153823-lhn3awurnu77riln 1034 arn...@gm...-20080324165650-zapppziji67yf5a2 1035 zouzou123gen-20080324175936-4mqc2kh0lo5wtdu2 1036 zouzou123gen-20080325004602-6wdsoym95mjuhwd3 1037 arn...@gm...-20080325100659-8fqy6q65itmghlep 1038 zouzou123gen-20080325175216-s297sdiucukfvijh 1039 arn...@gm...-20080325210137-3dfqyoi8ykosy087 1040 arn...@gm...-20080325211747-nwwy1eb33r071sca 1041 arn...@gm...-20080326084110-qbselrjckku275xi 1042 zouzou123gen-20080326123631-35642mgbk2i4ty32 1043 zouzou123gen-20080326124345-f4xwn2d3ty8ubd6r 1044 arn...@gm...-20080326162031-il0nyms30w0mky43 1045 arn...@gm...-20080326164801-8dru8mjc06xgzjpv 1046 arn...@gm...-20080326170438-uzl2rx8fqnohak7g 1047 zouzou123gen-20080326172821-d6uqcbmfb0c6rwlv 1048 arn...@gm...-20080326213257-qlgdh7m2712p2l0q 1049 arn...@gm...-20080326214313-ktnoekgk3s0wmatz 1050 arn...@gm...-20080326215256-0j1iqrf286b9g7zf 1051 arn...@gm...-20080327082121-hoi22wh1gwjdfbyd 1052 arn...@gm...-20080327120639-um3tukdt374rwvgm 1053 zouzou123gen-20080327130703-6vtek6uxy3vua543 1054 arn...@gm...-20080327215831-dmg5mkufskabwkro 1055 arn...@gm...-20080327231459-cdztcv25alsuyqmf 1056 arn...@gm...-20080328085925-gceybsr53oml1p24 1057 arn...@gm...-20080328200512-1sjuu6bcnl2dyd2a 1058 arn...@gm...-20080328210347-bussqjrm5mfswh7o 1059 arn...@gm...-20080329055630-braiir1dskv7a4qm 1060 arn...@gm...-20080329061558-rck8dz60wpj3c5ja 1061 arn...@gm...-20080329081253-if6o5jn329mbzfpl 1062 arn...@gm...-20080329081619-cb4x930j8sp55cs0 1063 arn...@gm...-20080329103216-hgjzo7ra2zixbztd 1064 arn...@gm...-20080329124042-q3aw4iodmo5kafyp 1065 arn...@gm...-20080329124926-2je1z18p0272zpua 1066 arn...@gm...-20080329150901-ehj9t32en7eps2dp 1067 zouzou123gen-20080329153653-36xlvpik2ns9r84r 1068 zouzou123gen-20080329162703-51xr8hg073pg7wq5 1069 zouzou123gen-20080329234706-8ddipdqu0xeudkql 1070 arn...@gm...-20080330081232-ubqr1171ewalrd4q 1071 zouzou123gen-20080330131607-yppbs3mgyjef1cux 1072 zouzou123gen-20080330134835-yv1nogy77ib1uehd 1073 zouzou123gen-20080331124549-alyw7vugdn30piqy 1074 zouzou123gen-20080331135108-q8frtqsin5bosfzm 1075 zouzou123gen-20080331140757-u94q52yccl5lsifk 1076 zouzou123gen-20080331152513-ue1x5qhigcw51348 1077 arn...@gm...-20080331184436-a8g6chibmg8nswls 1078 arn...@gm...-20080331220648-81485k28qmwruwz6 1079 zouzou123gen-20080401081001-2yjn07cf8s5sxr3a 1080 zouzou123gen-20080401081247-f3p4hdjojnd460jw 1081 zouzou123gen-20080401084117-24a454g8o0x656kg 1082 zouzou123gen-20080401133146-jabb5i8870fg6f66 1083 zouzou123gen-20080401154610-mxdqoo5bksru93e6 1084 arn...@gm...-20080401185530-lqj4tflt5ldmx46f 1085 arn...@gm...-20080401212616-ffl7m0xm8gt15knk 1086 arn...@gm...-20080402084515-ofmnwihzv159jton 1087 arn...@gm...-20080402133105-y70soi38owzl76i9 1088 arn...@gm...-20080402142417-rn2dbkx19wfz3vae 1089 arn...@gm...-20080402144459-u3z3hqvl8aqjc4a0 1090 zouzou123gen-20080402145051-zi8tmvy8u3r2mzu8 1091 arn...@gm...-20080402152137-f397uz1yp9qjvfwh 1092 zouzou123gen-20080402170355-29wda40wk3cy7lu5 1093 arn...@gm...-20080402180628-ipos9li0c4bsmq1h 1094 arn...@gm...-20080402181235-s2a6f4ww4lzayl46 1095 arn...@gm...-20080402193851-6mu64vgep6tijith 1096 arn...@gm...-20080402203810-86zpxsx69q83zf3r 1097 arn...@gm...-20080402204331-so2e8n892o23pejr 1098 poy-20080402224153-225qylr2cfwhqrg7 1099 mrmikejj-20080403125112-o8polh8rkn62umyh 1100 arn...@gm...-20080403125139-8xub76j1xazhfxna 1101 po...@12...-20080403140544-13kockkjho883nb4 1102 po...@12...-20080403143012-bxghtoodiolugpbs 1103 arn...@gm...-20080403190809-bbi4bz5rfcvjnt20 1104 arn...@gm...-20080403205410-czxru1vcg1s4wcws 1105 arn...@gm...-20080403213124-54spdrwszgyimd90 1106 po...@12...-20080404002406-aj74x5tngi6mmmj1 1107 arn...@gm...-20080404122415-mjy07qzbaxyhagra 1108 po...@12...-20080404145445-84lyk5tyy3b3br14 1109 po...@12...-20080404231417-v4v8x7u3f0hm0ejc 1110 po...@12...-20080405001107-14d1ojjof8xhvcj8 1111 arn...@gm...-20080405071929-jmnrul21sxx04kky 1112 arn...@gm...-20080405080105-9qbda7be0pi7y1ai 1113 po...@12...-20080405154555-yuj2n5kyndfjlpsf 1114 po...@12...-20080405220250-8y09d0samsj8ja94 1115 po...@12...-20080406134101-4860ytb61sbu3yhg 1116 po...@12...-20080406155849-2wzxzuzs5m8zpk0g 1117 po...@12...-20080406164835-bv5dydhm3qqydsty 1118 arn...@gm...-20080406210237-c7tyfgiz2sjgv044 Modified: dcplusplus/trunk/changelog.txt =================================================================== --- dcplusplus/trunk/changelog.txt 2008-04-14 20:10:03 UTC (rev 1142) +++ dcplusplus/trunk/changelog.txt 2008-04-14 20:10:48 UTC (rev 1143) @@ -26,6 +26,8 @@ * Added the title of the currently selected page in settings (poy) * [L#206785] Fixed a crash when a menu is owner-drawn while the desktop isn't visible (poy) * [L#211313] Fixed bad virtual name being loaded (thanks kulmegil) +* [L#202801] Allow virtual folders to have the same name +* Allow more characters in virtual names * Fixed downloading multiple file lists with the enter key (poy) -- 0.705 2008-03-14 -- Modified: dcplusplus/trunk/dcpp/ShareManager.cpp =================================================================== --- dcplusplus/trunk/dcpp/ShareManager.cpp 2008-04-14 20:10:03 UTC (rev 1142) +++ dcplusplus/trunk/dcpp/ShareManager.cpp 2008-04-14 20:10:48 UTC (rev 1143) @@ -70,9 +70,7 @@ StringList lists = File::findFiles(Util::getConfigPath(), "files?*.xml.bz2"); for_each(lists.begin(), lists.end(), File::deleteFile); - for(Directory::MapIter j = directories.begin(); j != directories.end(); ++j) { - delete j->second; - } + for_each(directories.begin(), directories.end(), DeleteFunction()); } ShareManager::Directory::Directory(const string& aName, Directory* aParent) : @@ -107,15 +105,27 @@ } } -string ShareManager::Directory::getRealPath() const throw() { +string ShareManager::Directory::getRealPath(const std::string& path) const throw(ShareException) { if(getParent()) { - return getParent()->getRealPath() + getName() + PATH_SEPARATOR_STR; + return getParent()->getRealPath(getName() + PATH_SEPARATOR_STR + path); } else { - dcassert(ShareManager::getInstance()->getByVirtual(getName()) != ShareManager::getInstance()->directories.end()); - return ShareManager::getInstance()->getByVirtual(getName())->first; + return ShareManager::getInstance()->findRealRoot(getName(), path); } } +string ShareManager::findRealRoot(const string& virtualRoot, const string& virtualPath) const throw(ShareException) { + for(StringMap::const_iterator i = shares.begin(); i != shares.end(); ++i) { + if(Util::stricmp(i->second, virtualRoot)) { + std::string name = i->first + PATH_SEPARATOR_STR + virtualPath; + if(File::getSize(name) != -1) { + return name; + } + } + } + + throw ShareException(UserConnection::FILE_NOT_AVAILABLE); +} + int64_t ShareManager::Directory::getSize() const throw() { int64_t tmp = size; for(Map::const_iterator i = directories.begin(); i != directories.end(); ++i) @@ -123,21 +133,14 @@ return tmp; } -size_t ShareManager::Directory::countFiles() const throw() { - size_t tmp = files.size(); - for(Map::const_iterator i = directories.begin(); i != directories.end(); ++i) - tmp+=i->second->countFiles(); - return tmp; -} - string ShareManager::toVirtual(const TTHValue& tth) const throw(ShareException) { - Lock l(cs); if(tth == bzXmlRoot) { return Transfer::USER_LIST_NAME_BZ; } else if(tth == xmlRoot) { return Transfer::USER_LIST_NAME; } + Lock l(cs); HashFileMap::const_iterator i = tthIndex.find(tth); if(i != tthIndex.end()) { return i->second->getADCPath(); @@ -147,17 +150,15 @@ } string ShareManager::toReal(const string& virtualFile) throw(ShareException) { + Lock l(cs); if(virtualFile == "MyList.DcLst") { throw ShareException("NMDC-style lists no longer supported, please upgrade your client"); } else if(virtualFile == Transfer::USER_LIST_NAME_BZ || virtualFile == Transfer::USER_LIST_NAME) { generateXmlList(); return getBZXmlFile(); - } else { - string realFile; - Lock l(cs); + } - return findFile(virtualFile)->getRealPath(); - } + return findFile(virtualFile)->getRealPath(); } TTHValue ShareManager::getTTH(const string& virtualFile) const throw(ShareException) { @@ -210,8 +211,8 @@ if(aFile.compare(0, 4, "TTH/") != 0) throw ShareException(UserConnection::FILE_NOT_AVAILABLE); + TTHValue val(aFile.substr(4)); Lock l(cs); - TTHValue val(aFile.substr(4)); HashFileIter i = tthIndex.find(val); if(i == tthIndex.end()) { throw ShareException(UserConnection::FILE_NOT_AVAILABLE); @@ -242,24 +243,22 @@ } string virtualName = virtualFile.substr(1, i-1); - Directory::Map::const_iterator dmi = getByVirtual(virtualName); + DirList::const_iterator dmi = getByVirtual(virtualName); if(dmi == directories.end()) { throw ShareException(UserConnection::FILE_NOT_AVAILABLE); } - Directory* d = dmi->second; + Directory* d = *dmi; - string file = virtualFile.substr(i + 1); - - string::size_type j = 0; - while( (i = file.find('/', j)) != string::npos) { - Directory::MapIter mi = d->directories.find(file.substr(j, i-j)); + string::size_type j = i + 1; + while( (i = virtualName.find('/', j)) != string::npos) { + Directory::MapIter mi = d->directories.find(virtualName.substr(j, i-j)); j = i + 1; if(mi == d->directories.end()) throw ShareException(UserConnection::FILE_NOT_AVAILABLE); d = mi->second; } - Directory::File::Set::const_iterator it = find_if(d->files.begin(), d->files.end(), Directory::File::StringComp(file.substr(j))); + Directory::File::Set::const_iterator it = find_if(d->files.begin(), d->files.end(), Directory::File::StringComp(virtualName.substr(j))); if(it == d->files.end()) throw ShareException(UserConnection::FILE_NOT_AVAILABLE); return it; @@ -269,13 +268,14 @@ string tmp = aVirt; string::size_type idx = 0; - while( (idx = tmp.find_first_of("$|:\\/"), idx) != string::npos) { + while( (idx = tmp.find_first_of("\\/"), idx) != string::npos) { tmp[idx] = '_'; } return tmp; } bool ShareManager::hasVirtual(const string& virtualName) const throw() { + Lock l(cs); return getByVirtual(virtualName) != directories.end(); } @@ -292,11 +292,7 @@ const string& virtualName = aXml.getChildAttrib("Virtual"); string vName = validateVirtual(virtualName.empty() ? Util::getLastDir(realPath) : virtualName); - - // add only unique directories - if(!hasVirtual(vName)) { - directories[realPath] = new Directory(vName, 0); - } + shares.insert(std::make_pair(realPath, virtualName)); } aXml.stepOut(); } @@ -309,15 +305,15 @@ static const string STTH = "TTH"; struct ShareLoader : public SimpleXMLReader::CallBack { - ShareLoader(ShareManager::Directory::Map& aDirs) : dirs(aDirs), cur(0), depth(0) { } + ShareLoader(ShareManager::DirList& aDirs) : dirs(aDirs), cur(0), depth(0) { } virtual void startTag(const string& name, StringPairList& attribs, bool simple) { if(name == SDIRECTORY) { const string& name = getAttrib(attribs, SNAME, 0); if(!name.empty()) { if(depth == 0) { - for(ShareManager::Directory::MapIter i = dirs.begin(); i != dirs.end(); ++i) { - if(Util::stricmp(i->second->getName(), name) == 0) { - cur = i->second; + for(ShareManager::DirList::iterator i = dirs.begin(); i != dirs.end(); ++i) { + if(Util::stricmp((*i)->getName(), name) == 0) { + cur = *i; break; } } @@ -355,7 +351,7 @@ } private: - ShareManager::Directory::Map& dirs; + ShareManager::DirList& dirs; ShareManager::Directory* cur; size_t depth; @@ -380,8 +376,8 @@ SimpleXMLReader(&loader).fromXML(txt); - for(Directory::MapIter i = directories.begin(); i != directories.end(); ++i) { - addTree(*i->second); + for(DirList::const_iterator i = directories.begin(); i != directories.end(); ++i) { + updateIndices(**i); } return true; @@ -396,9 +392,9 @@ aXml.addTag("Share"); aXml.stepIn(); - for(Directory::MapIter i = directories.begin(); i != directories.end(); ++i) { + for(StringMapIter i = shares.begin(); i != shares.end(); ++i) { aXml.addTag("Directory", i->first); - aXml.addChildAttrib("Virtual", i->second->getName()); + aXml.addChildAttrib("Virtual", i->second); } aXml.stepOut(); } @@ -412,12 +408,10 @@ throw ShareException(_("The temporary download directory cannot be shared")); } - string vName = validateVirtual(virtualName); - { Lock l(cs); - for(Directory::MapIter i = directories.begin(); i != directories.end(); ++i) { + for(StringMapIter i = shares.begin(); i != shares.end(); ++i) { if(Util::strnicmp(realPath, i->first, i->first.length()) == 0) { // Trying to share an already shared directory throw ShareException(_("Directory already shared")); @@ -426,63 +420,110 @@ throw ShareException(_("Remove all subdirectories before adding this one")); } } - - if(hasVirtual(vName)) { - throw ShareException(_("Virtual directory name already exists")); - } } Directory* dp = buildTree(realPath, 0); + + string vName = validateVirtual(virtualName); dp->setName(vName); { Lock l(cs); - addTree(*dp); - directories[realPath] = dp; + shares.insert(std::make_pair(realPath, vName)); + updateIndices(*merge(dp)); + setDirty(); } } +ShareManager::Directory* ShareManager::merge(Directory* directory) { + for(DirList::iterator i = directories.begin(); i != directories.end(); ++i) { + if(Util::stricmp((*i)->getName(), directory->getName()) == 0) { + dcdebug("Merging directory %s\n", directory->getName().c_str()); + (*i)->merge(directory); + return *i; + } + } + + dcdebug("Adding new directory %s\n", directory->getName().c_str()); + + directories.push_back(directory); + return directory; +} + +void ShareManager::Directory::merge(Directory* source) { + for(MapIter i = source->directories.begin(); i != source->directories.end(); ++i) { + Directory* subSource = i->second; + + MapIter ti = directories.find(subSource->getName()); + if(ti == directories.end()) { + if(findFile(subSource->getName()) != files.end()) { + dcdebug("File named the same as directory"); + delete subSource; + } else { + directories.insert(std::make_pair(subSource->getName(), subSource)); + } + } else { + Directory* subTarget = ti->second; + subTarget->merge(subSource); + delete subSource; + } + } + + // All subdirs either deleted or moved to target... + source->directories.clear(); + + for(File::Set::iterator i = source->files.begin(); i != source->files.end(); ++i) { + File::Set::iterator j = findFile(i->getName()); + + if(j == files.end()) { + if(directories.find(i->getName()) != directories.end()) { + dcdebug("Directory named the same as file"); + } else { + files.insert(*i); + } + } + } +} + void ShareManager::removeDirectory(const string& realPath) { if(realPath.empty()) return; - { - Lock l(cs); + HashManager::getInstance()->stopHashing(realPath); - Directory::MapIter i = directories.find(realPath); - if(i != directories.end()) { - delete i->second; - directories.erase(i); + Lock l(cs); + + StringMapIter i = shares.find(realPath); + if(i == shares.end()) { + return; + } + + const std::string& vName = i->second; + for(DirList::iterator j = directories.begin(); j != directories.end(); ) { + if(Util::stricmp((*j)->getName(), vName) == 0) { + delete *j; + directories.erase(j++); + } else { + ++j; } - - rebuildIndices(); - setDirty(); } + + shares.erase(i); - HashManager::getInstance()->stopHashing(realPath); + rebuildIndices(); + setDirty(); } void ShareManager::renameDirectory(const string& realPath, const string& virtualName) throw(ShareException) { - string vName = validateVirtual(virtualName); - - Lock l(cs); - //Find the virtual name - if (hasVirtual(vName)) { - throw ShareException(_("Virtual directory name already exists")); - } - - Directory::MapIter j = directories.find(realPath); - if(j == directories.end()) - return; - - j->second->setName(vName); + removeDirectory(realPath); + addDirectory(realPath, virtualName); } -ShareManager::Directory::Map::const_iterator ShareManager::getByVirtual(const string& virtualName) const throw() { - for(Directory::Map::const_iterator i = directories.begin(); i != directories.end(); ++i) { - if(Util::stricmp(i->second->getName(), virtualName) == 0) { +ShareManager::DirList::const_iterator ShareManager::getByVirtual(const string& virtualName) const throw() { + for(DirList::const_iterator i = directories.begin(); i != directories.end(); ++i) { + if(Util::stricmp((*i)->getName(), virtualName) == 0) { return i; } } @@ -491,20 +532,21 @@ int64_t ShareManager::getShareSize(const string& realPath) const throw() { Lock l(cs); - dcassert(realPath.size()>0); +#ifdef PORT_ME + dcassert(realPath.size()>0); Directory::Map::const_iterator i = directories.find(realPath); if(i != directories.end()) { return i->second->getSize(); } - +#endif return -1; } int64_t ShareManager::getShareSize() const throw() { Lock l(cs); int64_t tmp = 0; - for(Directory::Map::const_iterator i = directories.begin(); i != directories.end(); ++i) { + for(HashFileMap::const_iterator i = tthIndex.begin(); i != tthIndex.end(); ++i) { tmp += i->second->getSize(); } return tmp; @@ -711,17 +753,17 @@ return dir; } -void ShareManager::addTree(Directory& dir) { +void ShareManager::updateIndices(Directory& dir) { bloom.add(Text::toLower(dir.getName())); for(Directory::MapIter i = dir.directories.begin(); i != dir.directories.end(); ++i) { - addTree(*i->second); + updateIndices(*i->second); } dir.size = 0; for(Directory::File::Set::iterator i = dir.files.begin(); i != dir.files.end(); ) { - addFile(dir, i++); + updateIndices(dir, i++); } } @@ -729,12 +771,12 @@ tthIndex.clear(); bloom.clear(); - for(Directory::Map::const_iterator i = directories.begin(); i != directories.end(); ++i) { - addTree(*i->second); + for(DirList::const_iterator i = directories.begin(); i != directories.end(); ++i) { + updateIndices(**i); } } -void ShareManager::addFile(Directory& dir, const Directory::File::Set::iterator& i) { +void ShareManager::updateIndices(Directory& dir, const Directory::File::Set::iterator& i) { const Directory::File& f = *i; HashFileIter j = tthIndex.find(f.getTTH()); @@ -784,8 +826,8 @@ StringPairList ShareManager::getDirectories() const throw() { Lock l(cs); StringPairList ret; - for(Directory::Map::const_iterator i = directories.begin(); i != directories.end(); ++i) { - ret.push_back(make_pair(i->second->getName(), i->first)); + for(StringMap::const_iterator i = shares.begin(); i != shares.end(); ++i) { + ret.push_back(make_pair(i->second, i->first)); } return ret; } @@ -794,35 +836,35 @@ StringPairList dirs = getDirectories(); // Don't need to refresh if no directories are shared - if(dirs.begin() == dirs.end()) + if(dirs.empty()) refreshDirs = false; - { - if(refreshDirs) { - LogManager::getInstance()->message(_("File list refresh initiated")); + if(refreshDirs) { + LogManager::getInstance()->message(_("File list refresh initiated")); + + lastFullUpdate = GET_TICK(); + + DirList newDirs; + for(StringPairIter i = dirs.begin(); i != dirs.end(); ++i) { + Directory* dp = buildTree(i->second, 0); + dp->setName(i->first); + newDirs.push_back(dp); + } + + { + Lock l(cs); + for_each(directories.begin(), directories.end(), DeleteFunction()); + directories.clear(); - lastFullUpdate = GET_TICK(); - - Directory::Map newDirs; - for(StringPairIter i = dirs.begin(); i != dirs.end(); ++i) { - Directory* dp = buildTree(i->second, 0); - dp->setName(i->first); - newDirs.insert(make_pair(i->second, dp)); + for(DirList::iterator i = newDirs.begin(); i != newDirs.end(); ++i) { + merge(*i); } - { - Lock l(cs); - for(Directory::MapIter i = directories.begin(); i != directories.end(); ++i) { - delete i->second; - } - directories = newDirs; - - rebuildIndices(); - } - refreshDirs = false; - - LogManager::getInstance()->message(_("File list refresh finished")); + rebuildIndices(); } + refreshDirs = false; + + LogManager::getInstance()->message(_("File list refresh finished")); } if(update) { @@ -864,8 +906,8 @@ newXmlFile.write(SimpleXML::utf8Header); newXmlFile.write("<FileListing Version=\"1\" CID=\"" + ClientManager::getInstance()->getMe()->getCID().toBase32() + "\" Base=\"/\" Generator=\"" APPNAME " " VERSIONSTRING "\">\r\n"); - for(Directory::MapIter i = directories.begin(); i != directories.end(); ++i) { - i->second->toXml(newXmlFile, indent, tmp2, true); + for(DirList::const_iterator i = directories.begin(); i != directories.end(); ++i) { + (*i)->toXml(newXmlFile, indent, tmp2, true); } newXmlFile.write("</FileListing>"); newXmlFile.flush(); @@ -914,13 +956,15 @@ Lock l(cs); if(dir == "/") { - for(Directory::Map::const_iterator i = directories.begin(); i != directories.end(); ++i) { + for(DirList::const_iterator i = directories.begin(); i != directories.end(); ++i) { tmp.clear(); - i->second->toXml(sos, indent, tmp, recurse); + (*i)->toXml(sos, indent, tmp, recurse); } } else { string::size_type i = 1, j = 1; - Directory::Map::const_iterator it = directories.end(); + + Directory* root = NULL; + bool first = true; while( (i = dir.find('/', j)) != string::npos) { if(i == j) { @@ -930,23 +974,25 @@ if(first) { first = false; - it = getByVirtual(dir.substr(j, i-j)); + DirList::const_iterator it = getByVirtual(dir.substr(j, i-j)); if(it == directories.end()) return 0; + root = *it; + } else { - Directory::Map::const_iterator it2 = it->second->directories.find(dir.substr(j, i-j)); - if(it2 == it->second->directories.end()) { + Directory::Map::const_iterator it2 = root->directories.find(dir.substr(j, i-j)); + if(it2 == root->directories.end()) { return 0; } - it = it2; + root = it2->second; } j = i + 1; } - for(Directory::Map::const_iterator it2 = it->second->directories.begin(); it2 != it->second->directories.end(); ++it2) { + for(Directory::Map::const_iterator it2 = root->directories.begin(); it2 != root->directories.end(); ++it2) { it2->second->toXml(sos, indent, tmp, recurse); } - it->second->filesToXml(sos, indent, tmp); + root->filesToXml(sos, indent, tmp); } xml += "</FileListing>"; @@ -1207,8 +1253,8 @@ if(ssl.empty()) return; - for(Directory::Map::const_iterator j = directories.begin(); (j != directories.end()) && (results.size() < maxResults); ++j) { - j->second->search(results, ssl, aSearchType, aSize, aFileType, aClient, maxResults); + for(DirList::const_iterator j = directories.begin(); (j != directories.end()) && (results.size() < maxResults); ++j) { + (*j)->search(results, ssl, aSearchType, aSize, aFileType, aClient, maxResults); } } @@ -1336,24 +1382,33 @@ return; } - for(Directory::Map::const_iterator j = directories.begin(); (j != directories.end()) && (results.size() < maxResults); ++j) { - j->second->search(results, srch, maxResults); + for(DirList::const_iterator j = directories.begin(); (j != directories.end()) && (results.size() < maxResults); ++j) { + (*j)->search(results, srch, maxResults); } } ShareManager::Directory* ShareManager::getDirectory(const string& fname) { - for(Directory::MapIter mi = directories.begin(); mi != directories.end(); ++mi) { + for(StringMapIter mi = shares.begin(); mi != shares.end(); ++mi) { if(Util::strnicmp(fname, mi->first, mi->first.length()) == 0) { - Directory* d = mi->second; - + Directory* d = NULL; + for(DirList::iterator i = directories.begin(); i != directories.end(); ++i) { + if(Util::stricmp((*i)->getName(), mi->second) == 0) { + d = *i; + } + } + + if(!d) { + return NULL; + } + string::size_type i; string::size_type j = mi->first.length(); while( (i = fname.find(PATH_SEPARATOR, j)) != string::npos) { - mi = d->directories.find(fname.substr(j, i-j)); + Directory::MapIter dmi = d->directories.find(fname.substr(j, i-j)); j = i + 1; - if(mi == d->directories.end()) + if(dmi == d->directories.end()) return NULL; - d = mi->second; + d = dmi->second; } return d; } @@ -1366,7 +1421,7 @@ // Check if finished download is supposed to be shared Lock l(cs); const string& n = d->getPath(); - for(Directory::MapIter i = directories.begin(); i != directories.end(); i++) { + for(StringMapIter i = shares.begin(); i != shares.end(); i++) { if(Util::strnicmp(i->first, n, i->first.size()) == 0 && n[i->first.size()] == PATH_SEPARATOR) { string s = n.substr(i->first.size()+1); try { @@ -1397,7 +1452,7 @@ string name = Util::getFileName(fname); int64_t size = File::getSize(fname); Directory::File::Set::iterator it = d->files.insert(Directory::File(name, size, d, root)).first; - addFile(*d, it); + updateIndices(*d, it); } setDirty(); } Modified: dcplusplus/trunk/dcpp/ShareManager.h =================================================================== --- dcplusplus/trunk/dcpp/ShareManager.h 2008-04-14 20:10:03 UTC (rev 1142) +++ dcplusplus/trunk/dcpp/ShareManager.h 2008-04-14 20:10:48 UTC (rev 1143) @@ -86,6 +86,7 @@ SearchManager::TypeModes getType(const string& fileName) const throw(); string validateVirtual(const string& /*aVirt*/) const throw(); + bool hasVirtual(const string& name) const throw(); void addHits(uint32_t aHits) { hits += aHits; @@ -139,7 +140,7 @@ string getADCPath() const { return parent->getADCPath() + name; } string getFullName() const { return parent->getFullName() + name; } - string getRealPath() const { return parent->getRealPath() + name; } + string getRealPath() const { return parent->getRealPath(name); } GETSET(string, name, Name); GETSET(TTHValue, tth, TTH); @@ -166,10 +167,9 @@ string getADCPath() const throw(); string getFullName() const throw(); - string getRealPath() const throw(); + string getRealPath(const std::string& path) const throw(ShareException); int64_t getSize() const throw(); - size_t countFiles() const throw(); void search(SearchResult::List& aResults, StringSearch::List& aStrings, int aSearchType, int64_t aSize, int aFileType, Client* aClient, StringList::size_type maxResults) const throw(); void search(SearchResult::List& aResults, AdcSearch& aStrings, StringList::size_type maxResults) const throw(); @@ -179,6 +179,8 @@ File::Set::const_iterator findFile(const string& aFile) const { return find_if(files.begin(), files.end(), Directory::File::StringComp(aFile)); } + void merge(Directory* source); + GETSET(string, name, Name); GETSET(Directory*, parent, Parent); private: @@ -253,9 +255,13 @@ mutable CriticalSection cs; - // Map real name to directory structure - Directory::Map directories; + // List of root directory items + typedef std::list<Directory*> DirList; + DirList directories; + /** Map real name to virtual name - multiple real names may be mapped to a single virtual one */ + StringMap shares; + typedef unordered_map<TTHValue, Directory::File::Set::const_iterator> HashFileMap; typedef HashFileMap::iterator HashFileIter; @@ -269,12 +275,16 @@ void rebuildIndices(); - void addTree(Directory& aDirectory); - void addFile(Directory& dir, const Directory::File::Set::iterator& i); + void updateIndices(Directory& aDirectory); + void updateIndices(Directory& dir, const Directory::File::Set::iterator& i); + + Directory* merge(Directory* directory); + void generateXmlList(); bool loadCache() throw(); - bool hasVirtual(const string& name) const throw(); - Directory::Map::const_iterator getByVirtual(const string& virtualName) const throw(); + DirList::const_iterator getByVirtual(const string& virtualName) const throw(); + + string findRealRoot(const string& virtualRoot, const string& virtualLeaf) const throw(ShareException); Directory* getDirectory(const string& fname); Modified: dcplusplus/trunk/win32/UploadPage.cpp =================================================================== --- dcplusplus/trunk/win32/UploadPage.cpp 2008-04-14 20:10:03 UTC (rev 1142) +++ dcplusplus/trunk/win32/UploadPage.cpp 2008-04-14 20:10:48 UTC (rev 1143) @@ -256,17 +256,27 @@ if( path[ path.length() -1 ] != _T('\\') ) path += _T('\\'); + ShareManager* sm = ShareManager::getInstance(); try { - LineDlg dlg(this, T_("Virtual name"), T_("Name under which the others see the directory"), Text::toT(ShareManager::getInstance()->validateVirtual(Util::getLastDir(Text::fromT(path))))); - if(dlg.run() == IDOK) { - tstring line = dlg.getLine(); - ShareManager::getInstance()->addDirectory(Text::fromT(path), Text::fromT(line)); - TStringList row; - row.push_back(line); - row.push_back(path); - row.push_back(Text::toT(Util::formatBytes(ShareManager::getInstance()->getShareSize(Text::fromT(path))))); - directories->insert(row); - total->setText(Text::toT(Util::formatBytes(ShareManager::getInstance()->getShareSize()))); + while(true) { + LineDlg dlg(this, T_("Virtual name"), T_("Name under which the others see the directory"), Text::toT(sm->validateVirtual(Util::getLastDir(Text::fromT(path))))); + if(dlg.run() == IDOK) { + tstring line = dlg.getLine(); + if(sm->hasVirtual(sm->validateVirtual(Text::fromT(line)))) { + if(createMessageBox().show(str(TF_("A virtual directory named %1% already exists, do you wish to merge the contents?") % line), + _T(APPNAME) _T(" ") _T(VERSIONSTRING), MessageBox::BOX_YESNO, MessageBox::BOX_ICONQUESTION) == IDNO) { + continue; + } + } + ShareManager::getInstance()->addDirectory(Text::fromT(path), Text::fromT(line)); + TStringList row; + row.push_back(line); + row.push_back(path); + row.push_back(Text::toT(Util::formatBytes(ShareManager::getInstance()->getShareSize(Text::fromT(path))))); + directories->insert(row); + total->setText(Text::toT(Util::formatBytes(ShareManager::getInstance()->getShareSize()))); + } + break; } } catch(const ShareException& e) { createMessageBox().show(Text::toT(e.getError()), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MessageBox::BOX_OK, MessageBox::BOX_ICONSTOP); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |