reduce indentation
[oota-llvm.git] / lib / Support / MemoryBuffer.cpp
index 345a78c190c05ae102072dd716aec93ba26c210f..2b95089b5246f4620fb63fb354adf47fdfef6578 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/System/Errno.h"
 #include "llvm/System/Path.h"
 #include "llvm/System/Process.h"
 #include "llvm/System/Program.h"
@@ -70,13 +71,12 @@ namespace {
 class MemoryBufferMem : public MemoryBuffer {
   std::string FileID;
 public:
-  MemoryBufferMem(const char *Start, const char *End, StringRef FID,
-                  bool Copy = false)
+  MemoryBufferMem(StringRef InputData, StringRef FID, bool Copy = false)
   : FileID(FID) {
     if (!Copy)
-      init(Start, End);
+      init(InputData.data(), InputData.data()+InputData.size());
     else
-      initCopyOf(Start, End);
+      initCopyOf(InputData.data(), InputData.data()+InputData.size());
   }
   
   virtual const char *getBufferIdentifier() const {
@@ -87,19 +87,17 @@ public:
 
 /// getMemBuffer - Open the specified memory range as a MemoryBuffer.  Note
 /// that EndPtr[0] must be a null byte and be accessible!
-MemoryBuffer *MemoryBuffer::getMemBuffer(const char *StartPtr, 
-                                         const char *EndPtr,
+MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
                                          const char *BufferName) {
-  return new MemoryBufferMem(StartPtr, EndPtr, BufferName);
+  return new MemoryBufferMem(InputData, BufferName);
 }
 
 /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
 /// copying the contents and taking ownership of it.  This has no requirements
 /// on EndPtr[0].
-MemoryBuffer *MemoryBuffer::getMemBufferCopy(const char *StartPtr, 
-                                             const char *EndPtr,
+MemoryBuffer *MemoryBuffer::getMemBufferCopy(StringRef InputData,
                                              const char *BufferName) {
-  return new MemoryBufferMem(StartPtr, EndPtr, BufferName, true);
+  return new MemoryBufferMem(InputData, BufferName, true);
 }
 
 /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
@@ -111,7 +109,7 @@ MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size,
   char *Buf = (char *)malloc(Size+1);
   if (!Buf) return 0;
   Buf[Size] = 0;
-  MemoryBufferMem *SB = new MemoryBufferMem(Buf, Buf+Size, BufferName);
+  MemoryBufferMem *SB = new MemoryBufferMem(StringRef(Buf, Size), BufferName);
   // The memory for this buffer is owned by the MemoryBuffer.
   SB->MustDeleteBuffer = true;
   return SB;
@@ -167,6 +165,14 @@ public:
     sys::Path::UnMapFilePages(getBufferStart(), getBufferSize());
   }
 };
+
+/// FileCloser - RAII object to make sure an FD gets closed properly.
+class FileCloser {
+  int FD;
+public:
+  FileCloser(int FD) : FD(FD) {}
+  ~FileCloser() { ::close(FD); }
+};
 }
 
 MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
@@ -178,9 +184,10 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
   SmallString<256> PathBuf(Filename.begin(), Filename.end());
   int FD = ::open(PathBuf.c_str(), O_RDONLY|OpenFlags);
   if (FD == -1) {
-    if (ErrStr) *ErrStr = strerror(errno);
+    if (ErrStr) *ErrStr = sys::StrError();
     return 0;
   }
+  FileCloser FC(FD); // Close FD on return.
   
   // If we don't know the file size, use fstat to find out.  fstat on an open
   // file descriptor is cheaper than stat on a random path.
@@ -190,8 +197,7 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
     
     // TODO: This should use fstat64 when available.
     if (fstat(FD, FileInfoPtr) == -1) {
-      if (ErrStr) *ErrStr = strerror(errno);
-      ::close(FD);
+      if (ErrStr) *ErrStr = sys::StrError();
       return 0;
     }
     FileSize = FileInfoPtr->st_size;
@@ -208,7 +214,6 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
       (FileSize & (sys::Process::GetPageSize()-1)) != 0) {
     if (const char *Pages = sys::Path::MapInFilePages(FD, FileSize)) {
       // Close the file descriptor, now that the whole file is in memory.
-      ::close(FD);
       return new MemoryBufferMMapFile(Filename, Pages, FileSize);
     }
   }
@@ -217,30 +222,31 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
   if (!Buf) {
     // Failed to create a buffer.
     if (ErrStr) *ErrStr = "could not allocate buffer";
-    ::close(FD);
     return 0;
   }
 
   OwningPtr<MemoryBuffer> SB(Buf);
   char *BufPtr = const_cast<char*>(SB->getBufferStart());
-  
+
   size_t BytesLeft = FileSize;
   while (BytesLeft) {
     ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
-    if (NumRead > 0) {
-      BytesLeft -= NumRead;
-      BufPtr += NumRead;
-    } else if (NumRead == -1 && errno == EINTR) {
-      // try again
-    } else {
-      // error reading.
-      if (ErrStr) *ErrStr = strerror(errno);
-      close(FD);
+    if (NumRead == -1) {
+      if (errno == EINTR)
+        continue;
+      // Error while reading.
+      if (ErrStr) *ErrStr = sys::StrError();
       return 0;
+    } else if (NumRead == 0) {
+      // We hit EOF early, truncate and terminate buffer.
+      Buf->BufferEnd = BufPtr;
+      *BufPtr = 0;
+      return SB.take();
     }
+    BytesLeft -= NumRead;
+    BufPtr += NumRead;
   }
-  close(FD);
-  
+
   return SB.take();
 }