137b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===- FileOutputBuffer.cpp -----------------------------------------------===//
287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//                     The MCLinker Project
487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// This file is distributed under the University of Illinois Open Source
687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// License. See LICENSE.TXT for details.
787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h"
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h"
1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1587f34658dec9097d987d254a990ea7f311bfc95fStephen HinesFileOutputBuffer::FileOutputBuffer(llvm::sys::fs::mapped_file_region* pRegion,
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                   FileHandle& pFileHandle)
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_pRegion(pRegion), m_FileHandle(pFileHandle) {
1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2037b74a387bb3993387029859c2d9d051c41c724eStephen HinesFileOutputBuffer::~FileOutputBuffer() {
2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Unmap buffer, letting OS flush dirty pages to file on disk.
22a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  m_pRegion.reset();
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
25a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesstd::error_code
26a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen HinesFileOutputBuffer::create(FileHandle& pFileHandle,
27a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines                         size_t pSize,
28a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines                         std::unique_ptr<FileOutputBuffer>& pResult) {
290dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  std::error_code ec;
30a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines
31a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  // Resize the file before mapping the file region.
32a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  ec = llvm::sys::fs::resize_file(pFileHandle.handler(), pSize);
33a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (ec)
34a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines    return ec;
35a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  std::unique_ptr<llvm::sys::fs::mapped_file_region> mapped_file(
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      new llvm::sys::fs::mapped_file_region(pFileHandle.handler(),
38a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines          llvm::sys::fs::mapped_file_region::readwrite, pSize, 0, ec));
390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (ec)
400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    return ec;
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pResult.reset(new FileOutputBuffer(mapped_file.get(), pFileHandle));
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pResult)
440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    mapped_file.release();
45a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines
460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return std::error_code();
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4937b74a387bb3993387029859c2d9d051c41c724eStephen HinesMemoryRegion FileOutputBuffer::request(size_t pOffset, size_t pLength) {
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pOffset > getBufferSize() || (pOffset + pLength) > getBufferSize())
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return MemoryRegion();
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return MemoryRegion(getBufferStart() + pOffset, pLength);
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef FileOutputBuffer::getPath() const {
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return m_FileHandle.path().native();
5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
60