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