///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoTableObject.cc 
// ------------------
// Cego table object class implementation
//     
// Design and Implementation by Bjoern Lemke               
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoTableObject
// 
// Description: Cego table object structure
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// cego includes
#include "CegoTableObject.h"
#include "CegoTypeConverter.h"

// needed for memcpy
#include <string.h>
#include <stdlib.h>

CegoTableObject::CegoTableObject()
{
    _subCOList.Insert(this);
}

CegoTableObject::CegoTableObject(const CegoTableObject& oe) : CegoContentObject(oe)
{
    _pageId = oe._pageId;
    _lastPageId = oe._lastPageId;
    _pLastPageId = oe._pLastPageId;
    _maxFid = oe._maxFid;
    _subCOList.Insert(this);
}

CegoTableObject::CegoTableObject(unsigned tabSetId, CegoObject::ObjectType type, const Chain& objName ) : CegoContentObject(tabSetId, type, objName)
{
    _pageId = 0;
    _lastPageId = 0;
    _pLastPageId=0;
    _maxFid = 0;
    _subCOList.Insert(this);
}

CegoTableObject::CegoTableObject(unsigned tabSetId, CegoObject::ObjectType type,  const Chain& objName, const ListT<CegoField>& schema, const Chain& tabName) : CegoContentObject(tabSetId, type, objName, tabName, schema)
{
    _pageId = 0;    
    _lastPageId = 0;
    _pLastPageId=0;
    _maxFid = 0;
    _subCOList.Insert(this);
}

CegoTableObject::~CegoTableObject()
{   
}

void CegoTableObject::setSchema(const ListT<CegoField>& schema)
{
    _schema = schema;
}

void CegoTableObject::setDataPageId(PageIdType pageId)
{
    _pageId = pageId;
}

PageIdType CegoTableObject::getDataPageId() const
{
    return _pageId;
}

void CegoTableObject::setLastDataPageId(PageIdType pageId)
{
    _lastPageId = pageId;
}

PageIdType CegoTableObject::getLastDataPageId() const
{
    return _lastPageId;
}

void CegoTableObject::setRefLastDataPageId(PageIdType pageId)
{
    _lastPageId = pageId;
    if (_pLastPageId)
    {
	memcpy(_pLastPageId, &pageId, sizeof(PageIdType));
    }
}

PageIdType CegoTableObject::getRefLastDataPageId() const
{
    if (_pLastPageId)
    {
	PageIdType pageId;
	memcpy(&pageId, _pLastPageId, sizeof(PageIdType));
	return pageId;
    }
    else
    {
	return _lastPageId;
    }
}

void CegoTableObject::setMaxFid(unsigned maxFid)
{
    _maxFid = maxFid;
}

unsigned CegoTableObject::getMaxFid() const
{
    return _maxFid;
}

unsigned CegoTableObject::getEntrySize() const
{    
    unsigned entrySize = CegoContentObject::getBaseContentSize();
    entrySize = entrySize + sizeof(PageIdType); // pageId       
    entrySize = entrySize + sizeof(PageIdType); // last pageId
    entrySize = entrySize + sizeof(unsigned); // maxFid    
    return entrySize;
}

void CegoTableObject::encode(char *buf) const
{
    char* bufPtr = buf;

    unsigned entrySize = getEntrySize();

    CegoContentObject::encodeBaseContent(bufPtr, entrySize);
    bufPtr += CegoContentObject::getBaseContentSize();

    memcpy(bufPtr, &_pageId, sizeof(PageIdType));
    bufPtr = bufPtr + sizeof(PageIdType);

    memcpy(bufPtr, &_lastPageId, sizeof(PageIdType));
    bufPtr = bufPtr + sizeof(PageIdType);

    memcpy(bufPtr, &_maxFid, sizeof(unsigned));
    bufPtr = bufPtr + sizeof(unsigned);
}

void CegoTableObject::decode(char *buf)
{
    char* bufPtr = buf;

    unsigned size;

    CegoContentObject::decodeBaseContent(bufPtr, size);
    bufPtr += CegoContentObject::getBaseContentSize();
    
    memcpy(&_pageId, bufPtr, sizeof(PageIdType));
    bufPtr = bufPtr + sizeof(PageIdType);

    _pLastPageId = (char*)bufPtr;
    memcpy(&_lastPageId, bufPtr, sizeof(PageIdType));
    bufPtr = bufPtr + sizeof(PageIdType);

    memcpy(&_maxFid, bufPtr, sizeof(unsigned));
    bufPtr = bufPtr + sizeof(unsigned);
}

bool CegoTableObject::isValid()
{
    return _pageId != 0;
}

CegoTableObject& CegoTableObject::operator = ( const CegoTableObject& oe) 
{
    CegoContentObject::operator=(oe);

    _pageId = oe._pageId;
    _lastPageId = oe._pageId;
    _pLastPageId = oe._pLastPageId;    
    _maxFid = oe._maxFid;

    return (*this);
}

bool CegoTableObject::operator == ( const CegoTableObject& oe)
{
    return CegoContentObject::operator==(oe);
}

Chain CegoTableObject::getId(CegoProcBlock *pBlock) const
{
    return getTabName() + Chain("@") + getTableSet() + Chain("@") + getName();
}

Chain CegoTableObject::toChain(unsigned defTabSetId) const
{
    if ( ( defTabSetId == getTabSetId() && defTabSetId != 0 ) || defTabSetId == 0 )
	return getTabName() + Chain(" ") + getName();
    else
	return getTabName() + Chain("@") + getTableSet() + Chain(" ") + getName();
}

Chain CegoTableObject::getInfo() const
{
    Chain s;
    CegoField *pF = _schema.First();
    while (pF)
    {	
	s += Chain("Attr=") + pF->getAttrName()
	    + Chain(" ") + Chain(CEGO_TYPE_MAP[pF->getType()]) + Chain("[") + Chain(pF->getLength()) + Chain("]\n");
	pF = _schema.Next();	    
    }
    return s;
}

CegoContentObject* CegoTableObject::clone(bool isAttrRef)
{
    CegoTableObject *pClone = new CegoTableObject(*this);
    return (pClone);
}
