Home | History | Annotate | Download | only in auto_resources
      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:
     38   explicit AutoCloseFILE(FILE *f) : f_(f) { }
     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 
     52   bool IsError() const {
     53     return f_ == NULL;
     54   }
     55 
     56   bool IsEOF() const {
     57     return IsError() || feof(f_);
     58   }
     59 
     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.
     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:
     86   explicit AutoCloseFileDescriptor(int fd) : fd_(fd) { }
     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 
     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.
    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 
    131   AutoFreeBuffer()
    132       : data_(NULL), size_(0), reserve_size_(0) {}
    133 
    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 
    147   char* data() {
    148     return data_;
    149   }
    150 
    151   const char* data() const {
    152     return data_;
    153   }
    154 
    155   char* begin() {
    156     return data_;
    157   }
    158 
    159   const char* begin() const {
    160     return data_;
    161   }
    162 
    163   char* end() {
    164     return data_ + size_;
    165   }
    166 
    167   const char* end() const {
    168     return data_ + size_;
    169   }
    170 
    171   size_t size() const {
    172     return size_;
    173   }
    174 
    175   size_t reserve_size() const {
    176     return reserve_size_;
    177   }
    178 
    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:
    213   explicit AutoUMask(mode_t mask) {
    214       prev_umask = umask(mask);
    215   }
    216 
    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