Coverage Report

Created: 2026-10-10 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sentencepiece/src/filesystem.cc
Line
Count
Source
1
// Copyright 2016 Google Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.!
14
15
#include "filesystem.h"
16
17
#include <cerrno>
18
#include <fstream>
19
#include <iostream>
20
#include <memory>
21
#include <string>
22
23
#include "absl/log/log.h"
24
#include "absl/status/status.h"
25
#include "absl/strings/str_cat.h"
26
#include "absl/strings/string_view.h"
27
#include "util.h"
28
29
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(UNICODE) && \
30
    defined(_UNICODE)
31
#include <windows.h>
32
namespace {
33
std::wstring Utf8ToWide(absl::string_view input) {
34
  const int output_length = ::MultiByteToWideChar(
35
      CP_UTF8, 0, input.data(), static_cast<int>(input.size()), nullptr, 0);
36
  if (output_length == 0) {
37
    return L"";
38
  }
39
  std::wstring output(output_length, 0);
40
  const int result = ::MultiByteToWideChar(CP_UTF8, 0, input.data(),
41
                                           static_cast<int>(input.size()),
42
                                           output.data(), output.size());
43
  return result == output_length ? output : L"";
44
}
45
}  // namespace
46
#define WPATH(path) (Utf8ToWide(path).c_str())
47
#else
48
0
#define WPATH(path) (path.data())
49
#endif
50
51
namespace sentencepiece {
52
namespace filesystem {
53
54
class PosixReadableFile : public ReadableFile {
55
 public:
56
  explicit PosixReadableFile(absl::string_view filename,
57
0
                             bool is_binary = false) {
58
0
    if (filename.empty()) {
59
0
      is_ = &std::cin;
60
0
    } else {
61
0
      file_.open(WPATH(filename),
62
0
                 is_binary ? std::ios::binary | std::ios::in : std::ios::in);
63
0
      is_ = &file_;
64
0
    }
65
0
    if (!*is_ || ((is_->peek() != 0) && is_->fail())) {
66
0
      status_ = absl::ErrnoToStatus(errno, absl::StrCat("\"", filename, "\""));
67
0
    }
68
0
  }
69
70
0
  ~PosixReadableFile() override = default;
71
72
0
  absl::Status status() const override { return status_; }
73
74
0
  bool ReadLine(std::string* line) override {
75
0
    return static_cast<bool>(std::getline(*is_, *line));
76
0
  }
77
78
0
  bool ReadAll(std::string* line) override {
79
0
    if (is_ == &std::cin) {
80
0
      LOG(ERROR) << "ReadAll is not supported for stdin.";
81
0
      return false;
82
0
    }
83
0
    line->assign(std::istreambuf_iterator<char>(*is_),
84
0
                 std::istreambuf_iterator<char>());
85
0
    return true;
86
0
  }
87
88
 private:
89
  absl::Status status_;
90
  std::ifstream file_;
91
  std::istream* is_;
92
};
93
94
class PosixWritableFile : public WritableFile {
95
 public:
96
  explicit PosixWritableFile(absl::string_view filename,
97
0
                             bool is_binary = false) {
98
0
    if (filename.empty()) {
99
0
      os_ = &std::cout;
100
0
    } else {
101
0
      file_.open(WPATH(filename),
102
0
                 is_binary ? std::ios::binary | std::ios::out : std::ios::out);
103
0
      os_ = &file_;
104
0
    }
105
0
    if (!*os_) {
106
0
      status_ = absl::ErrnoToStatus(errno, absl::StrCat("\"", filename, "\""));
107
0
    }
108
0
  }
109
110
0
  ~PosixWritableFile() override = default;
111
112
0
  absl::Status status() const override { return status_; }
113
114
0
  bool Write(absl::string_view text) override {
115
0
    os_->write(text.data(), text.size());
116
0
    return os_->good();
117
0
  }
118
119
0
  bool WriteLine(absl::string_view text) override {
120
0
    return Write(text) && Write("\n");
121
0
  }
122
123
 private:
124
  absl::Status status_;
125
  std::ofstream file_;
126
  std::ostream* os_;
127
};
128
129
using DefaultReadableFile = PosixReadableFile;
130
using DefaultWritableFile = PosixWritableFile;
131
132
std::unique_ptr<ReadableFile> NewReadableFile(absl::string_view filename,
133
0
                                              bool is_binary) {
134
0
  return std::make_unique<DefaultReadableFile>(filename, is_binary);
135
0
}
136
137
std::unique_ptr<WritableFile> NewWritableFile(absl::string_view filename,
138
0
                                              bool is_binary) {
139
0
  return std::make_unique<DefaultWritableFile>(filename, is_binary);
140
0
}
141
142
}  // namespace filesystem
143
}  // namespace sentencepiece