1 /*
2  * Copyright (C) 2008 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 ART_RUNTIME_BASE_UNIX_FILE_MAPPED_FILE_H_
18 #define ART_RUNTIME_BASE_UNIX_FILE_MAPPED_FILE_H_
19 
20 #include <fcntl.h>
21 #include <string>
22 #include "base/unix_file/fd_file.h"
23 
24 namespace unix_file {
25 
26 // Random access file which handles an mmap(2), munmap(2) pair in C++
27 // RAII style. When a file is mmapped, the random access file
28 // interface accesses the mmapped memory directly; otherwise, the
29 // standard file I/O is used. Whenever a function fails, it returns
30 // false and errno is set to the corresponding error code.
31 class MappedFile : public FdFile {
32  public:
33   // File modes used in Open().
34   enum FileMode {
35 #ifdef __linux__
36     kReadOnlyMode = O_RDONLY | O_LARGEFILE,
37     kReadWriteMode = O_CREAT | O_RDWR | O_LARGEFILE,
38 #else
39     kReadOnlyMode = O_RDONLY,
40     kReadWriteMode = O_CREAT | O_RDWR,
41 #endif
42   };
43 
MappedFile()44   MappedFile() : FdFile(), file_size_(-1), mapped_file_(NULL), map_mode_(kMapReadOnly) {
45   }
46   // Creates a MappedFile using the given file descriptor. Takes ownership of
47   // the file descriptor.
MappedFile(int fd,bool check_usage)48   explicit MappedFile(int fd, bool check_usage) : FdFile(fd, check_usage), file_size_(-1),
49       mapped_file_(NULL), map_mode_(kMapReadOnly) {
50   }
51 
52   // Unmaps and closes the file if needed.
53   virtual ~MappedFile();
54 
55   // Maps an opened file to memory in the read-only mode.
56   bool MapReadOnly();
57 
58   // Maps an opened file to memory in the read-write mode. Before the
59   // file is mapped, it is truncated to 'file_size' bytes.
60   bool MapReadWrite(int64_t file_size);
61 
62   // Unmaps a mapped file so that, e.g., SetLength() may be invoked.
63   bool Unmap();
64 
65   // RandomAccessFile API.
66   // The functions below require that the file is open, but it doesn't
67   // have to be mapped.
68   virtual int Close();
69   virtual int64_t Read(char* buf, int64_t byte_count, int64_t offset) const;
70   // SetLength() requires that the file is not mmapped.
71   virtual int SetLength(int64_t new_length);
72   virtual int64_t GetLength() const;
73   virtual int Flush();
74   // Write() requires that, if the file is mmapped, it is mmapped in
75   // the read-write mode. Writes past the end of file are discarded.
76   virtual int64_t Write(const char* buf, int64_t byte_count, int64_t offset);
77 
78   // A convenience method equivalent to GetLength().
79   int64_t size() const;
80 
81   // Returns true if the file has been mmapped.
82   bool IsMapped() const;
83 
84   // Returns a pointer to the start of the memory mapping once the
85   // file is successfully mapped; crashes otherwise.
86   char* data() const;
87 
88  private:
89   enum MapMode {
90     kMapReadOnly = 1,
91     kMapReadWrite = 2,
92   };
93 
94   mutable int64_t file_size_;  // May be updated in GetLength().
95   void* mapped_file_;
96   MapMode map_mode_;
97 
98   DISALLOW_COPY_AND_ASSIGN(MappedFile);
99 };
100 
101 }  // namespace unix_file
102 
103 #endif  // ART_RUNTIME_BASE_UNIX_FILE_MAPPED_FILE_H_
104