FileBase.h revision a2dd52f0710c214e00c1a13e25116e1af5eec77a
1/*
2 * Copyright 2012, 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#ifndef BCC_SUPPORT_FILE_BASE_H
18#define BCC_SUPPORT_FILE_BASE_H
19
20#include <fcntl.h>
21#include <unistd.h>
22#include <string>
23#include <system_error>
24
25namespace android {
26  class FileMap;
27}
28
29namespace bcc {
30
31class FileBase {
32public:
33  enum OpenModeEnum {
34    kReadMode       = 1 << 0,
35    kWriteMode      = 1 << 1,
36    kReadWriteMode  = (kReadMode | kWriteMode),
37  };
38
39  enum FlagEnum {
40    kBinary = 1 << 0,
41    kTruncate = 1 << 1,
42    kAppend = 1 << 2,
43    kDeleteOnClose = 1 << 3
44  };
45
46  enum LockModeEnum {
47    // The shared resource behind the Stream locked in ReadLock mode can be
48    // locked by other processes at the same time.
49    kReadLock,
50
51    // The shared resource behind the Stream locked in WriteLock mode can only
52    // be locked by one process. It's exclusive. That is, the shared resource
53    // cannot have both ReadLock and WriteLock simultaneously.
54    kWriteLock
55  };
56
57  // Default configuration to the lock().
58  enum {
59    kDefaultMaxRetryLock = 4,
60    kDefaultRetryLockInterval = 200000UL,
61  };
62
63protected:
64  // Grant direct access of the internal file descriptor to the sub-class and
65  // error message such that they can implement their own I/O functionality.
66  int mFD;
67
68  std::error_code mError;
69
70private:
71  std::string mName;
72
73  // The 2nd argument to the POSIX open().
74  unsigned mOpenFlags;
75
76  // True true if we should call unlock() in destructor.
77  bool mShouldUnlock;
78
79  // True if file should be deleted in destructor.
80  bool mShouldDelete;
81
82  // Open mName with flag mOpenFlags (using POSIX open().)
83  bool open();
84
85  // Return true if mFD is the corresponded file descriptor to the file named
86  // mName on the filesystem. This check may returns failed, for example,
87  // someone re-create the file with the same name after we openning the file.
88  bool checkFileIntegrity();
89
90  inline bool reopen() {
91    // It's a private method, and all its callers are the few that can invoke it.
92    // That is, the pre-condition will be checked by the caller. Therefore, we don't
93    // need to check it again in reopen().
94    close();
95    return open();
96  }
97
98private:
99  FileBase(FileBase &); // Do not implement.
100  void operator=(const FileBase &); // Do not implement.
101
102protected:
103  // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to
104  // FileBase. It's a bit set composed by the value defined in
105  // FileBase::FlagEnum.
106  FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags);
107
108  void detectError();
109
110public:
111  // Lock the file descriptor in given pMode. If pNonblocking is true, the lock
112  // request issued will return immediately when the shared resource is locked.
113  // In this case, it retries pMaxRetry times, each wait pRetryInterval (in
114  // usecs) before the previous retry getting done.
115  //
116  // Only file is allowed to use this API.
117  bool lock(enum LockModeEnum pMode, bool pNonblocking = true,
118            unsigned pMaxRetry = kDefaultMaxRetryLock,
119            useconds_t pRetryInterval = kDefaultRetryLockInterval);
120
121  void unlock();
122
123  // Map the file content to the memory.
124  //
125  // One who gets non-null android::FileMap returned from this API is responsible
126  // for destroying it after the use.
127  android::FileMap *createMap(off_t pOffset, size_t pLength, bool pIsReadOnly);
128
129  size_t getSize();
130
131  off_t seek(off_t pOffset);
132  off_t tell();
133
134  inline bool hasError() const
135  { return (bool) mError; }
136
137  inline const std::error_code &getError() const
138  { return mError; }
139
140  // The return value of std::error_code::message() is obtained upon the call
141  // and is passed by value (that is, it's not a member of std::error_code.)
142  inline std::string getErrorMessage() const
143  { return mError.message(); }
144
145  inline const std::string &getName() const
146  { return mName; }
147
148  void close();
149
150  virtual ~FileBase();
151};
152
153} // end namespace bcc
154
155#endif  // BCC_SUPPORT_FILE_BASE_H
156