Esempio n. 1
0
int RichTxt::GetVertMove(int pos, int gx, RichContext rc, int dir) const
{
	ASSERT(dir == -1 || dir == 1);
	if(GetPartCount() == 0)
		return -1;
	int pi;
	int p = pos;
	if(pos >= 0) {
		pi = FindPart(p);
		pos -= p;
	}
	else {
		pi = dir > 0 ? 0 : GetPartCount() - 1;
		p = -1;
		pos = 0;
	}
	while(pi < GetPartCount()) {
		int q = IsTable(pi) ? GetTable(pi).GetVertMove(p, gx, rc, dir)
		                    : Get(pi, rc.styles).GetVertMove(p, gx, rc.page, dir);
		if(q >= 0)
			return q + pos;
		if(dir > 0)
			pos += GetPartLength(pi) + 1;
		p = -1;
		pi += dir;
		if(pi < 0)
			break;
		if(dir < 0)
			pos -= GetPartLength(pi) + 1;
	}
	return -1;
}
Esempio n. 2
0
void RichTxt::Normalize()
{
	RichPara pa;
	if(GetPartCount() && IsTable(0)) {
		part.Insert(0);
		Put(0, pa, RichStyle::GetDefault());
		Invalidate();
	}
	if(GetPartCount() == 0 || IsTable(GetPartCount() - 1)) {
		Put(GetPartCount(), pa, RichStyle::GetDefault());
		Invalidate();
	}
}
Esempio n. 3
0
void RichTxt::RestoreFormat(int pi, const Formating& info, int& ii, const RichStyles& style)
{
	Array<RichObject> dummy;
	while(ii < info.format.GetCount() && pi < GetPartCount()) {
		if(IsTable(pi)) {
			RichTable& tab = part[pi].Get<RichTable>();
			for(int i = 0; i < tab.GetRows(); i++)
				for(int j = 0; j < tab.GetColumns(); j++) {
					if(tab(i, j)) {
						if(ii >= info.format.GetCount())
							return;
						tab.InvalidateRefresh(i, j);
						tab[i][j].text.RestoreFormat(0, info, ii, style);
					}
				}
			pi++;
		}
		else {
			RichPara pa = Get(pi, style);
			RichPara pf;
			pf.Unpack(info.format[ii], dummy, GetStyle(style, info.styleid[ii]).format);
			RichPara t;
			t.format = pf.format;
			int si = 0;
			int sp = 0;
			for(int j = 0; j < pf.GetCount(); j++) {
				const RichPara::Part& q = pf[j];
				for(int k = 0; k < q.text.GetLength(); k++) {
					int len = q.text[k] - 32;
					t.part.Add().format = q.format;
					while(len) {
						const RichPara::Part& p = pa[si];
						if(p.IsText()) {
							int l = min(len, p.GetLength() - sp);
							t.part.Top().text.Cat(p.text.Mid(sp, l));
							sp += l;
							len -= l;
							ASSERT(sp <= p.GetLength());
							if(sp >= p.GetLength()) {
								sp = 0;
								si++;
							}
						}
						else {
							ASSERT(sp == 0);
							(t.part.Add() = pa[si++]).format = q.format;
							len--;
							sp = 0;
						}
					}
				}
			}
			ASSERT(si == pa.GetCount() && sp == 0);
			Put(pi, t, style);
			ii++;
			pi++;
		}
	}
}
Esempio n. 4
0
void RichTxt::ApplyZoom(Zoom z, const RichStyles& ostyle, const RichStyles& zstyle)
{
	for(int i = 0; i < GetPartCount(); i++)
		if(IsTable(i))
			part[i].Get<RichTable>().ApplyZoom(z, ostyle, zstyle);
		else {
			RichPara p = Get(i, ostyle);
			p.ApplyZoom(z);
			Set(i, p, zstyle);
		}
}
Esempio n. 5
0
bool CFileHashSet::SetHashSet(const QList<QByteArray>& HashSet)
{
	ASSERT(!CanHashParts());
	if(HashSet.size() != GetPartCount() || HashSet.isEmpty() || HashSet.at(0).size() != m_uSize)
	{
		ASSERT(0);
		return false;
	}

	m_HashSet.reserve(HashSet.size());
	foreach(const QByteArray& Hash, HashSet)
	{
		byte* pHash = (byte*)hash_malloc(m_uSize);
		memcpy(pHash,Hash.data(),m_uSize);

		QWriteLocker Locker(&m_SetMutex);
		m_HashSet.append(pHash);
	}
Esempio n. 6
0
WString RichTxt::GetPlainText() const {
	WString clip;
	for(int pi = 0; pi < GetPartCount(); pi++) {
		if(pi) {
			clip.Cat('\r');
			clip.Cat('\n');
		}
		if(IsTable(pi)) {
			const RichTable& tab = part[pi].Get<RichTable>();
			for(int i = 0; i < tab.GetRows(); i++)
				for(int j = 0; j < tab.GetColumns(); j++)
					if(tab(i, j)) {
						if(i || j) {
							clip.Cat('\r');
							clip.Cat('\n');
						}
						clip << tab[i][j].text.GetPlainText();
					}
		}
		else
			clip.Cat(Get(pi, RichStyle::GetDefault()).GetText());
	}
	return clip;
}
Esempio n. 7
0
PageY RichTxt::GetHeight(RichContext rc) const
{
	for(int i = 0; i < GetPartCount(); i++)
		rc.py = GetNextPageY(i, rc);
	return rc.py;
}
Esempio n. 8
0
CPacket* CKnownFile::CreateSrcInfoPacket(const CUpDownClient* forClient, uint8 byRequestedVersion, uint16 nRequestedOptions)
{
	// Kad reviewed
	
	if (m_ClientUploadList.empty()) {
		return NULL;	
	}
	
	if ((((CKnownFile*)forClient->GetRequestFile() != this)
		&& ((CKnownFile*)forClient->GetUploadFile() != this)) || forClient->GetUploadFileID() != GetFileHash()) {
		wxString file1 = _("Unknown");
		if (forClient->GetRequestFile() && forClient->GetRequestFile()->GetFileName().IsOk()) {
			file1 = forClient->GetRequestFile()->GetFileName().GetPrintable();
		} else if (forClient->GetUploadFile() && forClient->GetUploadFile()->GetFileName().IsOk()) {
			file1 = forClient->GetUploadFile()->GetFileName().GetPrintable();
		}
		wxString file2 = _("Unknown");
		if (GetFileName().IsOk()) {
			file2 = GetFileName().GetPrintable();
		}
		AddDebugLogLineM(false, logKnownFiles, wxT("File missmatch on source packet (K) Sending: ") + file1 + wxT("  From: ") + file2);
		return NULL;
	}

	const BitVector& rcvstatus = forClient->GetUpPartStatus();
	bool SupportsUploadChunksState = !rcvstatus.empty();
	//wxASSERT(rcvstatus.size() == GetPartCount()); // Obviously!
	if (rcvstatus.size() != GetPartCount()) {
		// Yuck. Same file but different part count? Seriously f****d up.
		AddDebugLogLineM(false, logKnownFiles, CFormat(wxT("Impossible situation: different partcounts for the same known file: %i (client) and %i (file)")) % rcvstatus.size() % GetPartCount());
		return NULL;
	}

	CMemFile data(1024);
	
	uint8 byUsedVersion;
	bool bIsSX2Packet;
	if (forClient->SupportsSourceExchange2() && byRequestedVersion > 0){
		// the client uses SourceExchange2 and requested the highest version he knows
		// and we send the highest version we know, but of course not higher than his request
		byUsedVersion = std::min(byRequestedVersion, (uint8)SOURCEEXCHANGE2_VERSION);
		bIsSX2Packet = true;
		data.WriteUInt8(byUsedVersion);

		// we don't support any special SX2 options yet, reserved for later use
		if (nRequestedOptions != 0) {
			AddDebugLogLineM(false, logKnownFiles, CFormat(wxT("Client requested unknown options for SourceExchange2: %u")) % nRequestedOptions);
		}
	} else {
		byUsedVersion = forClient->GetSourceExchange1Version();
		bIsSX2Packet = false;
		if (forClient->SupportsSourceExchange2()) {
			AddDebugLogLineM(false, logKnownFiles, wxT("Client which announced to support SX2 sent SX1 packet instead"));
		}
	}
	
	uint16 nCount = 0;

	data.WriteHash(forClient->GetUploadFileID());
	data.WriteUInt16(nCount);
	uint32 cDbgNoSrc = 0;

	SourceSet::iterator it = m_ClientUploadList.begin();
	for ( ; it != m_ClientUploadList.end(); it++ ) {
		const CUpDownClient *cur_src = *it;
		
		if (	cur_src->HasLowID() ||
			cur_src == forClient ||
			!(	cur_src->GetUploadState() == US_UPLOADING ||
				cur_src->GetUploadState() == US_ONUPLOADQUEUE)) {
			continue;
		}
		
		bool bNeeded = false;
		
		if ( SupportsUploadChunksState ) {
			const BitVector& srcstatus = cur_src->GetUpPartStatus();
			if ( !srcstatus.empty() ) {
				//wxASSERT(srcstatus.size() == GetPartCount()); // Obviously!
				if (srcstatus.size() != GetPartCount()) {
					continue;
				}
				if ( cur_src->GetUpPartCount() == forClient->GetUpPartCount() ) {
					for (int x = 0; x < GetPartCount(); x++ ) {
						if ( srcstatus.at(x) && !rcvstatus.at(x) ) {
							// We know the receiving client needs
							// a chunk from this client.
							bNeeded = true;
							break;
						}
					}
				}
			} else {
				cDbgNoSrc++;
				// This client doesn't support upload chunk status.
				// So just send it and hope for the best.
				bNeeded = true;
			}
		} else {
			// remote client does not support upload chunk status,
			// search sources which have at least one complete part
			// we could even sort the list of sources by available
			// chunks to return as much sources as possible which
			// have the most available chunks. but this could be
			// a noticeable performance problem.
			const BitVector& srcstatus = cur_src->GetUpPartStatus();
			if ( !srcstatus.empty() ) {
				//wxASSERT(srcstatus.size() == GetPartCount());
				if (srcstatus.size() != GetPartCount()) {
					continue;
				}
				for (int x = 0; x < GetPartCount(); x++ ) {
					if ( srcstatus.at(x) ) {
						// this client has at least one chunk
						bNeeded = true;
						break;
					}
				}
			} else {
				// This client doesn't support upload chunk status.
				// So just send it and hope for the best.
				bNeeded = true;
			}
		}

		if ( bNeeded ) {
			nCount++;
			uint32 dwID;
			if(byUsedVersion >= 3) {
				dwID = cur_src->GetUserIDHybrid();
			} else {
				dwID = cur_src->GetIP();
			}
			data.WriteUInt32(dwID);
			data.WriteUInt16(cur_src->GetUserPort());
			data.WriteUInt32(cur_src->GetServerIP());
			data.WriteUInt16(cur_src->GetServerPort());
			
			if (byUsedVersion >= 2) {
			    data.WriteHash(cur_src->GetUserHash());
			}
			
			if (byUsedVersion >= 4){
				// CryptSettings - SourceExchange V4
				// 5 Reserved (!)
				// 1 CryptLayer Required
				// 1 CryptLayer Requested
				// 1 CryptLayer Supported
				const uint8 uSupportsCryptLayer	= cur_src->SupportsCryptLayer() ? 1 : 0;
				const uint8 uRequestsCryptLayer	= cur_src->RequestsCryptLayer() ? 1 : 0;
				const uint8 uRequiresCryptLayer	= cur_src->RequiresCryptLayer() ? 1 : 0;
				const uint8 byCryptOptions = (uRequiresCryptLayer << 2) | (uRequestsCryptLayer << 1) | (uSupportsCryptLayer << 0);
				data.WriteUInt8(byCryptOptions);
			}			
			
			if (nCount > 500) {
				break;
			}
		}
	}
	
	if (!nCount) {
		return 0;
	}
	
	data.Seek(bIsSX2Packet ? 17 : 16, wxFromStart);
	data.WriteUInt16(nCount);

	CPacket* result = new CPacket(data, OP_EMULEPROT, bIsSX2Packet ? OP_ANSWERSOURCES2 : OP_ANSWERSOURCES);
	
	if ( result->GetPacketSize() > 354 ) {
		result->PackPacket();
	}
	
	return result;
}
Esempio n. 9
0
bool CKnownFile::LoadTagsFromFile(const CFileDataIO* file)
{
	uint32 tagcount = file->ReadUInt32();
	for (uint32 j = 0; j != tagcount; ++j) {
		CTag newtag(*file, true);
		switch(newtag.GetNameID()){
			case FT_FILENAME:
				if (GetFileName().IsOk()) {
					// Unlike eMule, we actually prefer the second
					// filename tag, since we use it to specify the
					// 'universial' filename (see CPath::ToUniv).
					CPath path = CPath::FromUniv(newtag.GetStr());

					// May be invalid, if from older versions where
					// unicoded filenames be saved as empty-strings.
					if (path.IsOk()) {
						SetFileName(path);
					}
				} else {
					SetFileName(CPath(newtag.GetStr()));
				}
				break;
			
			case FT_FILESIZE:
				SetFileSize(newtag.GetInt());
				m_AvailPartFrequency.clear();
				m_AvailPartFrequency.insert(
					m_AvailPartFrequency.begin(),
					GetPartCount(), 0);
				break;
			
			case FT_ATTRANSFERRED:
				statistic.alltimetransferred += newtag.GetInt();
				break;
			
			case FT_ATTRANSFERREDHI:
				statistic.alltimetransferred =
					(((uint64)newtag.GetInt()) << 32) +
					((uint64)statistic.alltimetransferred);
				break;
			
			case FT_ATREQUESTED:
				statistic.alltimerequested = newtag.GetInt();
				break;
			
			case FT_ATACCEPTED:
				statistic.alltimeaccepted = newtag.GetInt();
				break;
			
			case FT_ULPRIORITY:
				m_iUpPriority = newtag.GetInt();
				if( m_iUpPriority == PR_AUTO ){
					m_iUpPriority = PR_HIGH;
					m_bAutoUpPriority = true;
				} else {
					if (	m_iUpPriority != PR_VERYLOW &&
						m_iUpPriority != PR_LOW &&
						m_iUpPriority != PR_NORMAL &&
						m_iUpPriority != PR_HIGH &&
						m_iUpPriority != PR_VERYHIGH &&
						m_iUpPriority != PR_POWERSHARE) {
						m_iUpPriority = PR_NORMAL;
					}
					
					m_bAutoUpPriority = false;
				}
				break;
			
			case FT_PERMISSIONS:
				// Ignore it, it's not used anymore.
				break;
			
			case FT_AICH_HASH: {
				CAICHHash hash;
				bool hashSizeOk =
					hash.DecodeBase32(newtag.GetStr()) == CAICHHash::GetHashSize();
				wxASSERT(hashSizeOk);
				if (hashSizeOk) {
					m_pAICHHashSet->SetMasterHash(hash, AICH_HASHSETCOMPLETE);
				}
				break;
			}
			
			case FT_KADLASTPUBLISHSRC:
				SetLastPublishTimeKadSrc( newtag.GetInt(), 0 );
				
				if(GetLastPublishTimeKadSrc() > (uint32)time(NULL)+KADEMLIAREPUBLISHTIMES) {
					//There may be a posibility of an older client that saved a random number here.. This will check for that..
					SetLastPublishTimeKadSrc(0, 0);
				}
				break;
			
			case FT_KADLASTPUBLISHNOTES:
				SetLastPublishTimeKadNotes( newtag.GetInt() );
				break;
			
			case FT_KADLASTPUBLISHKEY:
				// Just purge it
				wxASSERT( newtag.IsInt() );
				break;
				
			default:
				// Store them here and write them back on saving.
				m_taglist.push_back(newtag);
		}	
	}
	
	return true;
}
Esempio n. 10
0
void CKnownFile::UpdatePartsInfo()
{
	// Cache part count
	uint16 partcount = GetPartCount();
	bool flag = (time(NULL) - m_nCompleteSourcesTime > 0); 

	// Ensure the frequency-list is ready
	if ( m_AvailPartFrequency.size() != GetPartCount() ) {
		m_AvailPartFrequency.clear();
		m_AvailPartFrequency.insert(m_AvailPartFrequency.begin(), GetPartCount(), 0);
	}

	if (flag) {
		ArrayOfUInts16 count;	
		count.reserve(m_ClientUploadList.size());	
		
		SourceSet::iterator it = m_ClientUploadList.begin();
		for ( ; it != m_ClientUploadList.end(); it++ ) {
			if ( !(*it)->GetUpPartStatus().empty() && (*it)->GetUpPartCount() == partcount ) {
				count.push_back((*it)->GetUpCompleteSourcesCount());
			}
		}
	
		m_nCompleteSourcesCount = m_nCompleteSourcesCountLo = m_nCompleteSourcesCountHi = 0;

		if( partcount > 0) {
			m_nCompleteSourcesCount = m_AvailPartFrequency[0];
		}
		for (uint16 i = 1; i < partcount; ++i) {
			if( m_nCompleteSourcesCount > m_AvailPartFrequency[i]) {
				m_nCompleteSourcesCount = m_AvailPartFrequency[i];
			}
		}
		count.push_back(m_nCompleteSourcesCount);

		int32 n = count.size();	
		if (n > 0) {
			std::sort(count.begin(), count.end(), std::less<uint16>());
			
			// calculate range
			int i = n >> 1;			// (n / 2)
			int j = (n * 3) >> 2;	// (n * 3) / 4
			int k = (n * 7) >> 3;	// (n * 7) / 8
			
			// For complete files, trust the people your uploading to more...
			
			// For low guess and normal guess count
			//	- If we see more sources then the guessed low and
			//	normal, use what we see.
			//	- If we see less sources then the guessed low,
			//	adjust network accounts for 100%, we account for
			//	0% with what we see and make sure we are still
			//	above the normal.
			// For high guess
			//	Adjust 100% network and 0% what we see.
			if (n < 20) {
				if ( count[i] < m_nCompleteSourcesCount ) {
					m_nCompleteSourcesCountLo = m_nCompleteSourcesCount;
				} else {
					m_nCompleteSourcesCountLo = count[i];
				}
				m_nCompleteSourcesCount= m_nCompleteSourcesCountLo;
				m_nCompleteSourcesCountHi = count[j];
				if( m_nCompleteSourcesCountHi < m_nCompleteSourcesCount ) {
					m_nCompleteSourcesCountHi = m_nCompleteSourcesCount;
				}
			} else {
			// Many sources..
			// For low guess
			//	Use what we see.
			// For normal guess
			//	Adjust network accounts for 100%, we account for
			//	0% with what we see and make sure we are still above the low.
			// For high guess
			//	Adjust network accounts for 100%, we account for 0%
			//	with what we see and make sure we are still above the normal.

				m_nCompleteSourcesCountLo = m_nCompleteSourcesCount;
				m_nCompleteSourcesCount = count[j];
				if( m_nCompleteSourcesCount < m_nCompleteSourcesCountLo ) {
					m_nCompleteSourcesCount = m_nCompleteSourcesCountLo;
				}
				m_nCompleteSourcesCountHi= count[k];
				if( m_nCompleteSourcesCountHi < m_nCompleteSourcesCount ) {
					m_nCompleteSourcesCountHi = m_nCompleteSourcesCount;
				}
			}
		}
		m_nCompleteSourcesTime = time(NULL) + (60);
	}