/*!
 * \file    OMS_ClassInfo.hpp
 * \author  IvanS, MarkusSi, PeterG
 * \brief   OMS Class Info.
 */
/*

    ========== licence begin  GPL
    Copyright (c) 2002-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



*/

#ifndef __OMS_CLASSINFO_HPP
#define __OMS_CLASSINFO_HPP

#include "Oms/OMS_Defines.h"
#include "gsp00.h"
#include "ggg00.h"

class OMS_ClassDumpInfo {
public:
  OMS_ClassDumpInfo(tsp00_Int4 hashSlot) 
    : m_hashSlot(hashSlot)
  {
  }
  void*                m_addr;
  void*                m_pBaseClass;
  ClassID              m_guid;
  tsp00_C64            m_ClassName;
  tsp00_Int4           m_ObjectSize;
  tsp00_Int4           m_hashSlot;
  void*                m_VTBLPtr;
  bool                 m_isBaseClass;
  bool                 m_isDerivedClass;
  bool                 m_isVarObject;
  bool                 m_filler;
};


class OMS_KeyDesc {        // PTS 1122540
private:
  tsp00_Int4   m_pos; 
  tsp00_Int4   m_len;       
  bool         m_partitioned;

public:
  OMS_KeyDesc (tsp00_Int4 pos, tsp00_Int4 len, bool partitioned)
    : m_pos(pos)
    , m_len(len)
    , m_partitioned(partitioned)
  {}
  bool              IsKeyed()       const { return m_len > 0;     }
  bool              IsPartitioned() const { return m_partitioned; }
  const tsp00_Int4  GetLen()        const { return m_len; }
  const tsp00_Int4  GetPos()        const { return m_pos; }
};


/// Entry (containing class properties) of the global class directory.  
class OMS_ClassInfo {
public:
  OMS_ClassInfo(const char  *ClassName, 
    const ClassIDRef        Guid,
    const OMS_ClassInfo*    pBaseClass,
    tsp00_Int4              keyPos,          // PTS 1122540
    tsp00_Int4              keyLen,          // PTS 1122540
    bool                    keyPartitioned,  // PTS 1122540
    size_t                  ObjSize, 
    void*                   vtptr,
    OMS_ClassInfo*          HashNext);
  void* operator new(size_t sz);
  void           DeleteSelf();
#if defined(OMS_PLACEMENT_DELETE)
  void  operator delete (void* p);
#endif
  void                    Dump(OMS_ClassDumpInfo&);
  bool                    IsBaseClass()   const { return m_isBaseClass; }
  bool                    IsDerivedClass() const { return m_isDerivedClass; }
  bool                    IsDerivedClassOf(const ClassIDRef guid) const 
  {
    const OMS_ClassInfo* pBaseClass = m_pBaseClass; 
    while (NULL != pBaseClass)
    {
      if (pBaseClass->GetGuid() == guid)
      {
        return true;
      }
      else
      {
        pBaseClass = pBaseClass->m_pBaseClass;
      }
    }
    return false;
  }
  bool                    IsVarObject()   const { return m_isVarObject; }
  const ClassIDRef        GetBaseGuid()   const { return m_pBaseClass->GetGuid(); }
  const char*             GetClassName()  const { return REINTERPRET_CAST(const char*, &m_ClassName[0]); }
  const ClassIDRef        GetGuid()       const { return m_guid; }
  const OMS_KeyDesc&      GetKeyDesc()    const { return m_KeyDesc; }       // PTS 1122540
  tsp00_Int4              GetObjectSize() const { return (tsp00_Int4) m_ObjectSize; }
  void*                   GetVTPtr()      const { return m_VTPtr; }
  void                    SetBaseClass()        { m_isBaseClass = true; }

  /*! Pointer to link together entries which belong to the same hash value 
  (see CContainerDictionary::m_classInfoHead) */
  OMS_ClassInfo*         m_HashNext;

private :
  /*!  class Guid */
  ClassID               m_guid;
  /*!  Name of the class */
  tsp00_C64             m_ClassName;
  /*! Description of the key, if one exist. */
  OMS_KeyDesc           m_KeyDesc;      // PTS 1122540
  /*! Size of the object itself + header information + key */
  size_t                m_ObjectSize;
  /*! Pointer to the virtual table (addresses of virtual functions). The objects are stored 
  ** in the kernel without the virtual table (as this is dependend on the current memory 
  ** allocation) and so if an object is copied into the local context, this vtable-pointer 
  ** is added to the object container. This means, that all objects belonging to the same
  ** class share the same vtable. */
  void*                 m_VTPtr;
  /*! If class is derived (see OMS_ClassInfo::m_isBaseClass), then this member points to 
  ** the corresponding entry of the base class  */
  const OMS_ClassInfo* m_pBaseClass;
  /*! Class is a base class? */
  bool                  m_isBaseClass;
  /*! Class is derived from another class? */
  bool                  m_isDerivedClass;
  /*! Object with variable length? */
  bool                  m_isVarObject;
};

typedef OMS_ClassInfo *OMS_ClassInfoPtr;

#endif  // __OMS_CLASSINFO_HPP