C++程序  |  135行  |  3.68 KB

//===- InputBuilder.h -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_MC_INPUTBUILDER_H_
#define MCLD_MC_INPUTBUILDER_H_

#include "mcld/InputTree.h"
#include "mcld/MC/Input.h"
#include "mcld/Support/FileHandle.h"

#include <stack>
#include <string>

namespace mcld {

class AttrConstraint;
class ContextFactory;
class InputFactory;
class LinkerConfig;
class MemoryAreaFactory;

/** \class InputBuilder
 *  \brief InputBuilder recieves InputActions and build the InputTree.
 *
 *  InputBuilder build input tree and inputs.
 */
class InputBuilder {
 public:
  explicit InputBuilder(const LinkerConfig& pConfig);

  InputBuilder(const LinkerConfig& pConfig,
               InputFactory& pInputFactory,
               ContextFactory& pContextFactory,
               MemoryAreaFactory& pMemoryFactory,
               bool pDelegate = true);

  virtual ~InputBuilder();

  // -----  input tree operations  ----- //
  const InputTree& getCurrentTree() const;
  InputTree& getCurrentTree();

  void setCurrentTree(InputTree& pInputTree);

  // -----  root of input tree  ----- //
  const InputTree::iterator& getCurrentNode() const { return m_Root; }
  InputTree::iterator& getCurrentNode() { return m_Root; }

  template <InputTree::Direction DIRECTION>
  InputTree& createNode(const std::string& pName,
                        const sys::fs::Path& pPath,
                        unsigned int pType = Input::Unknown);

  // -----  input operations  ----- //
  Input* createInput(const std::string& pName,
                     const sys::fs::Path& pPath,
                     unsigned int pType = Input::Unknown,
                     off_t pFileOffset = 0);

  bool setContext(Input& pInput, bool pCheck = true);

  bool setMemory(Input& pInput,
                 FileHandle::OpenMode pMode,
                 FileHandle::Permission pPerm);

  bool setMemory(Input& pInput, void* pMemBuffer, size_t pSize);

  InputTree& enterGroup();

  InputTree& exitGroup();

  bool isInGroup() const;

  const AttrConstraint& getConstraint() const;

  const AttributeProxy& getAttributes() const;
  AttributeProxy& getAttributes();

 private:
  const LinkerConfig& m_Config;

  InputFactory* m_pInputFactory;
  MemoryAreaFactory* m_pMemFactory;
  ContextFactory* m_pContextFactory;

  InputTree* m_pCurrentTree;
  InputTree::Mover* m_pMove;
  InputTree::iterator m_Root;
  std::stack<InputTree::iterator> m_ReturnStack;

  bool m_bOwnFactory;
};

//===----------------------------------------------------------------------===//
// Template implement
//===----------------------------------------------------------------------===//
template <>
inline InputTree& InputBuilder::createNode<InputTree::Inclusive>(
    const std::string& pName,
    const sys::fs::Path& pPath,
    unsigned int pType) {
  assert(m_pCurrentTree != NULL && m_pMove != NULL);

  Input* input = createInput(pName, pPath, pType);
  m_pCurrentTree->insert(m_Root, *m_pMove, *input);
  m_pMove->move(m_Root);
  m_pMove = &InputTree::Downward;

  return *m_pCurrentTree;
}

template <>
inline InputTree& InputBuilder::createNode<InputTree::Positional>(
    const std::string& pName,
    const sys::fs::Path& pPath,
    unsigned int pType) {
  assert(m_pCurrentTree != NULL && m_pMove != NULL);

  Input* input = createInput(pName, pPath, pType);
  m_pCurrentTree->insert(m_Root, *m_pMove, *input);
  m_pMove->move(m_Root);
  m_pMove = &InputTree::Afterward;

  return *m_pCurrentTree;
}

}  // namespace mcld

#endif  // MCLD_MC_INPUTBUILDER_H_