1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "SkMMapStream.h"
9
10 #include <unistd.h>
11 #include <sys/mman.h>
12 #include <fcntl.h>
13 #include <errno.h>
14
SkMMAPStream(const char filename[])15 SkMMAPStream::SkMMAPStream(const char filename[])
16 {
17 fAddr = NULL; // initialize to failure case
18
19 int fildes = open(filename, O_RDONLY);
20 if (fildes < 0)
21 {
22 SkDEBUGF(("---- failed to open(%s) for mmap stream error=%d\n", filename, errno));
23 return;
24 }
25
26 off_t offset = lseek(fildes, 0, SEEK_END); // find the file size
27 if (offset == -1)
28 {
29 SkDEBUGF(("---- failed to lseek(%s) for mmap stream error=%d\n", filename, errno));
30 close(fildes);
31 return;
32 }
33 (void)lseek(fildes, 0, SEEK_SET); // restore file offset to beginning
34
35 // to avoid a 64bit->32bit warning, I explicitly create a size_t size
36 size_t size = static_cast<size_t>(offset);
37
38 void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fildes, 0);
39
40 // According to the POSIX documentation of mmap it adds an extra reference
41 // to the file associated with the fildes which is not removed by a
42 // subsequent close() on that fildes. This reference is removed when there
43 // are no more mappings to the file.
44 close(fildes);
45
46 if (MAP_FAILED == addr)
47 {
48 SkDEBUGF(("---- failed to mmap(%s) for mmap stream error=%d\n", filename, errno));
49 return;
50 }
51
52 this->INHERITED::setMemory(addr, size);
53
54 fAddr = addr;
55 fSize = size;
56 }
57
~SkMMAPStream()58 SkMMAPStream::~SkMMAPStream()
59 {
60 this->closeMMap();
61 }
62
setMemory(const void * data,size_t length,bool copyData)63 void SkMMAPStream::setMemory(const void* data, size_t length, bool copyData)
64 {
65 this->closeMMap();
66 this->INHERITED::setMemory(data, length, copyData);
67 }
68
closeMMap()69 void SkMMAPStream::closeMMap()
70 {
71 if (fAddr)
72 {
73 munmap(fAddr, fSize);
74 fAddr = NULL;
75 }
76 }
77
78