/**
 * @file CapturedData.cpp
 * @author Tomas Urban
 * @version 0.1
 * @date 16/07/2009
 */
#include "CapturedData.h"
#include <sstream>
#include <iomanip>
#include <ctime>

CapturedData::CapturedData(void) :
	m_nCapturedLen(0),
	m_pCapturedData(0),
	m_captureType(ECaptureType_PCAP)
{
	m_timestamp.tv_sec = 0;
	m_timestamp.tv_usec = 0;
}

CapturedData::~CapturedData(void)
{
	delete m_pCapturedData;
}

void CapturedData::SetData (int nLen, const char * pData)
{
	DisposeEncodedData();
	delete m_pCapturedData;
	if (nLen > 0)
	{
		m_nCapturedLen = nLen;
		m_pCapturedData = new char[nLen];
		memcpy(m_pCapturedData, pData, nLen);
	}
	else
	{
		m_nCapturedLen = 0;
		m_pCapturedData = NULL;
	}
}

void CapturedData::SetTimestamp(timeval timestamp) 
{
	DisposeEncodedData();
	m_timestamp = timestamp;
}
void CapturedData::SetCaptureType(ECaptureType captureType)
{ 
	DisposeEncodedData();
	m_captureType = captureType; 
}

unsigned int CapturedData::CalculateDataLength()
{
	return TrafficCaptureMessage::CalculateDataLength() +
		1 + // capture type
		TIME_SIZE + // timestamp
		sizeof(m_nCapturedLen) + m_nCapturedLen; // captured packet
}

void CapturedData::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	EncodeUChar(static_cast<unsigned char>(m_captureType), nOffset);
	EncodeTime(m_timestamp, nOffset);
	EncodeUInt(m_nCapturedLen, nOffset);
	EncodeData(m_pCapturedData, m_nCapturedLen, nOffset);
}

bool CapturedData::DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset)
{
	delete m_pCapturedData;
	m_pCapturedData = NULL;
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	unsigned char c;
	if (!DecodeUChar(c, pPayload, nPayloadLength, nOffset))
		return false;
	m_captureType = static_cast<ECaptureType>(c);
	if (!DecodeTime(m_timestamp, pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeUInt(m_nCapturedLen, pPayload, nPayloadLength, nOffset))
	{
		m_nCapturedLen = 0;
		return false;
	}
	if (m_nCapturedLen)
	{
		m_pCapturedData = new char [m_nCapturedLen];
		if (!DecodeData(m_pCapturedData, m_nCapturedLen, pPayload, nPayloadLength, nOffset))
			return false;
	}
	return true;
}
std::string CapturedData::ToString()
{
	std::stringstream ss;
	ss << "Data captured\n";
	time_t t = m_timestamp.tv_sec;
	struct tm * ts;
    char szBuf[80];
	ts = localtime(&t);
	strftime(szBuf, sizeof(szBuf), "%Y-%m-%d %H:%M:%S", ts);
	ss << "Timestamp: " << szBuf << "." << m_timestamp.tv_usec << "\n";
	ss << "Length: " << m_nCapturedLen << "\n";
	for (unsigned int i = 0; i < m_nCapturedLen; i++)
	{
		if (i > 0)			
			ss << (i % 16 == 0 ? "\n" : " ");
		ss << std::hex << std::setfill('0') << std::setw(2) << 
			(short)(unsigned char)m_pCapturedData[i];        
	}
	ss << "\n\n";
	return ss.str();
}

