/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


#include "cdnsmsgbuf.h"
	
	
CDnsMsgBuf::CDnsMsgBuf(const TDesC8& aBuf):iDataLength(aBuf.Size())
	{	
	}

CDnsMsgBuf* CDnsMsgBuf::NewL(const TDesC8& aBuf)
	{
	CDnsMsgBuf* self =  new (ELeave) CDnsMsgBuf(aBuf);	
	CleanupStack::PushL(self);
	self->ConstructL(aBuf);
	CleanupStack::Pop(self);
	return self;
	}	
		
CDnsMsgBuf::~CDnsMsgBuf()
	{	
	}
		
void CDnsMsgBuf::ConstructL(const TDesC8& aBuf)
	{
	iPtr = (TUint8*)aBuf.Ptr();
	iIndex = 0;
	}
	
void CDnsMsgBuf::SetChar(TUint8 aVal)
	{
	*(iPtr+iIndex) = aVal;
	iIndex += sizeof(TUint8);		
	}
		
void CDnsMsgBuf::SetInt16(TUint16 aVal)
	{
    BigEndian::Put16(iPtr + iIndex, aVal);
    iIndex += sizeof(TUint16);
	}
		
void CDnsMsgBuf::SetInt32(TUint32 aVal)
	{
	BigEndian::Put32(iPtr + iIndex, aVal);
	iIndex += sizeof(TUint32);		
	}

void CDnsMsgBuf::SetDomainNameL(const TDesC8& aName)
	{	
	RBuf8 name;
    if(aName.LocateReverse('.')== aName.Length()-1)
        {
        name.Create(aName.Left(aName.Length()-1));
        }
    else 
        {
        name.Create(aName);
        }
	CStringParser* strParser =  CStringParser::NewL (name);
	CleanupStack::PushL ( strParser );
	TPtrC8 token;
	TChar ch = '.';
	TUint8 len = 0;
	while(1)
		{
		TBool result = strParser->ParseTill(token,ch);
		len = token.Size();
		SetChar(len);
		for(TInt i = 0; i< len; i++)
			{
			SetChar(token.Ptr()[i]);
			}
		strParser->SkipLength(1);
		if(!result)
			break;
		}
	
	// append a zero at the end
	SetChar(NULL);
	CleanupStack::PopAndDestroy ( strParser );
	name.Close();
	}

void CDnsMsgBuf::SetText(const TDesC8& aTxt)
	{
	TUint8 len = 0;
    len = aTxt.Size();
	SetChar(len);
	for(TInt i=0; i<len; i++)
		{
		SetChar(aTxt.Ptr()[i]);
		}
	}
	
void CDnsMsgBuf::SetPtrRdLengthL(const TDesC8& aName)
	{
	TUint16 len = GetDomainLengthL(aName);
	SetInt16(len);
	}
    
void CDnsMsgBuf::SetSrvRdLengthL(const TDesC8& aName)
	{
	TUint16 len = GetDomainLengthL(aName);
	len += 6;  //sizeof(prio+weight+port)
	SetInt16(len);
	}		

void CDnsMsgBuf::SetTxtRdLength(const RArray<RBuf8>& aTxtList)
	{
	TUint16 len = 0;	
	TInt count = aTxtList.Count();
	for (TInt i=0; i< count; i++)
		{
		len++;
		len += aTxtList[i].Size();  
		}
	SetInt16(len);
	}
 
TUint16 CDnsMsgBuf::GetDomainLengthL(const TDesC8& aName)const
	{
    RBuf8 name;
    if(aName.LocateReverse('.')== aName.Length()-1)
        {
        name.Create(aName.Left(aName.Length()-1));
        }
    else 
        {
        name.Create(aName);
        }
	
	CStringParser* strParser =  CStringParser::NewL (name);
	CleanupStack::PushL ( strParser );
	TPtrC8 token;
	TChar ch = '.';
	TUint16 len = 0;	
	while(1)
		{
		TBool result = strParser->ParseTill(token,ch);
		len++;
		len += token.Size();  
		strParser->SkipLength(1);
		if(!result)
			break;
		}		
	len++;   //0 length octet appended at the end
	CleanupStack::PopAndDestroy ( strParser );
	name.Close();
	return len;
	}		
	
