/*!
@defgroup       PageHandling Describes persistent layout of pages, frames and their handler
*/
/*!
@file           Kernel_Page.hpp
@author         DataAccess group
@ingroup        PageHandling
\if EMIT_LICENCE
    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end

\endif
*/
#ifndef KERNEL_PAGE_HPP
#define KERNEL_PAGE_HPP

#include "ggg00.h"
#include "SAPDBCommon/SAPDB_PersistentTypes.hpp"
#include "KernelCommon/Kernel_IPage.hpp"

/*!
@class Kernel_Page
@brief Virtual base class for all page handler classes in the kernel.

Defines frame handling and access to some header fields.
*/

class Kernel_Page : public Kernel_IPage
{
public:

    /// Field for multiple usage by derived classes
    typedef SAPDB_UInt4                                     PageId;
    /// Field for multiple usage by derived classes
    typedef SAPDB_UInt1                                     ParityOrPageType2;
    /// Constants for different page categories
    enum PageType
    {
        Kernel_KernelPageType               = ptNil_egg00,      // these are
        Kernel_DataPageType                 = ptData_egg00,     // 7.2 page types
        Kernel_DumpPageType                 = ptDump_egg00,
        Kernel_FBMPageType                  = ptFbm_egg00,
        Kernel_LogPageType                  = ptLog_egg00,
        Kernel_SavePageType                 = ptSave_egg00,
        Kernel_SysPageType                  = ptSys_egg00,
        Kernel_VTracePageType               = ptVtrace_egg00,
        Kernel_ConverterPageType            = ptConverter_egg00,
        Kernel_ConverterBitMapPageType      = ptConverterBitMap_egg00,
        Kernel_LogInfoPageType              = ptLogInfo_egg00,
        Kernel_IOManInfoPageType            = ptIOManInfo_egg00 // change ReadPageTypeName() too
    };
    /// Default constructor
    Kernel_Page():m_Hint( 0 )
    {}
    /*!
    @brief          Constructor; assigns frame
    @param          frame [in] kernel page frame

    Does not change frame contents.
    */
    Kernel_Page( const PageFrame    &frame )
    :
    m_Frame( frame ),
    m_Hint ( 0 )
    {}
    /// Assigns frame; does not change frame contents
    void SetFrame( const PageFrame  &frame )
    {
        m_Frame = frame;
    }
    /// Deassigns page frame
    void ReleaseFrame()
    {
        m_Frame.Deassign();
    }
    /*!
    @brief          Returns reference to actual frame
    @return         (const PageFrame&amp;) reference to frame
    */
    const PageFrame& GetFrame() const
    {
        return m_Frame;
    }
    /*!
    @brief          Returns reference to actual frame
    @return         (PageFrame&amp;) reference to frame
    */
    PageFrame& GetFrame()
    {
        return m_Frame;
    }
    /// Returns the pointer to the proper page frame
    virtual PageFramePtr GetFramePtr()
    {
        return m_Frame.GetDataPtr();
    }
    /// returns true if the page frame is assigned
    SAPDB_Bool IsAssigned() const
    {
        return m_Frame.IsAssigned();
    }
    /// Reads page type from frame
    PageType ReadPageType() const
    {
        return static_cast<PageType>(PersistentHeaderPtr()->m_PageType);
    }
    /// Returns the page type as string
    const SAPDB_Char* ReadPageTypeName() const
    {
        switch( ReadPageType())
        {
        case Kernel_KernelPageType:
            return ( SAPDB_Char* )"nil";
        case Kernel_DataPageType:
            return ( SAPDB_Char* )"data";
        case Kernel_DumpPageType:
            return ( SAPDB_Char* )"dump";
        case Kernel_FBMPageType:
            return ( SAPDB_Char* )"fbm";
        case Kernel_LogPageType:
            return ( SAPDB_Char* )"log";
        case Kernel_SavePageType:
            return ( SAPDB_Char* )"save";
        case Kernel_SysPageType:
            return ( SAPDB_Char* )"sys";
        case Kernel_VTracePageType:
            return ( SAPDB_Char* )"vtrace";
        case Kernel_ConverterPageType:
            return ( SAPDB_Char* )"converter";
        case Kernel_ConverterBitMapPageType:
            return ( SAPDB_Char* )"conv bit map";
        case Kernel_LogInfoPageType:
            return ( SAPDB_Char* )"log info";
        case Kernel_IOManInfoPageType:
            return ( SAPDB_Char* )"ioman info";
        default:
            return ( SAPDB_Char* )"UNDEF";
        }
    }
    /// Writes multi use value to frame
    void WritePageId( PageId  id )
    {
        PersistentHeaderPtr()->m_PageId = id;
    }
    /// Reads pageid from frame
    PageId ReadPageId() const
    {
        return PersistentHeaderPtr()->m_PageId;
    }
    /// Dumps frame contents to destination frame
    void DumpTo( PageFrame  &dest ) const
    {
        dest.Copy(m_Frame);
    }

protected:

    /// Writes page type to frame
    void WritePageType( PageType    type )
    {
        PersistentHeaderPtr()->m_PageType = type;
    }
    /// Writes multi use value to frame
    void WriteParityOrPageType2( ParityOrPageType2 value )
    {
        PersistentHeaderPtr()->m_ParityOrPageType2 = value;
    }
    /// Reads multi use value from frame
    ParityOrPageType2 ReadParityOrPageType2() const
    {
        return PersistentHeaderPtr()->m_ParityOrPageType2;
    }
    /// Sets pointer to associated hint
    void SetHint( void*    hint )
    {
        m_Hint = hint;
    }
    /// Returns pointer to associated hint
    void* GetHint() const
    {
        return m_Hint;
    }

protected:

    /// handle to frame which contains actual page
    PageFrame m_Frame;

    /// Hint pointer to additional data (for i/o purposes)
    void *m_Hint;

#if defined(AIX) || defined(HPUX) || defined(SUN)
public:
#else
protected:
#endif

    /// Persistent layout of data within kernel page header
    struct PersistentHeader // 8 bytes
    {
        SAPDB_UInt4     m_PageId;            // logical identifier if page
        SAPDB_Byte      m_PageType;
        SAPDB_UInt1     m_ParityOrPageType2; // 7.4: parity algorithm; 7.3: page type 2
        SAPDB_UInt2     m_Filler;
    };

    /// Compile time size check for header
    typedef SAPDB_Persistent<PersistentHeader,PersistentHeader,
    sizeof(SAPDB_UInt4) +
    sizeof(SAPDB_Byte)  +
    sizeof(SAPDB_UInt1) +
    sizeof(SAPDB_UInt2)> CheckedPersistentHeader;
    /// Returns pointer to page header on frame
    PersistentHeader* PersistentHeaderPtr()
    {
        return reinterpret_cast<PersistentHeader*>(m_Frame.GetDataPtr());
    }

    /// Returns const pointer to page header on frame
    const PersistentHeader * const PersistentHeaderPtr() const
    {
        return reinterpret_cast< const PersistentHeader * const>(m_Frame.GetDataPtr());
    }

    /// Returns size of page header
    SizeType GetHeaderSize() const
    {
        return sizeof(PersistentHeader);
    }
};
#endif // KERNEL_PAGE_HPP
