Check for librt earlier
[openal-soft.git] / common / alfstream.cpp
blob7378c678e818ea3f2736783812d03fc7eb7910c1
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()
92 if(mFile != INVALID_HANDLE_VALUE)
93 CloseHandle(mFile);
94 mFile = INVALID_HANDLE_VALUE;
97 bool filebuf::open(const wchar_t *filename, std::ios_base::openmode mode)
99 if((mode&std::ios_base::out) || !(mode&std::ios_base::in))
100 return false;
101 HANDLE f{CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
102 FILE_ATTRIBUTE_NORMAL, nullptr)};
103 if(f == INVALID_HANDLE_VALUE) return false;
105 if(mFile != INVALID_HANDLE_VALUE)
106 CloseHandle(mFile);
107 mFile = f;
109 setg(nullptr, nullptr, nullptr);
110 return true;
112 bool filebuf::open(const char *filename, std::ios_base::openmode mode)
114 std::wstring wname{utf8_to_wstr(filename)};
115 return open(wname.c_str(), mode);
119 ifstream::ifstream(const wchar_t *filename, std::ios_base::openmode mode)
120 : std::istream{nullptr}
122 init(&mStreamBuf);
124 // Set the failbit if the file failed to open.
125 if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in))
126 clear(failbit);
129 ifstream::ifstream(const char *filename, std::ios_base::openmode mode)
130 : std::istream{nullptr}
132 init(&mStreamBuf);
134 // Set the failbit if the file failed to open.
135 if((mode&std::ios_base::out) || !mStreamBuf.open(filename, mode|std::ios_base::in))
136 clear(failbit);
139 /* This is only here to ensure the compiler doesn't define an implicit
140 * destructor, which it tries to automatically inline and subsequently complain
141 * it can't inline without excessive code growth.
143 ifstream::~ifstream() { }
145 } // namespace al
147 #endif