void CXTPDatePickerItemMonth::ByFontAdjustLayout(CRect rcClient)
{
	CWindowDC dc(CWnd::GetDesktopWindow());
	CSize szDay(m_pControl->m_pPaintManager->CalcDayRect(&dc));
	CSize szHeader(m_pControl->m_pPaintManager->CalcMonthHeaderRect(&dc));
	CSize szWeekText(m_pControl->m_pPaintManager->CalcDayOfWeekRect(&dc));
	CSize szWeekNumber(m_pControl->m_pPaintManager->CalcWeekNumbersRect(&dc));

	m_rcMonth = rcClient;
	// calc header rect
	m_rcHeader = m_rcMonth;
	m_rcHeader.bottom = m_rcHeader.top + szHeader.cy;
	//m_rcHeader.right = m_rcHeader.left + szHeader.cx;

	// calc days of week rect
	m_rcDaysOfWeek = m_rcMonth;
	m_rcDaysOfWeek.top = m_rcHeader.bottom;
	//m_rcDaysOfWeek.bottom = m_rcDaysOfWeek.top + 18; // TODO: change to font height
	m_rcDaysOfWeek.bottom = m_rcDaysOfWeek.top + szWeekText.cy;

	// draw week numbers
	m_rcWeekNumbers = m_rcMonth;
	m_rcWeekNumbers.top = m_rcDaysOfWeek.bottom;
	//m_rcWeekNumbers.right = m_rcWeekNumbers.left + 18; // TODO: change to font width
	m_rcWeekNumbers.right = m_rcWeekNumbers.left + szWeekNumber.cx;

	// calc triangles rect
	m_rcLeftScroll = m_rcHeader;
	m_rcRightScroll = m_rcHeader;
	m_rcLeftScroll.right = m_rcHeader.left+ szWeekNumber.cx + 3;
	m_rcRightScroll.left = m_rcHeader.right - szWeekNumber.cx - 3;

	// calc days display params
	m_rcDaysArea = m_rcMonth;
	m_rcDaysArea.top = m_rcDaysOfWeek.bottom;
	m_rcDaysArea.left = m_rcWeekNumbers.right;
	m_rcDaysArea.right -= m_rcWeekNumbers.Width();

	CRect rcDay;
	int nIndex = 0;
	for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
	{
		for (int nDay = 0; nDay < XTP_WEEK_DAYS; nDay++)
		{
			CXTPDatePickerItemDay* pDay = GetDay(nIndex);
			nIndex++;

			rcDay.left = m_rcDaysArea.left + nDay * szDay.cx + 1;
			rcDay.top = m_rcDaysArea.top + nWeek * szDay.cy;
			rcDay.right = rcDay.left + szDay.cx ;
			rcDay.bottom = rcDay.top + szDay.cy;
			pDay->SetRect(rcDay);
		}
	}

}
Ejemplo n.º 2
0
void KviHttpRequest::processData(KviDataBuffer * data)
{
//	unsigned char obuffer[BUFFER_SIZE];
	if(m_bChunkedTransferEncoding && m_bIgnoreRemainingData)
	{
		// In chunked transfer encoding mode there may be additional headers
		// after the last chunk of data. We simply ignore them.
		return;
	}

	if(!m_bHeaderProcessed)
	{
		// time to process the header
		m_p->pBuffer->append(*data);

		int idx = m_p->pBuffer->find((const unsigned char *)"\r\n\r\n",4);
		if(idx == -1)
		{
			// header not complete
			if(m_p->pBuffer->size() > 4096)
			{
				resetInternalStatus();
				m_szLastError = __tr2qs("Header too long: exceeded 4096 bytes");
				emit terminated(false);
			}
			return;
		}
		KviCString szHeader((const char *)(m_p->pBuffer->data()),idx);
		m_p->pBuffer->remove(idx + 4);

		if(!processHeader(szHeader))
			return;

		m_bHeaderProcessed = true;

		if(m_eProcessingType == StoreToFile)
		{
			if(!openFile())return;
		}

		m_uReceivedSize = m_p->pBuffer->size();


		// here the header is complete and the eventual remaining data is in m_p->pBuffer. data has been already used.

	} else {
		// header already processed
		m_uReceivedSize += data->size();

		// here the header is complete and some data *might* be already in m_p->pBuffer. data is unused yet.

		// Optimisation: If the transfer is NOT chunked (so we don't have to parse it)
		// and the requested processing type is either Blocks or StoreToFile
		// then we just can avoid to copy the data to m_p->pBuffer.
		// This is a good optimisation since for large files we can save allocating
		// space for and moving megabytes of data...


		if((!m_bChunkedTransferEncoding) && ((m_eProcessingType == Blocks) || (m_eProcessingType == StoreToFile)))
		{
			switch(m_eProcessingType)
			{
				case Blocks:
					emit binaryData(*data);
				break;
				case StoreToFile:
					m_p->pFile->write((const char *)(data->data()),data->size());
				break;
				default:
				break;
			}

			if(((m_uTotalSize > 0) && (m_uReceivedSize > m_uTotalSize)) || ((m_uMaxContentLength > 0) && (m_uReceivedSize > m_uMaxContentLength)))
			{
				resetInternalStatus();
				m_szLastError=__tr2qs("The amount of received data exceeds expected length");
				emit terminated(false);
			}

			return;
		}

		// need to append to m_p->pBuffer and process it
		m_p->pBuffer->append(*data);
	}

	// we're processing data in m_p->pBuffer here
	if(m_bChunkedTransferEncoding)
	{
		// The transfer encoding is chunked: the buffer contains
		// chunks of data with an initial header composed
		// of a hexadecimal length, an optional bullshit and a single CRLF
		// The transfer terminates when we read a last chunk of size 0
		// that may be followed by optional headers...
		// This sux :)
		while(m_p->pBuffer->size() > 0) // <-- note that we may exit from this loop also for other conditions (there is a goto below)
		{
			// we process chunks of parts of chunks at a time.
			if(m_uRemainingChunkSize > 0)
			{
				// process the current chunk data
				unsigned int uProcessSize = m_uRemainingChunkSize;
				if(uProcessSize > (unsigned int)m_p->pBuffer->size())uProcessSize = m_p->pBuffer->size();
				m_uRemainingChunkSize -= uProcessSize;

				switch(m_eProcessingType)
				{
					case Blocks:
						if((unsigned int)m_p->pBuffer->size() == uProcessSize)
						{
							// avoid copying to a new buffer
							emit binaryData(*m_p->pBuffer);
						} else {
							// must copy
							KviDataBuffer tmp(uProcessSize,m_p->pBuffer->data());
							emit binaryData(tmp);
							m_p->pBuffer->remove(uProcessSize);
						}
					break;
					case Lines:
						if((unsigned int)m_p->pBuffer->size() == uProcessSize)
						{
							// avoid copying to a new buffer
							emitLines(m_p->pBuffer);
						} else {
							// must copy
							KviDataBuffer tmp(uProcessSize,m_p->pBuffer->data());
							emitLines(&tmp);
							m_p->pBuffer->remove(uProcessSize);
						}
					break;
					case StoreToFile:
						m_p->pFile->write((const char *)(m_p->pBuffer->data()),uProcessSize);
						m_p->pBuffer->remove(uProcessSize);
					break;
					default:
						// nothing.. just make gcc happy
					break;
				}
				// now either the buffer is empty or there is another chunk header: continue looping
			} else {
				// We're looking for the beginning of a chunk now.
				// Note that we might be at the end of a previous chunk that has a CRLF terminator
				// we need to skip it.
				int crlf = m_p->pBuffer->find((const unsigned char *)"\r\n",2);
				if(crlf != -1)
				{
					if(crlf == 0)
					{
						// This is a plain CRLF at the beginning of the buffer BEFORE a chunk header.
						// It comes from the previous chunk terminator. Skip it.
						m_p->pBuffer->remove(2);
					} else {
						// got a chunk header
						KviCString szHeader((const char *)(m_p->pBuffer->data()),crlf);
						szHeader.cutFromFirst(' ');
						// now szHeader should contain a hexadecimal chunk length... (why the hell it is hex and not decimal ????)
						QString szHexHeader = szHeader.ptr();
						bool bOk;
						m_uRemainingChunkSize = szHexHeader.toLong(&bOk,16);
						if(!bOk)
						{
							resetInternalStatus();
							m_szLastError = __tr2qs("Protocol error: invalid chunk size");
							emit terminated(false);
							return;
						}
						m_p->pBuffer->remove(crlf+2);
						if(m_uRemainingChunkSize == 0)
						{
							// this is the last chunk of data. It may be followed by optional headers
							// but we actually don't need them (since we're surely not in HEAD mode)
							m_bIgnoreRemainingData = true;
							m_p->pBuffer->clear();
							goto check_stream_length;
						}
					}
					// the rest is valid data of a non-zero chunk: continue looping
				} else {
					// chunk header not complete
					if(m_p->pBuffer->size() > 4096)
					{
						resetInternalStatus();
						m_szLastError = __tr2qs("Chunk header too long: exceeded 4096 bytes");
						emit terminated(false);
						return;
					}
					goto check_stream_length;
				}
			}
		}
	} else {
		// the transfer encoding is not chunked: m_p->pBuffer contains only valid data
		switch(m_eProcessingType)
		{
			case Blocks:
				if(m_p->pBuffer->size() > 0)emit binaryData(*m_p->pBuffer);
				m_p->pBuffer->clear();
			break;
			case Lines:
				if(m_p->pBuffer->size() > 0)emitLines(m_p->pBuffer);
			break;
			case StoreToFile:
				m_p->pFile->write((const char *)(m_p->pBuffer->data()),m_p->pBuffer->size());
				m_p->pBuffer->clear();
			break;
			default:
				// nothing.. just make gcc happy
			break;
		}
	}

check_stream_length:

	if(((m_uTotalSize > 0) && (m_uReceivedSize > m_uTotalSize)) || ((m_uMaxContentLength > 0) && (m_uReceivedSize > m_uMaxContentLength)))
	{
		resetInternalStatus();
		m_szLastError=__tr2qs("The amount of received data exceeds expected length");
		emit terminated(false);
	}
	return;
}