void CLibraryHistory::Serialize(CArchive& ar, int nVersion) { if ( nVersion < 7 ) return; int nCount = 0; POSITION pos; if ( ar.IsStoring() ) { for ( pos = GetIterator() ; pos ; ) { if ( GetNext( pos )->m_pFile != NULL ) nCount ++; } ar.WriteCount( nCount ); for ( pos = GetIterator() ; pos ; ) { CLibraryRecent* pRecent = GetNext( pos ); if ( pRecent->m_pFile != NULL ) pRecent->Serialize( ar, nVersion ); } ar << LastSeededTorrent.m_sPath; if ( LastSeededTorrent.m_sPath.GetLength() ) { ar << LastSeededTorrent.m_sName; ar << LastSeededTorrent.m_tLastSeeded; ar.Write( &LastSeededTorrent.m_pBTH, sizeof(SHA1) ); } } else { Clear(); for ( nCount = ar.ReadCount() ; nCount > 0 ; nCount-- ) { CLibraryRecent* pRecent = new CLibraryRecent(); pRecent->Serialize( ar, nVersion ); if ( pRecent->m_pFile != NULL ) { m_pList.AddTail( pRecent ); } else { delete pRecent; } } if ( nVersion > 22 ) { ar >> LastSeededTorrent.m_sPath; if ( LastSeededTorrent.m_sPath.GetLength() ) { ar >> LastSeededTorrent.m_sName; ar >> LastSeededTorrent.m_tLastSeeded; ar.Read( &LastSeededTorrent.m_pBTH, sizeof(SHA1) ); } }
//---------------------------------------------------------------------------------------------- int ObjectSerializer::SerializeUserDefinedType(ISerializable *pObj, TypeNode* pType, bool isPtr, fstream& pen) { int size = 0; bool isNull = false; if (isPtr) { // Access the pointer pointed by the pointer to pointer pObj = (*(ISerializable**)pObj); int length = 0; string typeName; char buffer[MaxTypeNameLength + 1]; isNull = (NULL == pObj); pen.write(reinterpret_cast<char*>(&isNull), sizeof(bool)); if (!isNull) { auto objLayout = pObj->GetObjectLayout(); typeName = g_ObjectFactory.FromCName(objLayout.CName()); PerformLateBinding(pObj, pType); length = typeName.size(); _ASSERTE(length <= MaxTypeNameLength); strcpy_s(buffer, typeName.c_str()); buffer[length] = 0; pen.write(buffer, MaxTypeNameLength + 1); Iterator* addresses = objLayout.GetIterator(); unsigned* addr32; for (int memberIdx = 0; addresses->MoveNext(); ++memberIdx) { _ASSERTE(memberIdx < pType->Children.size()); addr32 = reinterpret_cast<unsigned*>(addresses->Current()); SerializeType(reinterpret_cast<char*>(*addr32), pType->Children[memberIdx].Ptr32, pen); } } size = sizeof(unsigned); } else { auto objLayout = pObj->GetObjectLayout(); Iterator* addresses = objLayout.GetIterator(); unsigned* addr32; for (int memberIdx = 0; addresses->MoveNext(); ++memberIdx) { _ASSERTE(memberIdx < pType->Children.size()); addr32 = reinterpret_cast<unsigned*>(addresses->Current()); SerializeType(reinterpret_cast<char*>(*addr32), pType->Children[memberIdx].Ptr32, pen); } size = objLayout.TypeSize(); } return size; }
//---------------------------------------------------------------------------------------------- int ObjectSerializer::DeserializeUserDefinedType(ISerializable* pMem, TypeNode* pType, bool isPtr, fstream& eye) { int size = 0; ISerializable* pObj = NULL; bool isNull = false; if (isPtr) { unsigned* addr32; eye.read(reinterpret_cast<char*>(&isNull), sizeof(bool)); addr32 = reinterpret_cast<unsigned*>(pMem); if (!isNull) { string typeName; char buffer[MaxTypeNameLength + 1]; eye.read(buffer, MaxTypeNameLength + 1); typeName = buffer; pObj = static_cast<ISerializable*>(g_ObjectFactory.Create(typeName)); PerformLateBinding(pObj, pType); auto objLayout = pObj->GetObjectLayout(); Iterator* addresses = objLayout.GetIterator(); unsigned* addr32; for (int memberIdx = 0; addresses->MoveNext(); ++memberIdx) { _ASSERTE(memberIdx < pType->Children.size()); addr32 = reinterpret_cast<unsigned*>(addresses->Current()); DeserializeType(reinterpret_cast<char*>(*addr32), pType->Children[memberIdx].Ptr32, eye); } } *addr32 = reinterpret_cast<unsigned>(pObj); size = sizeof(unsigned); } else { pObj = reinterpret_cast<ISerializable*>(pMem); auto objLayout = pObj->GetObjectLayout(); Iterator* addresses = objLayout.GetIterator(); unsigned* addr32; for (int memberIdx = 0; addresses->MoveNext(); ++memberIdx) { _ASSERTE(memberIdx < pType->Children.size()); addr32 = reinterpret_cast<unsigned*>(addresses->Current()); DeserializeType(reinterpret_cast<char*>(*addr32), pType->Children[memberIdx].Ptr32, eye); } size = objLayout.TypeSize(); } return size; }
void CSecurity::Clear() { CQuickLock oLock( m_pSection ); for ( POSITION pos = m_Complains.GetStartPosition() ; pos ; ) { DWORD pAddress; CComplain* pComplain; m_Complains.GetNextAssoc( pos, pAddress, pComplain ); delete pComplain; } m_Complains.RemoveAll(); for ( POSITION pos = GetIterator() ; pos ; ) { delete GetNext( pos ); } m_pRules.RemoveAll(); m_Cache.clear(); m_AddressMap.clear(); m_pRuleIndexMap.clear(); for ( BYTE nType = 0 ; nType < urnLast ; nType++ ) m_HashMap[ nType ].clear(); }
BNetworkCookieJar::~BNetworkCookieJar() { BNetworkCookie* cookiePtr; for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) delete it.Remove(); }
void CDownloadWithSources::RemoveOverlappingSources(QWORD nOffset, QWORD nLength) { CQuickLock pLock( Transfers.m_pSection ); for ( POSITION posSource = GetIterator() ; posSource ; ) { CDownloadSource* pSource = GetNext( posSource ); if ( pSource->TouchedRange( nOffset, nLength ) ) { if ( GetTaskType() == dtaskMergeFile ) { // Merging process can produce corrupted blocks, retry connection after 30 seconds pSource->m_nFailures = 0; pSource->Close( 30 ); } else { theApp.Message( MSG_ERROR, IDS_DOWNLOAD_VERIFY_DROP, (LPCTSTR)CString( inet_ntoa( pSource->m_pAddress ) ), (LPCTSTR)pSource->m_sServer, (LPCTSTR)m_sName, nOffset, nOffset + nLength - 1 ); pSource->Remove( TRUE, FALSE ); } } } }
int CDownloadWithSources::GetSourceColor() { CQuickLock pLock( Transfers.m_pSection ); BOOL bTaken[SRC_COLORS] = {}; unsigned int nFree = SRC_COLORS; for ( POSITION posSource = GetIterator() ; posSource ; ) { CDownloadSource* pSource = GetNext( posSource ); if ( pSource->m_nColor >= 0 ) { if ( bTaken[ pSource->m_nColor ] == FALSE ) { bTaken[ pSource->m_nColor ] = TRUE; nFree--; } } } if ( nFree == 0 ) return GetRandomNum( 0u, SRC_COLORS - 1 ); nFree = GetRandomNum( 0u, nFree - 1 ); for ( int nColor = 0 ; nColor < SRC_COLORS ; nColor++ ) { if ( bTaken[ nColor ] == FALSE ) { if ( nFree-- == 0 ) return nColor; } } return GetRandomNum( 0u, SRC_COLORS - 1 ); }
void CLibraryHistory::ClearTodays() { for ( POSITION pos = GetIterator() ; pos ; ) { GetNext( pos )->m_bToday = FALSE; } }
CPrivateChatWnd* CChatWindows::FindED2KFrame(DWORD nClientID, const SOCKADDR_IN* pServerAddress) const { // For Low ID clients if ( ( nClientID > 0 ) && ( nClientID < 16777216 ) ) // ED2K Low ID { CString strLowID; strLowID.Format( L"%u@%s:%hu", nClientID, (LPCTSTR)CString( inet_ntoa( pServerAddress->sin_addr ) ), pServerAddress->sin_port ); for ( POSITION pos = GetIterator(); pos; ) { CPrivateChatWnd* pFrame = static_cast<CPrivateChatWnd*>( GetNext( pos ) ); if ( pFrame->IsKindOf( RUNTIME_CLASS(CPrivateChatWnd) ) ) { if ( pFrame->Find( strLowID ) ) return pFrame; } } } return NULL; }
BOOL CPlugins::OnExecuteFile(LPCTSTR pszFile, BOOL bUseImageViewer) { CPlugin* pImageViewer = NULL; for ( POSITION pos = GetIterator() ; pos ; ) { CPlugin* pPlugin = GetNext( pos ); if ( pPlugin->m_pExecute ) { if ( pPlugin->m_sName == _T("PeerProject Image Viewer") ) { pImageViewer = pPlugin; continue; } if ( pPlugin->m_pExecute->OnExecute( CComBSTR( pszFile ) ) == S_OK ) return TRUE; } } if ( bUseImageViewer && pImageViewer ) return ( pImageViewer->m_pExecute->OnExecute( CComBSTR( pszFile ) ) == S_OK ); return FALSE; }
BOOL CPlugins::OnCommand(CChildWnd* pActiveWnd, UINT nCommandID) { if ( pActiveWnd != NULL && pActiveWnd->IsKindOf( RUNTIME_CLASS(CPluginWnd) ) ) { CPluginWnd* pPluginWnd = (CPluginWnd*)pActiveWnd; if ( pPluginWnd->m_pOwner ) { if ( pPluginWnd->m_pOwner->OnCommand( nCommandID ) == S_OK ) return TRUE; } } for ( POSITION pos = GetIterator() ; pos ; ) { CPlugin* pPlugin = GetNext( pos ); if ( pPlugin->m_pCommand ) { if ( pPlugin->m_pCommand->OnCommand( nCommandID ) == S_OK ) return TRUE; } } return FALSE; }
void CNetwork::Clear() { for ( POSITION pos = GetIterator() ; pos ; ) { GetNext( pos )->Disconnect(); } }
BOOL CNetwork::RunNeighbours() { for ( POSITION posNext = GetIterator() ; posNext ; ) { CTransfer* pTransfer = GetNext( posNext ); try { if ( ! pTransfer->OnRun() ) return FALSE; } catch( CHAR* sError ) { CString strHost = inet_ntoa( pTransfer->m_pHost.sin_addr ); XDebugLog( MSG_ERROR, "error on channel '%s': %s", strHost, sError ); return FALSE; } #ifndef _DEBUG catch(...) { CString strHost = inet_ntoa( pTransfer->m_pHost.sin_addr ); XDebugLog( MSG_ERROR, "error on channel '%s': %s", strHost, "a fatal error" ); return FALSE; } #endif } return TRUE; }
void CSecurity::Expire() { CQuickLock oLock( m_pSection ); const DWORD tNow = static_cast< DWORD >( time( NULL ) ); for ( POSITION pos = m_Complains.GetStartPosition() ; pos ; ) { DWORD pAddress; CComplain* pComplain; m_Complains.GetNextAssoc( pos, pAddress, pComplain ); if ( pComplain->m_nExpire < tNow ) { m_Complains.RemoveKey( pAddress ); delete pComplain; } } for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } } }
BOOL CSecurity::IsDenied(const CQuerySearch* pQuery, const CString& strContent) { const DWORD tNow = static_cast< DWORD >( time( NULL ) ); CQuickLock oLock( m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { POSITION posLast = pos; CSecureRule* pRule = GetNext( pos ); if ( pRule->IsExpired( tNow ) ) { m_pRules.RemoveAt( posLast ); delete pRule; } else if ( pRule->Match( pQuery, strContent ) ) { pRule->m_nToday ++; pRule->m_nEver ++; if ( pRule->m_nAction == CSecureRule::srDeny ) return TRUE; if ( pRule->m_nAction == CSecureRule::srAccept ) return FALSE; } } return m_bDenyPolicy; }
void CUploads::OnRename(LPCTSTR pszSource, LPCTSTR pszTarget) { CSingleLock pLock( &Transfers.m_pSection ); if ( pLock.Lock( 500 ) ) { for ( POSITION pos = GetIterator() ; pos ; ) { GetNext( pos )->OnRename( pszSource, pszTarget ); } pLock.Unlock(); } CSingleLock pLock2( &theApp.m_pSection ); if ( pLock2.Lock( 500 ) ) { if ( CMainWnd* pMainWnd = (CMainWnd*)theApp.m_pSafeWnd ) { CMediaWnd* pMediaWnd = (CMediaWnd*)pMainWnd->m_pWindows.Find( RUNTIME_CLASS(CMediaWnd) ); if ( pMediaWnd != NULL ) { pMediaWnd->OnFileDelete( pszSource ); } } pLock2.Unlock(); } }
int CUploads::GetCount(CUploadTransfer* pExcept, int nState) const { if ( pExcept == NULL && nState == -1 ) return m_pList.GetCount(); int nCount = 0; for ( POSITION pos = GetIterator() ; pos ; ) { CUploadTransfer* pUpload = GetNext( pos ); if ( pUpload != pExcept ) { switch ( nState ) { case -1: nCount++; break; case -2: if ( pUpload->m_nState > upsNull ) nCount++; break; default: if ( pUpload->m_nState == nState ) nCount++; break; } } } return nCount; }
uint16_t CFX_ListItem::GetFirstChar() const { CPVT_Word word; CFX_Edit_Iterator* pIterator = GetIterator(); pIterator->SetAt(1); pIterator->GetWord(word); return word.Word; }
CG2Neighbour* CNeighboursWithG2::GetRandomHub(CG2Neighbour* pExcept, GGUID* pGUID) { CPtrArray pRandom; for ( POSITION pos = GetIterator() ; pos ; ) { CG2Neighbour* pNeighbour = (CG2Neighbour*)GetNext( pos ); if ( pNeighbour->m_nState == nrsConnected && pNeighbour->m_nProtocol == PROTOCOL_G2 && pNeighbour->m_nNodeType != ntLeaf && pNeighbour != pExcept ) { if ( pNeighbour->m_pGUIDCache->Lookup( pGUID ) == NULL ) { pRandom.Add( pNeighbour ); } } } int nSize = pRandom.GetSize(); if ( ! nSize ) return NULL; nSize = rand() % nSize; return (CG2Neighbour*)pRandom.GetAt( nSize ); }
DWORD CDownloadWithSources::GetSourceCount(BOOL bNoPush, BOOL bSane) const { CQuickLock pLock( Transfers.m_pSection ); if ( ! bNoPush && ! bSane ) return GetCount(); const DWORD tNow = GetTickCount(); DWORD nCount = 0; for ( POSITION posSource = GetIterator() ; posSource ; ) { CDownloadSource* pSource = GetNext( posSource ); if ( ! bNoPush || ! pSource->m_bPushOnly ) { if ( ! bSane || ( ( pSource->m_tAttempt < tNow || pSource->m_tAttempt - tNow <= 900000 ) && ! pSource->m_bKeep ) ) { nCount++; } } } return nCount; }
void CDownloadWithSources::SortSource(CDownloadSource* pSource) { CQuickLock pLock( Transfers.m_pSection ); if ( m_pSources.GetCount() == 1 ) return; // No sorting POSITION posSource = m_pSources.Find( pSource ); ASSERT( posSource ); m_pSources.RemoveAt( posSource ); // Run through the sources to the correct position for ( POSITION posCompare = GetIterator() ; posCompare ; ) { posSource = posCompare; CDownloadSource* pCompare = GetNext( posCompare ); if ( pCompare->m_nSortOrder >= pSource->m_nSortOrder ) break; } // Insert source in front of current compare source m_pSources.InsertBefore( posSource, pSource ); }
int CUploads::GetTorrentCount(int nState) const { int nCount = 0; for ( POSITION pos = GetIterator() ; pos ; ) { CUploadTransfer* pUpload = GetNext( pos ); if ( pUpload->m_nProtocol == PROTOCOL_BT ) { switch ( nState ) { case -1: nCount++; break; case -2: if ( pUpload->m_nState > upsNull ) nCount++; break; case -3: if ( pUpload->m_nState >= upsUploading ) nCount++; break; default: if ( pUpload->m_nState == nState ) nCount++; break; } } } return nCount; }
CPrivateChatFrame* CChatWindows::FindED2KFrame(DWORD nClientID, SOCKADDR_IN* pServerAddress) { // For Low ID clients if ( ( nClientID > 0 ) && ( nClientID < 16777216 ) ) // ED2K Low ID { CString strLowID; strLowID.Format( _T("%u@%s:%hu"), nClientID, (LPCTSTR)CString( inet_ntoa( pServerAddress->sin_addr ) ), pServerAddress->sin_port ); for ( POSITION pos = GetIterator() ; pos ; ) { CPrivateChatFrame* pFrame = reinterpret_cast<CPrivateChatFrame*>( GetNext( pos ) ); if ( pFrame->IsKindOf( RUNTIME_CLASS(CPrivateChatFrame) ) ) { if ( ( strLowID == pFrame->m_sNick ) && ( pFrame->m_pSession == NULL ) ) { return pFrame; } } } } return NULL; }
ECode NetworkIdentitySet::WriteToStream( /* [in] */ IDataOutput* out) { VALIDATE_NOT_NULL(out); out->WriteInt32(VERSION_ADD_NETWORK_ID); Int32 size; GetSize(&size); out->WriteInt32(size); AutoPtr<IIterator> iter; GetIterator((IIterator**)&iter); while (Ptr(iter)->Func(iter->HasNext)) { AutoPtr<INetworkIdentity> ident = INetworkIdentity::Probe(Ptr(iter)->Func(iter->GetNext)); Int32 type; ident->GetType(&type); out->WriteInt32(type); Int32 subtype; ident->GetSubType(&subtype); out->WriteInt32(subtype); String subscriberId; ident->GetSubscriberId(&subscriberId); WriteOptionalString(out, subscriberId); String networkId; ident->GetNetworkId(&networkId); WriteOptionalString(out, networkId); Boolean roaming; ident->GetRoaming(&roaming); out->WriteBoolean(roaming); } return NOERROR; }
CLiveList* CSecurity::GetList() const { CQuickLock oLock( m_pSection ); CLiveList* pLiveList = new CLiveList( COL_SECURITY_LAST, GetCount() + GetCount() / 4u ); if ( CLiveItem* pDefault = pLiveList->Add( (LPVOID)0 ) ) { pDefault->Set( COL_SECURITY_NUM, _T(" - ") ); // Need leading space for proper sort priority (until sorting is fixed) pDefault->Set( COL_SECURITY_CONTENT, LoadString( IDS_SECURITY_DEFAULT ) ); // "Default Policy" pDefault->Set( COL_SECURITY_ACTION, LoadString( Security.m_bDenyPolicy ? IDS_SECURITY_DENY : IDS_SECURITY_ACCEPT ) ); pDefault->SetImage( Security.m_bDenyPolicy ? Settings.General.LanguageRTL ? 0 : 2 : 1 ); } const DWORD tNow = static_cast< DWORD >( time( NULL ) ); int nCount = 1; for ( POSITION pos = GetIterator() ; pos ; ++nCount ) { GetNext( pos )->ToList( pLiveList, nCount, tNow ); } // Unimplemented seperate IP address rules //for ( CAddressRuleMap::const_iterator i = m_pIPRules.begin() ; i != m_pIPRules.end() ; ++i, ++nCount ) //{ // (*i).second->ToList( pLiveList, nCount, tNow ); //} return pLiveList; }
// Takes a connected computer to ignore, and a GUID (do) // Randomly chooses a neighbour from amongst those that are connected, running Gnutella2, hubs, and don't know about the GUID // Returns a pointer to that randomly selected neighbour CG2Neighbour* CNeighboursWithG2::GetRandomHub(CG2Neighbour* pExcept, const Hashes::Guid& oGUID) { // Make a new local empty list that will hold pointers to neighbours CArray< CG2Neighbour* > pRandom; // Loop through each computer we're connected to for ( POSITION pos = GetIterator() ; pos ; ) { // Get the neighbour under the current position, and move to the next one in the list CNeighbour* pNeighbour = GetNext( pos ); // If this is a Gnutella2 hub if ( pNeighbour->m_nState == nrsConnected && // We've finished the handshake with this computer, and pNeighbour->m_nProtocol == PROTOCOL_G2 && // It's running Gnutella2 software, and pNeighbour->m_nNodeType != ntLeaf && // Our connection to it isn't down to a leaf, and pNeighbour != pExcept ) // It's not the one the caller told us to avoid { // And it doesn't know the given GUID, add it to the random list if ( static_cast< CG2Neighbour* >( pNeighbour )->m_pGUIDCache->Lookup( oGUID ) == NULL ) pRandom.Add( static_cast< CG2Neighbour* >( pNeighbour ) ); } } // If we didn't find any neighbours to put in the list, return null INT_PTR nSize = pRandom.GetSize(); if ( ! nSize ) return NULL; // Choose a random number between 0 and nSize - 1, use it as an index, and return the neighbour at it nSize = GetRandomNum< INT_PTR >( 0, nSize - 1 ); return pRandom.GetAt( nSize ); }
void JackMidiService::SetFrameOffset(int offset) { IteratorPtr<MidiDevice>it(GetIterator()) ; for (it->Begin();!it->IsDone();it->Next()) { JackMidiDevice ¤t=(JackMidiDevice &)it->CurrentItem() ; current.SetFrameOffset(offset) ; } } ;
// Takes a protocol, like Gnutella, a state, like connecting, and a node connection type, like we are both ultrapeers // Counts the number of neighbours in the list that match these criteria, pass -1 to count them all DWORD CNeighboursBase::GetCount(PROTOCOLID nProtocol, int nState, int nNodeType) const { DWORD nCount = 0; CSingleLock pLock( &Network.m_pSection, FALSE ); if ( pLock.Lock( 200 ) ) { for ( POSITION pos = GetIterator() ; pos ; ) { CNeighbour* pNeighbour = GetNext( pos ); // If this neighbour has the protocol we are looking for, or nProtocl is negative to count them all if ( nProtocol == PROTOCOL_ANY || nProtocol == pNeighbour->m_nProtocol ) { // If this neighbour is currently in the state we are looking for, or nState is negative to count them all if ( nState < 0 || nState == pNeighbour->m_nState ) { // If this neighbour is in the ultra or leaf role we are looking for, or nNodeType is null to count them all if ( nNodeType < 0 || nNodeType == pNeighbour->m_nNodeType ) nCount++; } } } } return nCount; }
// Find the newest neighbor object CNeighbour* CNeighboursBase::GetNewest(PROTOCOLID nProtocol, int nState, int nNodeType) const { ASSUME_LOCK( Network.m_pSection ); const DWORD tNow = GetTickCount(); DWORD tMinTime = 0xffffffff; CNeighbour* pNewestNeighbour = NULL; for ( POSITION pos = GetIterator() ; pos ; ) { CNeighbour* pNeighbour = GetNext( pos ); if ( ( nProtocol == PROTOCOL_ANY || nProtocol == pNeighbour->m_nProtocol ) && ( nState < 0 || nState == pNeighbour->m_nState ) && ( nNodeType < 0 || nNodeType == pNeighbour->m_nNodeType ) ) { DWORD tTime = tNow - pNeighbour->m_tConnected; if ( tTime < tMinTime ) { tMinTime = tTime; pNewestNeighbour = pNeighbour; } } } return pNewestNeighbour; }
// Counts how many connections to leaves we have for that protocol, and compares that number to settings limit // Returns true if we need more leaf connections, false if we have enough bool CNeighboursWithConnect::NeedMoreLeafs(PROTOCOLID nProtocol) const { if ( ! Network.IsConnected() ) return false; switch ( nProtocol ) { case PROTOCOL_NULL: if ( ! Settings.Gnutella1.Enabled && ! Settings.Gnutella2.Enabled ) return false; break; case PROTOCOL_G1: if ( ! Settings.Gnutella1.Enabled ) return false; break; case PROTOCOL_G2: if ( ! Settings.Gnutella2.Enabled ) return false; break; default: return false; } // Make an array to count the number of leaf connections we have for each network DWORD nConnected[ PROTOCOL_LAST ] = {}; // Count the number of leaf connections we have, by looping for each neighbour in the list for ( POSITION pos = GetIterator() ; pos ; ) { const CNeighbour* pNeighbour = GetNext( pos ); // If we've finished the handshake with this neighbour, and our connection to is down to a leaf if ( pNeighbour->m_nState == nrsConnected && pNeighbour->m_nNodeType == ntLeaf ) nConnected[ pNeighbour->m_nProtocol ]++; // Count it as one more for its network } // Compose the answer for the protocol the caller wants to know about switch ( nProtocol ) { // The caller wants to know if we need more leaves for either Gnutella or Gnutella2 case PROTOCOL_NULL: // If we need more Gnutella or Gnutella2 leaves, return true, only return false if we don't need more leaves from either network return nConnected[PROTOCOL_G1] < Settings.Gnutella1.NumLeafs || nConnected[PROTOCOL_G2] < Settings.Gnutella2.NumLeafs; // Return true if we need more Gnutella ultrapeer connections case PROTOCOL_G1: // Compare our leaf count to NumLeafs from settings, return true if we don't have enough return IsG1UltrapeerCapable() && nConnected[PROTOCOL_G1] < Settings.Gnutella1.NumLeafs; // Gnutella NumLeafs is 0 by default, we always have enough leaves // Return true if we need more Gnutella2 hub connections case PROTOCOL_G2: // Compare our leaf count to NumLeafs from settings, return true if we don't have enough return IsG2HubCapable() && nConnected[PROTOCOL_G2] < Settings.Gnutella2.NumLeafs; // Gnutella2 NumLeafs is 1024 by default } return false; }