1//===- MemoryAreaFactory.cpp ----------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include <mcld/Support/MemoryAreaFactory.h>
10#include <mcld/Support/MsgHandling.h>
11#include <mcld/Support/SystemUtils.h>
12#include <mcld/Support/Space.h>
13
14using namespace mcld;
15
16//===----------------------------------------------------------------------===//
17// MemoryAreaFactory
18//===----------------------------------------------------------------------===//
19MemoryAreaFactory::MemoryAreaFactory(size_t pNum)
20  : GCFactory<MemoryArea, 0>(pNum) {
21}
22
23MemoryAreaFactory::~MemoryAreaFactory()
24{
25  HandleToArea::iterator rec, rEnd = m_HandleToArea.end();
26  for (rec = m_HandleToArea.begin(); rec != rEnd; ++rec) {
27    if (rec->handle->isOpened()) {
28      rec->handle->close();
29    }
30    delete rec->handle;
31  }
32}
33
34MemoryArea*
35MemoryAreaFactory::produce(const sys::fs::Path& pPath,
36                           FileHandle::OpenMode pMode)
37{
38  HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
39  if (NULL == map_result.area) {
40    // can not found
41    FileHandle* handler = new FileHandle();
42    if (!handler->open(pPath, pMode)) {
43      error(diag::err_cannot_open_file) << pPath
44                                        << sys::strerror(handler->error());
45    }
46
47    MemoryArea* result = allocate();
48    new (result) MemoryArea(*handler);
49
50    m_HandleToArea.push_back(handler, result);
51    return result;
52  }
53
54  return map_result.area;
55}
56
57MemoryArea*
58MemoryAreaFactory::produce(const sys::fs::Path& pPath,
59                           FileHandle::OpenMode pMode,
60                           FileHandle::Permission pPerm)
61{
62  HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
63  if (NULL == map_result.area) {
64    // can not found
65    FileHandle* handler = new FileHandle();
66    if (!handler->open(pPath, pMode, pPerm)) {
67      error(diag::err_cannot_open_file) << pPath
68                                        << sys::strerror(handler->error());
69    }
70
71    MemoryArea* result = allocate();
72    new (result) MemoryArea(*handler);
73
74    m_HandleToArea.push_back(handler, result);
75    return result;
76  }
77
78  return map_result.area;
79}
80
81MemoryArea* MemoryAreaFactory::produce(void* pMemBuffer, size_t pSize)
82{
83  Space* space = Space::Create(pMemBuffer, pSize);
84  MemoryArea* result = allocate();
85  new (result) MemoryArea(*space);
86  return result;
87}
88
89MemoryArea*
90MemoryAreaFactory::produce(int pFD, FileHandle::OpenMode pMode)
91{
92  FileHandle* handler = new FileHandle();
93  handler->delegate(pFD, pMode);
94
95  MemoryArea* result = allocate();
96  new (result) MemoryArea(*handler);
97
98  return result;
99}
100
101void MemoryAreaFactory::destruct(MemoryArea* pArea)
102{
103  m_HandleToArea.erase(pArea);
104  pArea->clear();
105  pArea->handler()->close();
106  destroy(pArea);
107  deallocate(pArea);
108}
109
110