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