blob: aabe4cb049df6bac8f500802bff3da7cb81596ee [file] [log] [blame]
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001/*
2 * Copyright (C) 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "io_delegate.h"
18
Christopher Wiley054afbd2015-10-16 17:08:43 -070019#include <cstring>
Christopher Wiley4a2884b2015-10-07 11:27:45 -070020#include <fstream>
Christopher Wiley054afbd2015-10-16 17:08:43 -070021#include <vector>
22
23#ifdef _WIN32
24#include <direct.h>
25#else
26#include <sys/stat.h>
Christopher Wiley9d6e0b22015-11-13 12:18:16 -080027#include <unistd.h>
Christopher Wiley054afbd2015-10-16 17:08:43 -070028#endif
29
Elliott Hughes0a620672015-12-04 13:53:18 -080030#include <android-base/strings.h>
Casey Dahlin64533512015-10-23 17:11:21 -070031
Christopher Wiley054afbd2015-10-16 17:08:43 -070032#include "logging.h"
33#include "os.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070034
35using std::string;
36using std::unique_ptr;
Christopher Wiley054afbd2015-10-16 17:08:43 -070037using std::vector;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070038
Casey Dahlin64533512015-10-23 17:11:21 -070039using android::base::Split;
40
Christopher Wiley4a2884b2015-10-07 11:27:45 -070041namespace android {
42namespace aidl {
43
44unique_ptr<string> IoDelegate::GetFileContents(
45 const string& filename,
46 const string& content_suffix) const {
47 unique_ptr<string> contents;
48 std::ifstream in(filename, std::ios::in | std::ios::binary);
49 if (!in) {
50 return contents;
51 }
52 contents.reset(new string);
53 in.seekg(0, std::ios::end);
54 ssize_t file_size = in.tellg();
55 contents->resize(file_size + content_suffix.length());
56 in.seekg(0, std::ios::beg);
57 // Read the file contents into the beginning of the string
58 in.read(&(*contents)[0], file_size);
59 // Drop the suffix in at the end.
60 contents->replace(file_size, content_suffix.length(), content_suffix);
61 in.close();
62
63 return contents;
64}
65
Christopher Wileyef140932015-11-03 09:29:19 -080066unique_ptr<LineReader> IoDelegate::GetLineReader(
67 const string& file_path) const {
68 return LineReader::ReadFromFile(file_path);
69}
70
Christopher Wiley72877ac2015-10-06 14:41:42 -070071bool IoDelegate::FileIsReadable(const string& path) const {
72#ifdef _WIN32
73 // check that the file exists and is not write-only
74 return (0 == _access(path.c_str(), 0)) && // mode 0=exist
75 (0 == _access(path.c_str(), 4)); // mode 4=readable
76#else
77 return (0 == access(path.c_str(), R_OK));
78#endif
79}
Christopher Wiley054afbd2015-10-16 17:08:43 -070080
81bool IoDelegate::CreatedNestedDirs(
82 const string& caller_base_dir,
83 const vector<string>& nested_subdirs) const {
84 string base_dir = caller_base_dir;
85 if (base_dir.empty()) {
86 base_dir = ".";
87 }
88 for (const string& subdir : nested_subdirs) {
89 if (base_dir[base_dir.size() - 1] != OS_PATH_SEPARATOR) {
90 base_dir += OS_PATH_SEPARATOR;
91 }
92 base_dir += subdir;
93 bool success;
94#ifdef _WIN32
95 success = _mkdir(base_dir.c_str()) == 0;
96#else
97 success = mkdir(base_dir.c_str(),
98 S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
99#endif
Christopher Wiley3badcde2015-11-06 10:59:27 -0800100 // On darwin when you try to mkdir("/", ...) we get EISDIR.
101 if (!success && (errno != EEXIST && errno != EISDIR)) {
Christopher Wiley054afbd2015-10-16 17:08:43 -0700102 LOG(ERROR) << "Error while creating directories: " << strerror(errno);
103 return false;
104 }
105 }
106 return true;
107}
108
Casey Dahlin64533512015-10-23 17:11:21 -0700109bool IoDelegate::CreatePathForFile(const string& path) const {
110 if (path.empty()) {
111 return true;
112 }
113
114 string base = ".";
115 if (path[0] == OS_PATH_SEPARATOR) {
116 base = "/";
117 }
118
119 auto split = Split(path, string{1u, OS_PATH_SEPARATOR});
120 split.pop_back();
121
122 return CreatedNestedDirs(base, split);
123}
124
Christopher Wiley054afbd2015-10-16 17:08:43 -0700125unique_ptr<CodeWriter> IoDelegate::GetCodeWriter(
126 const string& file_path) const {
127 return GetFileWriter(file_path);
128}
129
Christopher Wiley9d6e0b22015-11-13 12:18:16 -0800130void IoDelegate::RemovePath(const std::string& file_path) const {
131#ifdef _WIN32
132 _unlink(file_path.c_str());
133#else
134 unlink(file_path.c_str());
135#endif
136}
137
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700138} // namespace android
139} // namespace aidl