1 /* 2 * Copyright (C) 2016 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 #ifndef CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_ 17 #define CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_ 18 19 #include <stdarg.h> 20 #include <stdio.h> 21 #include <string.h> 22 #include <unistd.h> 23 #include <pthread.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 27 template <typename T, size_t N> 28 char (&ArraySizeHelper(T (&array)[N]))[N]; 29 30 template <typename T, size_t N> 31 char (&ArraySizeHelper(const T (&array)[N]))[N]; 32 33 #define arraysize(array) (sizeof(ArraySizeHelper(array))) 34 35 // Automatically close a file descriptor 36 class AutoCloseFILE { 37 public: AutoCloseFILE(FILE * f)38 explicit AutoCloseFILE(FILE *f) : f_(f) { } ~AutoCloseFILE()39 virtual ~AutoCloseFILE() { 40 if (f_) { 41 (void)::fclose(f_); 42 f_ = NULL; 43 } 44 } 45 46 operator FILE*() const { 47 return f_; 48 } 49 50 bool CopyFrom(const AutoCloseFILE& in); 51 IsError()52 bool IsError() const { 53 return f_ == NULL; 54 } 55 IsEOF()56 bool IsEOF() const { 57 return IsError() || feof(f_); 58 } 59 IsOpen()60 bool IsOpen() const { 61 return f_ != NULL; 62 } 63 64 // Close the underlying file descriptor, returning a status to give the caller 65 // the chance to act on failure to close. 66 // Returns true on success. close()67 bool close() { 68 bool rval = true; 69 if (f_) { 70 rval = !::fclose(f_); 71 f_ = NULL; 72 } 73 return rval; 74 } 75 76 private: 77 AutoCloseFILE& operator=(const AutoCloseFILE & o); 78 explicit AutoCloseFILE(const AutoCloseFILE &); 79 80 FILE* f_; 81 }; 82 83 // Automatically close a file descriptor 84 class AutoCloseFileDescriptor { 85 public: AutoCloseFileDescriptor(int fd)86 explicit AutoCloseFileDescriptor(int fd) : fd_(fd) { } ~AutoCloseFileDescriptor()87 virtual ~AutoCloseFileDescriptor() { 88 if (fd_ != -1) { 89 (void)::close(fd_); 90 fd_ = -1; 91 } 92 } 93 94 operator int() const { 95 return fd_; 96 } 97 IsError()98 bool IsError() const { 99 return fd_ == -1; 100 } 101 102 // Close the underlying file descriptor, returning a status to give the caller 103 // the chance to act on failure to close. 104 // Returns true on success. close()105 bool close() { 106 bool rval = true; 107 if (fd_ != -1) { 108 rval = !::close(fd_); 109 fd_ = -1; 110 } 111 return rval; 112 } 113 114 private: 115 AutoCloseFileDescriptor& operator=(const AutoCloseFileDescriptor & o); 116 explicit AutoCloseFileDescriptor(const AutoCloseFileDescriptor &); 117 118 int fd_; 119 }; 120 121 // In C++11 this is just std::vector<char>, but Android isn't 122 // there yet. 123 class AutoFreeBuffer { 124 public: 125 enum { 126 // Minimum reserve size of AutoFreeBuffer to consider shrinking reservation. 127 // Any buffer shorter than this will not be shrunk. 128 kAutoBufferShrinkReserveThreshold = 8192 129 }; 130 AutoFreeBuffer()131 AutoFreeBuffer() 132 : data_(NULL), size_(0), reserve_size_(0) {} 133 AutoFreeBuffer(size_t reserve_size)134 AutoFreeBuffer(size_t reserve_size) 135 : data_(NULL), size_(0), reserve_size_(0) { 136 Reserve(reserve_size); 137 } 138 139 ~AutoFreeBuffer(); 140 void Clear(); 141 bool Resize(size_t newsize); 142 bool Reserve(size_t newsize); 143 bool SetToString(const char* in); 144 bool Append(const void* new_data, size_t new_data_size); 145 size_t PrintF(const char* format, ... ); 146 data()147 char* data() { 148 return data_; 149 } 150 data()151 const char* data() const { 152 return data_; 153 } 154 begin()155 char* begin() { 156 return data_; 157 } 158 begin()159 const char* begin() const { 160 return data_; 161 } 162 end()163 char* end() { 164 return data_ + size_; 165 } 166 end()167 const char* end() const { 168 return data_ + size_; 169 } 170 size()171 size_t size() const { 172 return size_; 173 } 174 reserve_size()175 size_t reserve_size() const { 176 return reserve_size_; 177 } 178 Swap(AutoFreeBuffer & other)179 void Swap(AutoFreeBuffer& other) { 180 char* temp_ptr = data_; 181 data_ = other.data_; 182 other.data_ = temp_ptr; 183 184 size_t temp_size = size_; 185 size_ = other.size_; 186 other.size_ = temp_size; 187 188 temp_size = reserve_size_; 189 reserve_size_ = other.reserve_size_; 190 other.reserve_size_ = temp_size; 191 } 192 193 bool operator==(const AutoFreeBuffer& other) const { 194 return (size_ == other.size_) && !memcmp(data_, other.data_, size_); 195 } 196 197 bool operator!=(const AutoFreeBuffer& other) const { 198 return !(*this == other); 199 } 200 201 protected: 202 char *data_; 203 size_t size_; 204 size_t reserve_size_; 205 206 private: 207 AutoFreeBuffer& operator=(const AutoFreeBuffer&); 208 explicit AutoFreeBuffer(const AutoFreeBuffer&); 209 }; 210 211 class AutoUMask { 212 public: AutoUMask(mode_t mask)213 explicit AutoUMask(mode_t mask) { 214 prev_umask = umask(mask); 215 } 216 ~AutoUMask()217 ~AutoUMask() { 218 umask(prev_umask); 219 } 220 private: 221 mode_t prev_umask; 222 }; 223 #endif // CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_ 224