14f94c520f8d699a5973956a1716272146be17128Zonr Chang/*
24f94c520f8d699a5973956a1716272146be17128Zonr Chang * Copyright 2012, The Android Open Source Project
34f94c520f8d699a5973956a1716272146be17128Zonr Chang *
44f94c520f8d699a5973956a1716272146be17128Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
54f94c520f8d699a5973956a1716272146be17128Zonr Chang * you may not use this file except in compliance with the License.
64f94c520f8d699a5973956a1716272146be17128Zonr Chang * You may obtain a copy of the License at
74f94c520f8d699a5973956a1716272146be17128Zonr Chang *
84f94c520f8d699a5973956a1716272146be17128Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
94f94c520f8d699a5973956a1716272146be17128Zonr Chang *
104f94c520f8d699a5973956a1716272146be17128Zonr Chang * Unless required by applicable law or agreed to in writing, software
114f94c520f8d699a5973956a1716272146be17128Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
124f94c520f8d699a5973956a1716272146be17128Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f94c520f8d699a5973956a1716272146be17128Zonr Chang * See the License for the specific language governing permissions and
144f94c520f8d699a5973956a1716272146be17128Zonr Chang * limitations under the License.
154f94c520f8d699a5973956a1716272146be17128Zonr Chang */
164f94c520f8d699a5973956a1716272146be17128Zonr Chang
17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#ifndef BCC_SUPPORT_FILE_BASE_H
18c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#define BCC_SUPPORT_FILE_BASE_H
194f94c520f8d699a5973956a1716272146be17128Zonr Chang
204f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <fcntl.h>
214f94c520f8d699a5973956a1716272146be17128Zonr Chang
224f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <string>
234f94c520f8d699a5973956a1716272146be17128Zonr Chang
244f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <llvm/Support/system_error.h>
254f94c520f8d699a5973956a1716272146be17128Zonr Chang
264f94c520f8d699a5973956a1716272146be17128Zonr Changnamespace android {
274f94c520f8d699a5973956a1716272146be17128Zonr Chang  class FileMap;
284f94c520f8d699a5973956a1716272146be17128Zonr Chang}
294f94c520f8d699a5973956a1716272146be17128Zonr Chang
304f94c520f8d699a5973956a1716272146be17128Zonr Changnamespace bcc {
314f94c520f8d699a5973956a1716272146be17128Zonr Chang
324f94c520f8d699a5973956a1716272146be17128Zonr Changclass FileBase {
334f94c520f8d699a5973956a1716272146be17128Zonr Changpublic:
344f94c520f8d699a5973956a1716272146be17128Zonr Chang  enum OpenModeEnum {
354f94c520f8d699a5973956a1716272146be17128Zonr Chang    kReadMode       = 1 << 0,
364f94c520f8d699a5973956a1716272146be17128Zonr Chang    kWriteMode      = 1 << 1,
374f94c520f8d699a5973956a1716272146be17128Zonr Chang    kReadWriteMode  = (kReadMode | kWriteMode),
384f94c520f8d699a5973956a1716272146be17128Zonr Chang  };
394f94c520f8d699a5973956a1716272146be17128Zonr Chang
404f94c520f8d699a5973956a1716272146be17128Zonr Chang  enum FlagEnum {
414f94c520f8d699a5973956a1716272146be17128Zonr Chang    kBinary = 1 << 0,
42c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao    kTruncate = 1 << 1,
43b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao    kAppend = 1 << 2,
44331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    kDeleteOnClose = 1 << 3
454f94c520f8d699a5973956a1716272146be17128Zonr Chang  };
464f94c520f8d699a5973956a1716272146be17128Zonr Chang
474f94c520f8d699a5973956a1716272146be17128Zonr Chang  enum LockModeEnum {
484f94c520f8d699a5973956a1716272146be17128Zonr Chang    // The shared resource behind the Stream locked in ReadLock mode can be
494f94c520f8d699a5973956a1716272146be17128Zonr Chang    // locked by other processes at the same time.
504f94c520f8d699a5973956a1716272146be17128Zonr Chang    kReadLock,
514f94c520f8d699a5973956a1716272146be17128Zonr Chang
524f94c520f8d699a5973956a1716272146be17128Zonr Chang    // The shared resource behind the Stream locked in WriteLock mode can only
534f94c520f8d699a5973956a1716272146be17128Zonr Chang    // be locked by one process. It's exclusive. That is, the shared resource
544f94c520f8d699a5973956a1716272146be17128Zonr Chang    // cannot have both ReadLock and WriteLock simultaneously.
554f94c520f8d699a5973956a1716272146be17128Zonr Chang    kWriteLock
564f94c520f8d699a5973956a1716272146be17128Zonr Chang  };
574f94c520f8d699a5973956a1716272146be17128Zonr Chang
584f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Default configuration to the lock().
594f94c520f8d699a5973956a1716272146be17128Zonr Chang  enum {
604f94c520f8d699a5973956a1716272146be17128Zonr Chang    kDefaultMaxRetryLock = 4,
614f94c520f8d699a5973956a1716272146be17128Zonr Chang    kDefaultRetryLockInterval = 200000UL,
624f94c520f8d699a5973956a1716272146be17128Zonr Chang  };
634f94c520f8d699a5973956a1716272146be17128Zonr Chang
644f94c520f8d699a5973956a1716272146be17128Zonr Changprotected:
654f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Grant direct access of the internal file descriptor to the sub-class and
664f94c520f8d699a5973956a1716272146be17128Zonr Chang  // error message such that they can implement their own I/O functionality.
674f94c520f8d699a5973956a1716272146be17128Zonr Chang  int mFD;
684f94c520f8d699a5973956a1716272146be17128Zonr Chang
694f94c520f8d699a5973956a1716272146be17128Zonr Chang  llvm::error_code mError;
704f94c520f8d699a5973956a1716272146be17128Zonr Chang
714f94c520f8d699a5973956a1716272146be17128Zonr Changprivate:
724f94c520f8d699a5973956a1716272146be17128Zonr Chang  std::string mName;
734f94c520f8d699a5973956a1716272146be17128Zonr Chang
744f94c520f8d699a5973956a1716272146be17128Zonr Chang  // The 2nd argument to the POSIX open().
754f94c520f8d699a5973956a1716272146be17128Zonr Chang  unsigned mOpenFlags;
764f94c520f8d699a5973956a1716272146be17128Zonr Chang
774f94c520f8d699a5973956a1716272146be17128Zonr Chang  // True true if we should call unlock() in destructor.
784f94c520f8d699a5973956a1716272146be17128Zonr Chang  bool mShouldUnlock;
794f94c520f8d699a5973956a1716272146be17128Zonr Chang
80331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // True if file should be deleted in destructor.
81331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  bool mShouldDelete;
82331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
834f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Open mName with flag mOpenFlags (using POSIX open().)
844f94c520f8d699a5973956a1716272146be17128Zonr Chang  bool open();
854f94c520f8d699a5973956a1716272146be17128Zonr Chang
864f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Return true if mFD is the corresponded file descriptor to the file named
874f94c520f8d699a5973956a1716272146be17128Zonr Chang  // mName on the filesystem. This check may returns failed, for example,
884f94c520f8d699a5973956a1716272146be17128Zonr Chang  // someone re-create the file with the same name after we openning the file.
894f94c520f8d699a5973956a1716272146be17128Zonr Chang  bool checkFileIntegrity();
904f94c520f8d699a5973956a1716272146be17128Zonr Chang
914f94c520f8d699a5973956a1716272146be17128Zonr Chang  inline bool reopen() {
924f94c520f8d699a5973956a1716272146be17128Zonr Chang    // It's a private method, and all its callers are the few that can invoke it.
934f94c520f8d699a5973956a1716272146be17128Zonr Chang    // That is, the pre-condition will be checked by the caller. Therefore, we don't
944f94c520f8d699a5973956a1716272146be17128Zonr Chang    // need to check it again in reopen().
954f94c520f8d699a5973956a1716272146be17128Zonr Chang    close();
964f94c520f8d699a5973956a1716272146be17128Zonr Chang    return open();
974f94c520f8d699a5973956a1716272146be17128Zonr Chang  }
984f94c520f8d699a5973956a1716272146be17128Zonr Chang
994f94c520f8d699a5973956a1716272146be17128Zonr Changprivate:
1004f94c520f8d699a5973956a1716272146be17128Zonr Chang  FileBase(FileBase &); // Do not implement.
1014f94c520f8d699a5973956a1716272146be17128Zonr Chang  void operator=(const FileBase &); // Do not implement.
1024f94c520f8d699a5973956a1716272146be17128Zonr Chang
1034f94c520f8d699a5973956a1716272146be17128Zonr Changprotected:
1044f94c520f8d699a5973956a1716272146be17128Zonr Chang  // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to
1054f94c520f8d699a5973956a1716272146be17128Zonr Chang  // FileBase. It's a bit set composed by the value defined in
1064f94c520f8d699a5973956a1716272146be17128Zonr Chang  // FileBase::FlagEnum.
1074f94c520f8d699a5973956a1716272146be17128Zonr Chang  FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags);
1084f94c520f8d699a5973956a1716272146be17128Zonr Chang
1094f94c520f8d699a5973956a1716272146be17128Zonr Chang  void detectError();
1104f94c520f8d699a5973956a1716272146be17128Zonr Chang
1114f94c520f8d699a5973956a1716272146be17128Zonr Changpublic:
1124f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Lock the file descriptor in given pMode. If pNonblocking is true, the lock
1134f94c520f8d699a5973956a1716272146be17128Zonr Chang  // request issued will return immediately when the shared resource is locked.
1144f94c520f8d699a5973956a1716272146be17128Zonr Chang  // In this case, it retries pMaxRetry times, each wait pRetryInterval (in
1154f94c520f8d699a5973956a1716272146be17128Zonr Chang  // usecs) before the previous retry getting done.
1164f94c520f8d699a5973956a1716272146be17128Zonr Chang  //
1174f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Only file is allowed to use this API.
1184f94c520f8d699a5973956a1716272146be17128Zonr Chang  bool lock(enum LockModeEnum pMode, bool pNonblocking = true,
1194f94c520f8d699a5973956a1716272146be17128Zonr Chang            unsigned pMaxRetry = kDefaultMaxRetryLock,
1204f94c520f8d699a5973956a1716272146be17128Zonr Chang            useconds_t pRetryInterval = kDefaultRetryLockInterval);
1214f94c520f8d699a5973956a1716272146be17128Zonr Chang
1224f94c520f8d699a5973956a1716272146be17128Zonr Chang  void unlock();
1234f94c520f8d699a5973956a1716272146be17128Zonr Chang
1244f94c520f8d699a5973956a1716272146be17128Zonr Chang  // Map the file content to the memory.
1254f94c520f8d699a5973956a1716272146be17128Zonr Chang  //
1264f94c520f8d699a5973956a1716272146be17128Zonr Chang  // One who gets non-null android::FileMap returned from this API is responsible
1274f94c520f8d699a5973956a1716272146be17128Zonr Chang  // for destroying it after the use.
1284f94c520f8d699a5973956a1716272146be17128Zonr Chang  android::FileMap *createMap(off_t pOffset, size_t pLength, bool pIsReadOnly);
1294f94c520f8d699a5973956a1716272146be17128Zonr Chang
1304f94c520f8d699a5973956a1716272146be17128Zonr Chang  size_t getSize();
1314f94c520f8d699a5973956a1716272146be17128Zonr Chang
1324f94c520f8d699a5973956a1716272146be17128Zonr Chang  off_t seek(off_t pOffset);
1334f94c520f8d699a5973956a1716272146be17128Zonr Chang  off_t tell();
1344f94c520f8d699a5973956a1716272146be17128Zonr Chang
1354f94c520f8d699a5973956a1716272146be17128Zonr Chang  inline bool hasError() const
1364f94c520f8d699a5973956a1716272146be17128Zonr Chang  { return (mError.value() != llvm::errc::success); }
1374f94c520f8d699a5973956a1716272146be17128Zonr Chang
1384f94c520f8d699a5973956a1716272146be17128Zonr Chang  inline const llvm::error_code &getError() const
1394f94c520f8d699a5973956a1716272146be17128Zonr Chang  { return mError; }
1404f94c520f8d699a5973956a1716272146be17128Zonr Chang
1414f94c520f8d699a5973956a1716272146be17128Zonr Chang  // The return value of llvm::error_code::message() is obtained upon the call
1424f94c520f8d699a5973956a1716272146be17128Zonr Chang  // and is passed by value (that is, it's not a member of llvm::error_code.)
1434f94c520f8d699a5973956a1716272146be17128Zonr Chang  inline std::string getErrorMessage() const
1444f94c520f8d699a5973956a1716272146be17128Zonr Chang  { return mError.message(); }
1454f94c520f8d699a5973956a1716272146be17128Zonr Chang
1464f94c520f8d699a5973956a1716272146be17128Zonr Chang  inline const std::string &getName() const
1474f94c520f8d699a5973956a1716272146be17128Zonr Chang  { return mName; }
1484f94c520f8d699a5973956a1716272146be17128Zonr Chang
1494f94c520f8d699a5973956a1716272146be17128Zonr Chang  void close();
1504f94c520f8d699a5973956a1716272146be17128Zonr Chang
1514f94c520f8d699a5973956a1716272146be17128Zonr Chang  virtual ~FileBase();
1524f94c520f8d699a5973956a1716272146be17128Zonr Chang};
1534f94c520f8d699a5973956a1716272146be17128Zonr Chang
1544f94c520f8d699a5973956a1716272146be17128Zonr Chang} // end namespace bcc
1554f94c520f8d699a5973956a1716272146be17128Zonr Chang
156c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#endif  // BCC_SUPPORT_FILE_BASE_H
157