Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
file_ifstream.h
1 #pragma once
2 
3 #include <istream>
4 #include <streambuf>
5 #include <memory>
6 #include <cstdio>
7 #include <cassert>
8 
9 #include "../macros.h"
10 
11 namespace smlt {
12 
13 class FileStreamBuf : public std::streambuf {
14  /* This is essentially a std::istream wrapper around FILE*
15  * mainly so that we can access the underlying FILE* for C
16  * APIs (e.g. stb_vorbis) */
17 
18  static const int BUFFER_SIZE = 4096;
19 
20  /* This is used to log a warning when we start having quite
21  * a lot of files open. Some platforms (Dreamcast) are limited
22  * in how many open files there can be... */
23 
24  static const uint32_t FILE_OPEN_WARN_COUNT = 6;
25  static uint32_t open_file_counter;
26 public:
27  FileStreamBuf(const std::string& name, const std::string& mode);
28  ~FileStreamBuf();
29 
30  int_type underflow() override;
31 
32  std::streampos seekpos(
33  std::streampos sp,
34  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override;
35 
36  std::streampos seekoff(
37  std::streamoff off,
38  std::ios_base::seekdir way,
39  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override;
40 
41  int_type pbackfail(int_type c = EOF) override;
42 
43  FILE* file() const {
44  return filein_;
45  }
46 
47 private:
48  FILE* filein_ = nullptr;
49  char buffer_[BUFFER_SIZE];
50  uint32_t last_read_pos_ = 0;
51 };
52 
53 class FileIfstream : public std::istream {
54 public:
55  FileIfstream(std::shared_ptr<FileStreamBuf> buf):
56  std::istream(buf.get()),
57  buffer_(buf) {
58 
59  }
60 
61  FILE* file() const {
62  return buffer_->file();
63  }
64 
65  explicit operator bool() const {
66  return !fail();
67  }
68 
69 private:
70  std::shared_ptr<FileStreamBuf> buffer_;
71 };
72 
73 
74 }
smlt
Definition: animation.cpp:25
smlt::FileIfstream
Definition: file_ifstream.h:53
smlt::FileStreamBuf
Definition: file_ifstream.h:13