1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved. 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 <cstring> 16 17 #include "tensorflow/contrib/lite/toco/toco_port.h" 18 #include "tensorflow/contrib/lite/toco/toco_types.h" 19 #include "tensorflow/core/platform/logging.h" 20 21 namespace toco { 22 namespace port { 23 void CopyToBuffer(const string& src, char* dest) { 24 memcpy(dest, src.data(), src.size()); 25 } 26 27 #ifdef PLATFORM_GOOGLE 28 void CopyToBuffer(const Cord& src, char* dest) { src.CopyToArray(dest); } 29 #endif 30 } // namespace port 31 } // namespace toco 32 33 #if defined(PLATFORM_GOOGLE) && !defined(__APPLE__) && !defined(__ANDROID__) 34 35 // Wrap Google file operations. 36 37 #include "base/init_google.h" 38 #include "file/base/file.h" 39 #include "file/base/filesystem.h" 40 #include "file/base/helpers.h" 41 #include "file/base/options.h" 42 #include "file/base/path.h" 43 44 namespace toco { 45 namespace port { 46 47 void InitGoogle(const char* usage, int* argc, char*** argv, bool remove_flags) { 48 ::InitGoogle(usage, argc, argv, remove_flags); 49 } 50 51 void CheckInitGoogleIsDone(const char* message) { 52 ::CheckInitGoogleIsDone(message); 53 } 54 55 namespace file { 56 57 // Conversion to our wrapper Status. 58 Status ToStatus(const ::util::Status& uts) { 59 return Status(uts.ok(), uts.error_message()); 60 } 61 62 // Conversion to our wrapper Options. 63 toco::port::file::Options ToOptions(const ::file::Options& options) { 64 CHECK_EQ(&options, &::file::Defaults()); 65 return Options(); 66 } 67 68 Status Writable(const string& filename) { 69 File* f = nullptr; 70 const auto status = ::file::Open(filename, "w", &f, ::file::Defaults()); 71 if (f) { 72 QCHECK_OK(f->Close(::file::Defaults())); 73 } 74 return ToStatus(status); 75 } 76 77 Status Readable(const string& filename, const file::Options& options) { 78 return ToStatus(::file::Readable(filename, ::file::Defaults())); 79 } 80 81 Status Exists(const string& filename, const file::Options& options) { 82 auto status = ::file::Exists(filename, ::file::Defaults()); 83 return ToStatus(status); 84 } 85 86 Status GetContents(const string& filename, string* contents, 87 const file::Options& options) { 88 return ToStatus(::file::GetContents(filename, contents, ::file::Defaults())); 89 } 90 91 Status SetContents(const string& filename, const string& contents, 92 const file::Options& options) { 93 return ToStatus(::file::SetContents(filename, contents, ::file::Defaults())); 94 } 95 96 string JoinPath(const string& a, const string& b) { 97 return ::file::JoinPath(a, b); 98 } 99 100 } // namespace file 101 } // namespace port 102 } // namespace toco 103 104 #else // (__APPLE__ || __ANDROID__) 105 106 #include <fcntl.h> 107 #include <sys/stat.h> 108 #include <sys/types.h> 109 #include <unistd.h> 110 #include <cstdio> 111 112 #if defined(PLATFORM_GOOGLE) 113 #include "base/commandlineflags.h" 114 #endif 115 116 namespace toco { 117 namespace port { 118 119 static bool port_initialized = false; 120 121 void InitGoogle(const char* usage, int* argc, char*** argv, bool remove_flags) { 122 if (!port_initialized) { 123 #if defined(PLATFORM_GOOGLE) 124 ParseCommandLineFlags(argc, argv, remove_flags); 125 #endif 126 port_initialized = true; 127 } 128 } 129 130 void CheckInitGoogleIsDone(const char* message) { 131 CHECK(port_initialized) << message; 132 } 133 134 namespace file { 135 136 Status Writable(const string& filename) { 137 FILE* f = fopen(filename.c_str(), "w"); 138 if (f) { 139 fclose(f); 140 return Status(true, ""); 141 } 142 return Status(false, "not writable"); 143 } 144 145 Status Readable(const string& filename, const file::Options& options) { 146 FILE* f = fopen(filename.c_str(), "r"); 147 if (f) { 148 fclose(f); 149 return Status(true, ""); 150 } 151 return Status(false, "not readable"); 152 } 153 154 Status Exists(const string& filename, const file::Options& options) { 155 struct stat statbuf; 156 int ret = stat(filename.c_str(), &statbuf); 157 return Status(ret != -1, ""); 158 } 159 160 Status GetContents(const string& path, string* output, 161 const file::Options& options) { 162 output->clear(); 163 164 int fd = open(path.c_str(), O_RDONLY); 165 if (fd == -1) { 166 return Status(false, "can't open() for read"); 167 } 168 169 // Direct read, for speed. 170 const int kBufSize = 1 << 16; 171 char buffer[kBufSize]; 172 while (true) { 173 int size = read(fd, buffer, kBufSize); 174 if (size == 0) { 175 // Done. 176 close(fd); 177 return Status(true, ""); 178 } else if (size == -1) { 179 // Error. 180 close(fd); 181 return Status(false, "error during read()"); 182 } else { 183 output->append(buffer, size); 184 } 185 } 186 187 CHECK(0); 188 return Status(false, "internal error"); 189 } 190 191 Status SetContents(const string& filename, const string& contents, 192 const file::Options& options) { 193 int fd = open(filename.c_str(), O_WRONLY | O_CREAT, 0664); 194 if (fd == -1) { 195 return Status(false, "can't open() for write"); 196 } 197 198 size_t i = 0; 199 while (i < contents.size()) { 200 size_t to_write = contents.size() - i; 201 ssize_t written = write(fd, &contents[i], to_write); 202 if (written == -1) { 203 close(fd); 204 return Status(false, "write() error"); 205 } 206 i += written; 207 } 208 close(fd); 209 210 return Status(true, ""); 211 } 212 213 string JoinPath(const string& base, const string& filename) { 214 if (base.empty()) return filename; 215 string base_fixed = base; 216 if (!base_fixed.empty() && base_fixed.back() == '/') base_fixed.pop_back(); 217 string filename_fixed = filename; 218 if (!filename_fixed.empty() && filename_fixed.front() == '/') 219 filename_fixed.erase(0, 1); 220 return base_fixed + "/" + filename_fixed; 221 } 222 223 } // namespace file 224 } // namespace port 225 } // namespace toco 226 227 #endif // (__APPLE || __ANDROID__) 228