1 // Copyright 2016 The Chromium Embedded Framework Authors. Portions copyright
2 // 2012 The Chromium Authors. All rights reserved. Use of this source code is
3 // governed by a BSD-style license that can be found in the LICENSE file.
4
5 #include "tests/shared/browser/file_util.h"
6
7 #include "include/base/cef_build.h"
8 #include "include/base/cef_scoped_ptr.h"
9 #include "include/cef_task.h"
10
11 #include <algorithm>
12 #include <cstdio>
13 #include <memory>
14
15 namespace client {
16 namespace file_util {
17
18 namespace {
19
AllowFileIO()20 bool AllowFileIO() {
21 if (CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO)) {
22 NOTREACHED() << "file IO is not allowed on the current thread";
23 return false;
24 }
25 return true;
26 }
27
28 } // namespace
29
30 #if defined(OS_WIN)
31 const char kPathSep = '\\';
32 #else
33 const char kPathSep = '/';
34 #endif
35
ReadFileToString(const std::string & path,std::string * contents,size_t max_size)36 bool ReadFileToString(const std::string& path,
37 std::string* contents,
38 size_t max_size) {
39 if (!AllowFileIO())
40 return false;
41
42 if (contents)
43 contents->clear();
44 FILE* file = fopen(path.c_str(), "rb");
45 if (!file)
46 return false;
47
48 const size_t kBufferSize = 1 << 16;
49 scoped_ptr<char[]> buf(new char[kBufferSize]);
50 size_t len;
51 size_t size = 0;
52 bool read_status = true;
53
54 // Many files supplied in |path| have incorrect size (proc files etc).
55 // Hence, the file is read sequentially as opposed to a one-shot read.
56 while ((len = fread(buf.get(), 1, kBufferSize, file)) > 0) {
57 if (contents)
58 contents->append(buf.get(), std::min(len, max_size - size));
59
60 if ((max_size - size) < len) {
61 read_status = false;
62 break;
63 }
64
65 size += len;
66 }
67 read_status = read_status && !ferror(file);
68 fclose(file);
69
70 return read_status;
71 }
72
WriteFile(const std::string & path,const char * data,int size)73 int WriteFile(const std::string& path, const char* data, int size) {
74 if (!AllowFileIO())
75 return -1;
76
77 FILE* file = fopen(path.c_str(), "wb");
78 if (!file)
79 return -1;
80
81 int written = 0;
82
83 do {
84 size_t write = fwrite(data + written, 1, size - written, file);
85 if (write == 0)
86 break;
87 written += static_cast<int>(write);
88 } while (written < size);
89
90 fclose(file);
91
92 return written;
93 }
94
JoinPath(const std::string & path1,const std::string & path2)95 std::string JoinPath(const std::string& path1, const std::string& path2) {
96 if (path1.empty() && path2.empty())
97 return std::string();
98 if (path1.empty())
99 return path2;
100 if (path2.empty())
101 return path1;
102
103 std::string result = path1;
104 if (result[result.size() - 1] != kPathSep)
105 result += kPathSep;
106 if (path2[0] == kPathSep)
107 result += path2.substr(1);
108 else
109 result += path2;
110 return result;
111 }
112
GetFileExtension(const std::string & path)113 std::string GetFileExtension(const std::string& path) {
114 size_t sep = path.find_last_of(".");
115 if (sep != std::string::npos)
116 return path.substr(sep + 1);
117 return std::string();
118 }
119
120 } // namespace file_util
121 } // namespace client
122