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