Skip to content

Commit ad4b4d5

Browse files
committed
If non-mmap: use stdio reading of files instead of std::stream
std::fstream is much slower than the good ol' standard implementation. In addition, there are no risks of throwing exceptions.
1 parent 56d75de commit ad4b4d5

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

.github/workflows/verible-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,8 @@ jobs:
462462
uses: actions/cache@v3
463463
with:
464464
path: "c:/users/runneradmin/_bazel_runneradmin"
465-
key: bazelcache_windows2_${{ steps.cache_timestamp.outputs.time }}
466-
restore-keys: bazelcache_windows2_
465+
key: bazelcache_windows_${{ steps.cache_timestamp.outputs.time }}
466+
restore-keys: bazelcache_windows_
467467

468468
- name: Install dependencies
469469
run: |

common/util/file_util.cc

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
#include <algorithm>
1818
#include <cerrno>
19+
#include <cstdint>
20+
#include <cstdio>
1921
#include <cstdlib>
2022
#include <cstring>
2123
#include <filesystem>
22-
#include <fstream>
23-
#include <iostream>
2424
#include <memory>
2525
#include <string>
2626
#include <system_error>
@@ -154,34 +154,35 @@ absl::Status FileExists(const std::string &filename) {
154154

155155
absl::StatusOr<std::string> GetContentAsString(absl::string_view filename) {
156156
std::string content;
157-
std::ifstream fs;
158-
std::istream *stream = nullptr;
157+
FILE *stream = nullptr;
159158
const bool use_stdin = IsStdin(filename);
160159
if (use_stdin) {
161-
stream = &std::cin;
160+
#ifdef _WIN32
161+
_setmode(_fileno(stdin), _O_BINARY); // Work around DOS/Win silliness.
162+
#endif
163+
stream = stdin;
162164
} else {
163165
const std::string filename_str = std::string{filename};
164166
if (absl::Status status = FileExists(filename_str); !status.ok()) {
165167
return status; // Bail
166168
}
167-
fs.open(filename_str.c_str());
169+
stream = fopen(filename_str.c_str(), "rb");
168170
std::error_code err;
169171
const size_t prealloc = fs::file_size(filename_str, err);
170172
if (err.value() == 0) content.reserve(prealloc);
171-
stream = &fs;
172173
}
173-
if (!stream->good()) {
174+
if (!stream) {
174175
return CreateErrorStatusFromErrno(filename, "can't read");
175176
}
176177
char buffer[4096];
177-
while (stream->good() && !stream->eof()) {
178-
stream->read(buffer, sizeof(buffer));
179-
content.append(buffer, stream->gcount());
180-
}
181-
182-
// Allow stdin to be reopened for more input.
183-
if (use_stdin && std::cin.eof()) std::cin.clear();
184-
return std::move(content);
178+
int bytes_read;
179+
do {
180+
bytes_read = fread(buffer, 1, sizeof(buffer), stream);
181+
content.append(buffer, bytes_read);
182+
} while (bytes_read > 0);
183+
fclose(stream);
184+
185+
return content;
185186
}
186187

187188
static absl::StatusOr<std::unique_ptr<MemBlock>> AttemptMemMapFile(
@@ -244,11 +245,21 @@ absl::StatusOr<std::unique_ptr<MemBlock>> GetContentAsMemBlock(
244245
absl::Status SetContents(absl::string_view filename,
245246
absl::string_view content) {
246247
VLOG(1) << __FUNCTION__ << ": Writing file: " << filename;
247-
std::ofstream f(std::string(filename).c_str());
248-
if (!f.good()) return CreateErrorStatusFromErrno(filename, "can't write.");
249-
f << content;
250-
f.close();
251-
if (!f.good()) return CreateErrorStatusFromErrno(filename, "closing.");
248+
FILE *out = fopen(std::string(filename).c_str(), "wb");
249+
if (!out) return CreateErrorStatusFromErrno(filename, "can't write.");
250+
const int64_t expected_write = content.size();
251+
int64_t total_written = 0;
252+
while (!content.empty()) {
253+
int64_t w = fwrite(content.data(), 1, content.size(), out);
254+
total_written += w;
255+
content.remove_prefix(w);
256+
}
257+
if (total_written != expected_write) {
258+
return CreateErrorStatusFromErrno(filename, "Could not write completely.");
259+
}
260+
if (fclose(out) != 0) {
261+
return CreateErrorStatusFromErrno(filename, "closing.");
262+
}
252263
return absl::OkStatus();
253264
}
254265

0 commit comments

Comments
 (0)