//===- FragmentRef.h ------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_FRAGMENT_FRAGMENT_REFERENCE_H
#define MCLD_FRAGMENT_FRAGMENT_REFERENCE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <mcld/Config/Config.h>
#include <mcld/ADT/SizeTraits.h>
#include <mcld/ADT/TypeTraits.h>
#include <mcld/Support/Allocators.h>
namespace mcld {
class Fragment;
class LDSection;
class Layout;
/** \class FragmentRef
* \brief FragmentRef is a reference of a Fragment's contetnt.
*
*/
class FragmentRef
{
public:
typedef uint64_t Offset; // FIXME: use SizeTraits<T>::Offset
typedef NonConstTraits<unsigned char>::pointer Address;
typedef ConstTraits<unsigned char>::pointer ConstAddress;
public:
/// Create - create a fragment reference for a given fragment.
///
/// @param pFrag - the given fragment
/// @param pOffset - the offset, can be larger than the fragment, but can not
/// be larger than the section size.
/// @return if the offset is legal, return the fragment reference. Otherwise,
/// return NULL.
static FragmentRef* Create(Fragment& pFrag, uint64_t pOffset);
static FragmentRef* Create(LDSection& pSection, uint64_t pOffset);
/// Clear - clear all generated FragmentRef in the system.
static void Clear();
static FragmentRef* Null();
// ----- modifiers ----- //
FragmentRef& assign(const FragmentRef& pCopy);
FragmentRef& assign(Fragment& pFrag, Offset pOffset = 0);
/// memcpy - copy memory
/// copy memory from the fragment to the pDesc.
/// @pDest - the destination address
/// @pNBytes - copies pNBytes from the fragment[offset()+pOffset]
/// @pOffset - additional offset.
/// the start address offset from fragment[offset()]
void memcpy(void* pDest, size_t pNBytes, Offset pOffset = 0) const;
// ----- observers ----- //
bool isNull() const { return (this == Null()); }
Fragment* frag()
{ return m_pFragment; }
const Fragment* frag() const
{ return m_pFragment; }
Offset offset() const
{ return m_Offset; }
Offset getOutputOffset() const;
// ----- dereference ----- //
Address deref();
ConstAddress deref() const;
Address operator*()
{ return deref(); }
ConstAddress operator*() const
{ return deref(); }
private:
friend FragmentRef& NullFragmentRef();
friend class Chunk<FragmentRef, MCLD_SECTIONS_PER_INPUT>;
friend class Relocation;
FragmentRef();
FragmentRef(Fragment& pFrag, Offset pOffset = 0);
private:
Fragment* m_pFragment;
Offset m_Offset;
static FragmentRef g_NullFragmentRef;
};
} // namespace of mcld
#endif