LLVM API Documentation
00001 //===--- llvm/Support/DataStream.cpp - Lazy streamed data -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements DataStreamer, which fetches bytes of Data from 00011 // a stream source. It provides support for streaming (lazy reading) of 00012 // bitcode. An example implementation of streaming from a file or stdin 00013 // is included. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "llvm/Support/DataStream.h" 00018 #include "llvm/ADT/Statistic.h" 00019 #include "llvm/Support/FileSystem.h" 00020 #include "llvm/Support/Program.h" 00021 #include <cerrno> 00022 #include <cstdio> 00023 #include <string> 00024 #include <system_error> 00025 #if !defined(_MSC_VER) && !defined(__MINGW32__) 00026 #include <unistd.h> 00027 #else 00028 #include <io.h> 00029 #endif 00030 using namespace llvm; 00031 00032 #define DEBUG_TYPE "Data-stream" 00033 00034 // Interface goals: 00035 // * StreamableMemoryObject doesn't care about complexities like using 00036 // threads/async callbacks to actually overlap download+compile 00037 // * Don't want to duplicate Data in memory 00038 // * Don't need to know total Data len in advance 00039 // Non-goals: 00040 // StreamableMemoryObject already has random access so this interface only does 00041 // in-order streaming (no arbitrary seeking, else we'd have to buffer all the 00042 // Data here in addition to MemoryObject). This also means that if we want 00043 // to be able to to free Data, BitstreamBytes/BitcodeReader will implement it 00044 00045 STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); 00046 00047 namespace llvm { 00048 DataStreamer::~DataStreamer() {} 00049 } 00050 00051 namespace { 00052 00053 // Very simple stream backed by a file. Mostly useful for stdin and debugging; 00054 // actual file access is probably still best done with mmap. 00055 class DataFileStreamer : public DataStreamer { 00056 int Fd; 00057 public: 00058 DataFileStreamer() : Fd(0) {} 00059 virtual ~DataFileStreamer() { 00060 close(Fd); 00061 } 00062 size_t GetBytes(unsigned char *buf, size_t len) override { 00063 NumStreamFetches++; 00064 return read(Fd, buf, len); 00065 } 00066 00067 std::error_code OpenFile(const std::string &Filename) { 00068 if (Filename == "-") { 00069 Fd = 0; 00070 sys::ChangeStdinToBinary(); 00071 return std::error_code(); 00072 } 00073 00074 return sys::fs::openFileForRead(Filename, Fd); 00075 } 00076 }; 00077 00078 } 00079 00080 namespace llvm { 00081 DataStreamer *getDataFileStreamer(const std::string &Filename, 00082 std::string *StrError) { 00083 DataFileStreamer *s = new DataFileStreamer(); 00084 if (std::error_code e = s->OpenFile(Filename)) { 00085 *StrError = std::string("Could not open ") + Filename + ": " + 00086 e.message() + "\n"; 00087 return nullptr; 00088 } 00089 return s; 00090 } 00091 00092 }