/*!
  @file           IOMan_DataVolume.hpp
  @author         TorstenS
  @ingroup        IOManagement
  @brief          This module is used to handle a data volume.
  @see            

\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 IOMAN_DATA_VOLUME_HPP
#define IOMAN_DATA_VOLUME_HPP



/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include "gsp00.h"   // PASCAL: SP_basic_constants_and_types
#include "vsp002.h"  // PASCAL: IO Types

#include "IOManager/IOMan_Volume.hpp"
#include "IOManager/IOMan_KernelPages.hpp"
#include "IOManager/IOMan_BlockAddress.hpp"
#include "IOManager/IOMan_ClusterAddress.hpp"
#include "IOManager/IOMan_Types.hpp"
#include "KernelCommon/Kernel_Common.hpp"
#include "KernelCommon/Kernel_IPage.hpp"


/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/


/*===========================================================================*
 *  MACROS                                                                   *
 *===========================================================================*/


/*===========================================================================*
 *  CLASSES, STRUCTURES, TYPES, UNIONS ...                                   *
 *===========================================================================*/

/* -----------------------------------------------------------------------*/
/*!
  @class    IOMan_DataVolume
  @brief    This class is used to handle data volumes.

 */
/* -----------------------------------------------------------------------*/


class IOMan_DataVolume : public IOMan_Volume
{
public:

    /* -----------------------------------------------------------------------*/
    /*! @name Constructors and initialization */
    /*@{*/
    /* -----------------------------------------------------------------------*/

    /* -----------------------------------------------------------------------*/
    /*!
    @brief  Default Constructor. This method is used to set the member data 
            to an initial state, in particular the type to data. Additional 
            the constructor of the derived IOMan_Volume class is called.
            Note that the logical devo won't be set.
    @return none

    */
    /* -----------------------------------------------------------------------*/

    IOMan_DataVolume():IOMan_Volume( tsp2_dev_type::fromConst( sp2dt_data ))
    {}

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to set the individual logical data volume
                identifier.
       @param   devNo [in] Logical volume identifier
       @param   frame [in] Frame for the IOManInfoPage of the data volume
       @return  none

     */
    /* -----------------------------------------------------------------------*/

    void Initialize(
        const IOMan_DeviceNo            devNo,
        const Kernel_IPage::PageFrame   &frame )
    {
        IOMan_Volume::Initialize( devNo, frame );
    }

    /* -----------------------------------------------------------------------*/
    /*@}*/
    /* -----------------------------------------------------------------------*/

    /* -----------------------------------------------------------------------*/
    /*! @name Administration */
    /*@{*/
    /* -----------------------------------------------------------------------*/

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to bring a data volume from close mode into
                open mode. For more informations see IOMan_Volume::Open().
       @param   taskId [in] Identification of the calling task.
       @return  (IOMan_ReturnCode) IOMan_Okay means open was successful
     */
    /* -----------------------------------------------------------------------*/

    IOMan_ReturnCode Open( const tsp00_TaskId   taskId )
    {
        return( IOMan_Volume::Open( taskId, SAPDB_TRUE, IOMAN_OPEN_FOR_WRITE ));
    }

    /* -----------------------------------------------------------------------*/
    /*@}*/
    /* -----------------------------------------------------------------------*/

    /* -----------------------------------------------------------------------*/
    /*! @name Input/Output */
    /*@{*/
    /* -----------------------------------------------------------------------*/

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to read one page from a volume into the
                given memory. The correctness  of the read page will be checked
                as far as three times if an error has occured. Each error is
                loged in the knldiag file and the io buffer is dumped. In this
                case the method provides a false as return code. In case of fatal
                errors of the IO subsystem an emergency shutdown is executed.
       @param   taskId [in] Identification of the calling task.
       @param   page [in] Handler of the wanted Page.
       @param   block [in] Position of the wanted page within the volume.
       @return  true means page succesful read; else false for bad data page
     */
    /* -----------------------------------------------------------------------*/

    bool ReadPage(
        const tsp00_TaskId       taskId,
        Kernel_IPage             &page,
        const IOMan_BlockAddress &block )
    {
        SAPDBERR_ASSERT_STATE( block.GetDeviceNo() == m_LogicalDevNo );

        return IOMan_Volume::Read( taskId, page, block.GetBlockNo());
    }

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to write one page from given memory into
                a volume. Before the proper io is executed the correctness of  
                the given page will be checked. Each error is loged in the 
                knldiag file and the io buffer is dumped. In any case of error 
                an emergency shutdown is executed.
       @param   taskId [in] Identification of the calling task.
       @param   page [in] Handler of the wanted Page.
       @param   block [in] Position of the wanted page within the volume.
       @return  none
     */
    /* -----------------------------------------------------------------------*/

    void WritePage(
        const tsp00_TaskId       taskId,
        Kernel_IPage             &page,
        const IOMan_BlockAddress &block )
    {
        SAPDBERR_ASSERT_STATE( block.GetDeviceNo() == m_LogicalDevNo );

        IOMan_Volume::Write( taskId, page, block.GetBlockNo());
    }

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to write pages from given memory into
                a volume. Before the proper io is executed the correctness of  
                the given page will be checked. Each error is loged in the 
                knldiag file and the io buffer is dumped. In any case of error 
                an emergency shutdown is executed.
       @param   taskId [in] Identification of the calling task.
       @param   pages [in] Handler of the pages to be written
       @param   cluster [in] Destination address of the pages to be written
       @return  none
     */
    /* -----------------------------------------------------------------------*/

    void WritePages(
        const tsp00_TaskId          taskId,
        IOMan_IKernelPages          &pages,
        const IOMan_ClusterAddress  &cluster )
    {
        SAPDBERR_ASSERT_STATE( cluster.GetDeviceNo() == m_LogicalDevNo );

        IOMan_Volume::WriteVector( taskId, pages, cluster );
    }

    /* -----------------------------------------------------------------------*/
    /*@}*/
    /* -----------------------------------------------------------------------*/

private:

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   The assignment operator is not supported to avoid not allowed
                duplicates.
       @param   volume [in] volume 
       @return  IOMan_DataVolume&
     */
    /* -----------------------------------------------------------------------*/

    IOMan_DataVolume& operator=( const IOMan_DataVolume &volume );

    // copy constructor is needed for newarray operation during initialization
    //IOMan_DataVolume( const IOMan_DataVolume &volume );

};

#endif  /* IOMAN_DATA_VOLUME_HPP */

