| 128 | } |
| 129 | |
| 130 | bool ReadFileToString(const FilePath& path, |
| 131 | std::string* contents, |
| 132 | size_t max_size) { |
| 133 | if (contents) |
| 134 | contents->clear(); |
| 135 | if (path.ReferencesParent()) |
| 136 | return false; |
| 137 | FILE* file = OpenFile(path, "rb"); |
| 138 | if (!file) { |
| 139 | return false; |
| 140 | } |
| 141 | |
| 142 | char buf[1 << 16]; |
| 143 | size_t len; |
| 144 | size_t size = 0; |
| 145 | bool read_status = true; |
| 146 | |
| 147 | // Many files supplied in |path| have incorrect size (proc files etc). |
| 148 | // Hence, the file is read sequentially as opposed to a one-shot read. |
| 149 | while ((len = fread(buf, 1, sizeof(buf), file)) > 0) { |
| 150 | if (contents) |
| 151 | contents->append(buf, std::min(len, max_size - size)); |
| 152 | |
| 153 | if ((max_size - size) < len) { |
| 154 | read_status = false; |
| 155 | break; |
| 156 | } |
| 157 | |
| 158 | size += len; |
| 159 | } |
| 160 | read_status = read_status && !ferror(file); |
| 161 | CloseFile(file); |
| 162 | |
| 163 | return read_status; |
| 164 | } |
| 165 | |
| 166 | bool ReadFileToString(const FilePath& path, std::string* contents) { |
| 167 | return ReadFileToString(path, contents, std::numeric_limits<size_t>::max()); |