blob: 85faf67ecd0b6c7c6db23d91fe4d8f47cf60693d [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>
27#endif
28
Casey Dahlin64533512015-10-23 17:11:21 -070029#include <base/strings.h>
30
Christopher Wiley054afbd2015-10-16 17:08:43 -070031#include "logging.h"
32#include "os.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070033
34using std::string;
35using std::unique_ptr;
Christopher Wiley054afbd2015-10-16 17:08:43 -070036using std::vector;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070037
Casey Dahlin64533512015-10-23 17:11:21 -070038using android::base::Split;
39
Christopher Wiley4a2884b2015-10-07 11:27:45 -070040namespace android {
41namespace aidl {
42
43unique_ptr<string> IoDelegate::GetFileContents(
44 const string& filename,
45 const string& content_suffix) const {
46 unique_ptr<string> contents;
47 std::ifstream in(filename, std::ios::in | std::ios::binary);
48 if (!in) {
49 return contents;
50 }
51 contents.reset(new string);
52 in.seekg(0, std::ios::end);
53 ssize_t file_size = in.tellg();
54 contents->resize(file_size + content_suffix.length());
55 in.seekg(0, std::ios::beg);
56 // Read the file contents into the beginning of the string
57 in.read(&(*contents)[0], file_size);
58 // Drop the suffix in at the end.
59 contents->replace(file_size, content_suffix.length(), content_suffix);
60 in.close();
61
62 return contents;
63}
64
Christopher Wileyef140932015-11-03 09:29:19 -080065unique_ptr<LineReader> IoDelegate::GetLineReader(
66 const string& file_path) const {
67 return LineReader::ReadFromFile(file_path);
68}
69
Christopher Wiley72877ac2015-10-06 14:41:42 -070070bool IoDelegate::FileIsReadable(const string& path) const {
71#ifdef _WIN32
72 // check that the file exists and is not write-only
73 return (0 == _access(path.c_str(), 0)) && // mode 0=exist
74 (0 == _access(path.c_str(), 4)); // mode 4=readable
75#else
76 return (0 == access(path.c_str(), R_OK));
77#endif
78}
Christopher Wiley054afbd2015-10-16 17:08:43 -070079
80bool IoDelegate::CreatedNestedDirs(
81 const string& caller_base_dir,
82 const vector<string>& nested_subdirs) const {
83 string base_dir = caller_base_dir;
84 if (base_dir.empty()) {
85 base_dir = ".";
86 }
87 for (const string& subdir : nested_subdirs) {
88 if (base_dir[base_dir.size() - 1] != OS_PATH_SEPARATOR) {
89 base_dir += OS_PATH_SEPARATOR;
90 }
91 base_dir += subdir;
92 bool success;
93#ifdef _WIN32
94 success = _mkdir(base_dir.c_str()) == 0;
95#else
96 success = mkdir(base_dir.c_str(),
97 S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
98#endif
Christopher Wiley3badcde2015-11-06 10:59:27 -080099 // On darwin when you try to mkdir("/", ...) we get EISDIR.
100 if (!success && (errno != EEXIST && errno != EISDIR)) {
Christopher Wiley054afbd2015-10-16 17:08:43 -0700101 LOG(ERROR) << "Error while creating directories: " << strerror(errno);
102 return false;
103 }
104 }
105 return true;
106}
107
Casey Dahlin64533512015-10-23 17:11:21 -0700108bool IoDelegate::CreatePathForFile(const string& path) const {
109 if (path.empty()) {
110 return true;
111 }
112
113 string base = ".";
114 if (path[0] == OS_PATH_SEPARATOR) {
115 base = "/";
116 }
117
118 auto split = Split(path, string{1u, OS_PATH_SEPARATOR});
119 split.pop_back();
120
121 return CreatedNestedDirs(base, split);
122}
123
Christopher Wiley054afbd2015-10-16 17:08:43 -0700124unique_ptr<CodeWriter> IoDelegate::GetCodeWriter(
125 const string& file_path) const {
126 return GetFileWriter(file_path);
127}
128
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700129} // namespace android
130} // namespace aidl