----------------------------------------------------------------------------------
| 135 | |
| 136 | // ---------------------------------------------------------------------------------- |
| 137 | size_t DefaultIOStream::FileSize() const { |
| 138 | if (!mFile || mFilename.empty()) { |
| 139 | return 0; |
| 140 | } |
| 141 | |
| 142 | if (SIZE_MAX == mCachedSize) { |
| 143 | |
| 144 | // Although fseek/ftell would allow us to reuse the existing file handle here, |
| 145 | // it is generally unsafe because: |
| 146 | // - For binary streams, it is not technically well-defined |
| 147 | // - For text files the results are meaningless |
| 148 | // That's why we use the safer variant fstat here. |
| 149 | // |
| 150 | // See here for details: |
| 151 | // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file |
| 152 | #if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601) |
| 153 | struct __stat64 fileStat; |
| 154 | //using fileno + fstat avoids having to handle the filename |
| 155 | int err = _fstat64(_fileno(mFile), &fileStat); |
| 156 | if (0 != err) |
| 157 | return 0; |
| 158 | mCachedSize = (size_t)(fileStat.st_size); |
| 159 | #elif defined _WIN32 |
| 160 | struct _stat fileStat; |
| 161 | //using fileno + fstat avoids having to handle the filename |
| 162 | int err = _fstat(_fileno(mFile), &fileStat); |
| 163 | if (0 != err) |
| 164 | return 0; |
| 165 | mCachedSize = (size_t)(fileStat.st_size); |
| 166 | #elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__ |
| 167 | struct stat fileStat; |
| 168 | int err = stat(mFilename.c_str(), &fileStat); |
| 169 | if (0 != err) |
| 170 | return 0; |
| 171 | const unsigned long long cachedSize = fileStat.st_size; |
| 172 | mCachedSize = static_cast<size_t>(cachedSize); |
| 173 | #else |
| 174 | #error "Unknown platform" |
| 175 | #endif |
| 176 | } |
| 177 | return mCachedSize; |
| 178 | } |
| 179 | |
| 180 | // ---------------------------------------------------------------------------------- |
| 181 | void DefaultIOStream::Flush() { |
no test coverage detected