LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/ports - SkOSFile_posix.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 110 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "SkOSFile.h"
       9             : #include "SkString.h"
      10             : #include "SkTFitsIn.h"
      11             : #include "SkTemplates.h"
      12             : #include "SkTypes.h"
      13             : 
      14             : #include <dirent.h>
      15             : #include <stdio.h>
      16             : #include <string.h>
      17             : #include <sys/mman.h>
      18             : #include <sys/stat.h>
      19             : #include <sys/types.h>
      20             : #include <unistd.h>
      21             : 
      22           0 : size_t sk_fgetsize(FILE* f) {
      23           0 :     int fd = fileno(f);
      24           0 :     if (fd < 0) {
      25           0 :         return 0;
      26             :     }
      27             : 
      28             :     struct stat status;
      29           0 :     if (0 != fstat(fd, &status)) {
      30           0 :         return 0;
      31             :     }
      32           0 :     if (!S_ISREG(status.st_mode)) {
      33           0 :         return 0;
      34             :     }
      35           0 :     if (!SkTFitsIn<size_t>(status.st_size)) {
      36           0 :         return 0;
      37             :     }
      38           0 :     return static_cast<size_t>(status.st_size);
      39             : }
      40             : 
      41           0 : bool sk_exists(const char *path, SkFILE_Flags flags) {
      42           0 :     int mode = F_OK;
      43           0 :     if (flags & kRead_SkFILE_Flag) {
      44           0 :         mode |= R_OK;
      45             :     }
      46           0 :     if (flags & kWrite_SkFILE_Flag) {
      47           0 :         mode |= W_OK;
      48             :     }
      49           0 :     return (0 == access(path, mode));
      50             : }
      51             : 
      52             : typedef struct {
      53             :     dev_t dev;
      54             :     ino_t ino;
      55             : } SkFILEID;
      56             : 
      57           0 : static bool sk_ino(FILE* a, SkFILEID* id) {
      58           0 :     int fd = fileno(a);
      59           0 :     if (fd < 0) {
      60           0 :         return 0;
      61             :     }
      62             :     struct stat status;
      63           0 :     if (0 != fstat(fd, &status)) {
      64           0 :         return 0;
      65             :     }
      66           0 :     id->dev = status.st_dev;
      67           0 :     id->ino = status.st_ino;
      68           0 :     return true;
      69             : }
      70             : 
      71           0 : bool sk_fidentical(FILE* a, FILE* b) {
      72             :     SkFILEID aID, bID;
      73           0 :     return sk_ino(a, &aID) && sk_ino(b, &bID)
      74           0 :            && aID.ino == bID.ino
      75           0 :            && aID.dev == bID.dev;
      76             : }
      77             : 
      78           0 : void sk_fmunmap(const void* addr, size_t length) {
      79           0 :     munmap(const_cast<void*>(addr), length);
      80           0 : }
      81             : 
      82           0 : void* sk_fdmmap(int fd, size_t* size) {
      83             :     struct stat status;
      84           0 :     if (0 != fstat(fd, &status)) {
      85           0 :         return nullptr;
      86             :     }
      87           0 :     if (!S_ISREG(status.st_mode)) {
      88           0 :         return nullptr;
      89             :     }
      90           0 :     if (!SkTFitsIn<size_t>(status.st_size)) {
      91           0 :         return nullptr;
      92             :     }
      93           0 :     size_t fileSize = static_cast<size_t>(status.st_size);
      94             : 
      95           0 :     void* addr = mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd, 0);
      96           0 :     if (MAP_FAILED == addr) {
      97           0 :         return nullptr;
      98             :     }
      99             : 
     100           0 :     *size = fileSize;
     101           0 :     return addr;
     102             : }
     103             : 
     104           0 : int sk_fileno(FILE* f) {
     105           0 :     return fileno(f);
     106             : }
     107             : 
     108           0 : void* sk_fmmap(FILE* f, size_t* size) {
     109           0 :     int fd = sk_fileno(f);
     110           0 :     if (fd < 0) {
     111           0 :         return nullptr;
     112             :     }
     113             : 
     114           0 :     return sk_fdmmap(fd, size);
     115             : }
     116             : 
     117           0 : size_t sk_qread(FILE* file, void* buffer, size_t count, size_t offset) {
     118           0 :     int fd = sk_fileno(file);
     119           0 :     if (fd < 0) {
     120           0 :         return SIZE_MAX;
     121             :     }
     122           0 :     ssize_t bytesRead = pread(fd, buffer, count, offset);
     123           0 :     if (bytesRead < 0) {
     124           0 :         return SIZE_MAX;
     125             :     }
     126           0 :     return bytesRead;
     127             : }
     128             : 
     129             : ////////////////////////////////////////////////////////////////////////////
     130             : 
     131           0 : struct SkOSFileIterData {
     132           0 :     SkOSFileIterData() : fDIR(0) { }
     133             :     DIR* fDIR;
     134             :     SkString fPath, fSuffix;
     135             : };
     136             : static_assert(sizeof(SkOSFileIterData) <= SkOSFile::Iter::kStorageSize, "not_enough_space");
     137             : 
     138           0 : SkOSFile::Iter::Iter() { new (fSelf.get()) SkOSFileIterData; }
     139             : 
     140           0 : SkOSFile::Iter::Iter(const char path[], const char suffix[]) {
     141           0 :     new (fSelf.get()) SkOSFileIterData;
     142           0 :     this->reset(path, suffix);
     143           0 : }
     144             : 
     145           0 : SkOSFile::Iter::~Iter() {
     146           0 :     SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
     147           0 :     if (self.fDIR) {
     148           0 :         ::closedir(self.fDIR);
     149             :     }
     150           0 :     self.~SkOSFileIterData();
     151           0 : }
     152             : 
     153           0 : void SkOSFile::Iter::reset(const char path[], const char suffix[]) {
     154           0 :     SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
     155           0 :     if (self.fDIR) {
     156           0 :         ::closedir(self.fDIR);
     157           0 :         self.fDIR = 0;
     158             :     }
     159             : 
     160           0 :     self.fPath.set(path);
     161           0 :     if (path) {
     162           0 :         self.fDIR = ::opendir(path);
     163           0 :         self.fSuffix.set(suffix);
     164             :     } else {
     165           0 :         self.fSuffix.reset();
     166             :     }
     167           0 : }
     168             : 
     169             : // returns true if suffix is empty, or if str ends with suffix
     170           0 : static bool issuffixfor(const SkString& suffix, const char str[]) {
     171           0 :     size_t  suffixLen = suffix.size();
     172           0 :     size_t  strLen = strlen(str);
     173             : 
     174           0 :     return  strLen >= suffixLen &&
     175           0 :             memcmp(suffix.c_str(), str + strLen - suffixLen, suffixLen) == 0;
     176             : }
     177             : 
     178           0 : bool SkOSFile::Iter::next(SkString* name, bool getDir) {
     179           0 :     SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
     180           0 :     if (self.fDIR) {
     181             :         dirent* entry;
     182             : 
     183           0 :         while ((entry = ::readdir(self.fDIR)) != nullptr) {
     184             :             struct stat s;
     185           0 :             SkString str(self.fPath);
     186             : 
     187           0 :             if (!str.endsWith("/") && !str.endsWith("\\")) {
     188           0 :                 str.append("/");
     189             :             }
     190           0 :             str.append(entry->d_name);
     191             : 
     192           0 :             if (0 == stat(str.c_str(), &s)) {
     193           0 :                 if (getDir) {
     194           0 :                     if (s.st_mode & S_IFDIR) {
     195           0 :                         break;
     196             :                     }
     197             :                 } else {
     198           0 :                     if (!(s.st_mode & S_IFDIR) && issuffixfor(self.fSuffix, entry->d_name)) {
     199           0 :                         break;
     200             :                     }
     201             :                 }
     202             :             }
     203             :         }
     204           0 :         if (entry) { // we broke out with a file
     205           0 :             if (name) {
     206           0 :                 name->set(entry->d_name);
     207             :             }
     208           0 :             return true;
     209             :         }
     210             :     }
     211           0 :     return false;
     212             : }

Generated by: LCOV version 1.13