• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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