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