Simulant  21.12-574
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  char fbuffer_[BUFFER_SIZE];
51 
52  uint32_t last_read_pos_ = 0;
53 };
54 
55 class FileIfstream : public std::istream {
56 public:
57  FileIfstream(std::shared_ptr<FileStreamBuf> buf):
58  std::istream(buf.get()),
59  buffer_(buf) {
60 
61  }
62 
63  FILE* file() const {
64  return buffer_->file();
65  }
66 
67  explicit operator bool() const {
68  return !fail();
69  }
70 
71 private:
72  std::shared_ptr<FileStreamBuf> buffer_;
73 };
74 
75 
76 }
smlt
Definition: animation.cpp:25
smlt::FileIfstream
Definition: file_ifstream.h:55
smlt::FileStreamBuf
Definition: file_ifstream.h:13