xref: /minix3/external/bsd/llvm/dist/llvm/lib/Support/DataStream.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- llvm/Support/DataStream.cpp - Lazy streamed data -----------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements DataStreamer, which fetches bytes of Data from
11f4a2713aSLionel Sambuc // a stream source. It provides support for streaming (lazy reading) of
12f4a2713aSLionel Sambuc // bitcode. An example implementation of streaming from a file or stdin
13f4a2713aSLionel Sambuc // is included.
14f4a2713aSLionel Sambuc //
15f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc #include "llvm/Support/DataStream.h"
18f4a2713aSLionel Sambuc #include "llvm/ADT/Statistic.h"
19f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
20f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
21f4a2713aSLionel Sambuc #include <cerrno>
22f4a2713aSLionel Sambuc #include <cstdio>
23f4a2713aSLionel Sambuc #include <string>
24*0a6a1f1dSLionel Sambuc #include <system_error>
25f4a2713aSLionel Sambuc #if !defined(_MSC_VER) && !defined(__MINGW32__)
26f4a2713aSLionel Sambuc #include <unistd.h>
27f4a2713aSLionel Sambuc #else
28f4a2713aSLionel Sambuc #include <io.h>
29f4a2713aSLionel Sambuc #endif
30f4a2713aSLionel Sambuc using namespace llvm;
31f4a2713aSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "Data-stream"
33*0a6a1f1dSLionel Sambuc 
34f4a2713aSLionel Sambuc // Interface goals:
35*0a6a1f1dSLionel Sambuc // * StreamingMemoryObject doesn't care about complexities like using
36f4a2713aSLionel Sambuc //   threads/async callbacks to actually overlap download+compile
37f4a2713aSLionel Sambuc // * Don't want to duplicate Data in memory
38f4a2713aSLionel Sambuc // * Don't need to know total Data len in advance
39f4a2713aSLionel Sambuc // Non-goals:
40*0a6a1f1dSLionel Sambuc // StreamingMemoryObject already has random access so this interface only does
41f4a2713aSLionel Sambuc // in-order streaming (no arbitrary seeking, else we'd have to buffer all the
42f4a2713aSLionel Sambuc // Data here in addition to MemoryObject).  This also means that if we want
43f4a2713aSLionel Sambuc // to be able to to free Data, BitstreamBytes/BitcodeReader will implement it
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch");
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc namespace llvm {
~DataStreamer()48f4a2713aSLionel Sambuc DataStreamer::~DataStreamer() {}
49f4a2713aSLionel Sambuc }
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc namespace {
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc // Very simple stream backed by a file. Mostly useful for stdin and debugging;
54f4a2713aSLionel Sambuc // actual file access is probably still best done with mmap.
55f4a2713aSLionel Sambuc class DataFileStreamer : public DataStreamer {
56f4a2713aSLionel Sambuc  int Fd;
57f4a2713aSLionel Sambuc public:
DataFileStreamer()58f4a2713aSLionel Sambuc   DataFileStreamer() : Fd(0) {}
~DataFileStreamer()59f4a2713aSLionel Sambuc   virtual ~DataFileStreamer() {
60f4a2713aSLionel Sambuc     close(Fd);
61f4a2713aSLionel Sambuc   }
GetBytes(unsigned char * buf,size_t len)62*0a6a1f1dSLionel Sambuc   size_t GetBytes(unsigned char *buf, size_t len) override {
63f4a2713aSLionel Sambuc     NumStreamFetches++;
64f4a2713aSLionel Sambuc     return read(Fd, buf, len);
65f4a2713aSLionel Sambuc   }
66f4a2713aSLionel Sambuc 
OpenFile(const std::string & Filename)67*0a6a1f1dSLionel Sambuc   std::error_code OpenFile(const std::string &Filename) {
68f4a2713aSLionel Sambuc     if (Filename == "-") {
69f4a2713aSLionel Sambuc       Fd = 0;
70f4a2713aSLionel Sambuc       sys::ChangeStdinToBinary();
71*0a6a1f1dSLionel Sambuc       return std::error_code();
72f4a2713aSLionel Sambuc     }
73f4a2713aSLionel Sambuc 
74f4a2713aSLionel Sambuc     return sys::fs::openFileForRead(Filename, Fd);
75f4a2713aSLionel Sambuc   }
76f4a2713aSLionel Sambuc };
77f4a2713aSLionel Sambuc 
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc namespace llvm {
getDataFileStreamer(const std::string & Filename,std::string * StrError)81f4a2713aSLionel Sambuc DataStreamer *getDataFileStreamer(const std::string &Filename,
82f4a2713aSLionel Sambuc                                   std::string *StrError) {
83f4a2713aSLionel Sambuc   DataFileStreamer *s = new DataFileStreamer();
84*0a6a1f1dSLionel Sambuc   if (std::error_code e = s->OpenFile(Filename)) {
85f4a2713aSLionel Sambuc     *StrError = std::string("Could not open ") + Filename + ": " +
86f4a2713aSLionel Sambuc         e.message() + "\n";
87*0a6a1f1dSLionel Sambuc     return nullptr;
88f4a2713aSLionel Sambuc   }
89f4a2713aSLionel Sambuc   return s;
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc 
92f4a2713aSLionel Sambuc }
93