Stop the Oboe recording stream when recording is stopped
[openal-soft.git] / common / alfstream.cpp
blob3beda83301cc400e4698c1c559f764e093489c1c
2 #include "config.h"
4 #include "alfstream.h"
6 #include "strutils.h"
8 #ifdef _WIN32
10 namespace al {
12 auto filebuf::underflow() -> int_type
14 if(mFile != INVALID_HANDLE_VALUE && gptr() == egptr())
16 // Read in the next chunk of data, and set the pointers on success
17 DWORD got{};
18 if(ReadFile(mFile, mBuffer.data(), static_cast<DWORD>(mBuffer.size()), &got, nullptr))
19 setg(mBuffer.data(), mBuffer.data(), mBuffer.data()+got);
21 if(gptr() == egptr())
22 return traits_type::eof();
23 return traits_type::to_int_type(*gptr());
26 auto filebuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) -> pos_type
28 if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in))
29 return traits_type::eof();
31 LARGE_INTEGER fpos{};
32 switch(whence)
34 case std::ios_base::beg:
35 fpos.QuadPart = offset;
36 if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN))
37 return traits_type::eof();
38 break;
40 case std::ios_base::cur:
41 // If the offset remains in the current buffer range, just
42 // update the pointer.
43 if((offset >= 0 && offset < off_type(egptr()-gptr())) ||
44 (offset < 0 && -offset <= off_type(gptr()-eback())))
46 // Get the current file offset to report the correct read
47 // offset.
48 fpos.QuadPart = 0;
49 if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT))
50 return traits_type::eof();
51 setg(eback(), gptr()+offset, egptr());
52 return fpos.QuadPart - off_type(egptr()-gptr());
54 // Need to offset for the file offset being at egptr() while
55 // the requested offset is relative to gptr().
56 offset -= off_type(egptr()-gptr());
57 fpos.QuadPart = offset;
58 if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_CURRENT))
59 return traits_type::eof();
60 break;
62 case std::ios_base::end:
63 fpos.QuadPart = offset;
64 if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_END))
65 return traits_type::eof();
66 break;
68 default:
69 return traits_type::eof();
71 setg(nullptr, nullptr, nullptr);
72 return fpos.QuadPart;
75 auto filebuf::seekpos(pos_type pos, std::ios_base::openmode mode) -> pos_type
77 // Simplified version of seekoff
78 if(mFile == INVALID_HANDLE_VALUE || (mode&std::ios_base::out) || !(mode&std::ios_base::in))
79 return traits_type::eof();
81 LARGE_INTEGER fpos{};
82 fpos.QuadPart = pos;
83 if(!SetFilePointerEx(mFile, fpos, &fpos, FILE_BEGIN))
84 return traits_type::eof();
86 setg(nullptr, nullptr, nullptr);
87 return fpos.QuadPart;
90 filebuf::~filebuf()
91 { close(); }
93 bool filebuf::open(const wchar_t *filename, std::ios_base::openmode mode)
95 if((mode&std::ios_base::out) || !(mode&std::ios_base::in))
96 return false;
97 HANDLE f{CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
98 FILE_ATTRIBUTE_NORMAL, nullptr)};
99 if(f == INVALID_HANDLE_VALUE) return false;
101 if(mFile != INVALID_HANDLE_VALUE)
102 CloseHandle(mFile);
103 mFile = f;
105 setg(nullptr, nullptr, nullptr);
106 return true;
108 bool filebuf::open(const char *filename, std::ios_base::openmode mode)
110 std::wstring wname{utf8_to_wstr(filename)};
111 return open(wname.c_str(), mode);
114 void filebuf::close()
116 if(mFile != INVALID_HANDLE_VALUE)
117 CloseHandle(mFile);
118 mFile = INVALID_HANDLE_VALUE;
122 ifstream::ifstream(const wchar_t *filename, std::ios_base::openmode mode)
123 : std::istream{nullptr}
125 init(&mStreamBuf);
127 // Set the failbit if the file failed to open.
128 if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in))
129 clear(failbit);
132 ifstream::ifstream(const char *filename, std::ios_base::openmode mode)
133 : std::istream{nullptr}
135 init(&mStreamBuf);
137 // Set the failbit if the file failed to open.
138 if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in))
139 clear(failbit);
142 /* This is only here to ensure the compiler doesn't define an implicit
143 * destructor, which it tries to automatically inline and subsequently complain
144 * it can't inline without excessive code growth.
146 ifstream::~ifstream() { }
148 } // namespace al
150 #endif