Home | History | Annotate | Download | only in ports
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      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 "SkTypes.h"
     10 
     11 #include <errno.h>
     12 #include <stdio.h>
     13 #include <sys/stat.h>
     14 
     15 #ifdef SK_BUILD_FOR_UNIX
     16 #include <unistd.h>
     17 #endif
     18 
     19 #ifdef _WIN32
     20 #include <direct.h>
     21 #include <io.h>
     22 #endif
     23 
     24 #ifdef SK_BUILD_FOR_IOS
     25 #include "SkOSFile_ios.h"
     26 #endif
     27 
     28 FILE* sk_fopen(const char path[], SkFILE_Flags flags) {
     29     char    perm[4];
     30     char*   p = perm;
     31 
     32     if (flags & kRead_SkFILE_Flag) {
     33         *p++ = 'r';
     34     }
     35     if (flags & kWrite_SkFILE_Flag) {
     36         *p++ = 'w';
     37     }
     38     *p++ = 'b';
     39     *p = 0;
     40 
     41     //TODO: on Windows fopen is just ASCII or the current code page,
     42     //convert to utf16 and use _wfopen
     43     FILE* file = nullptr;
     44     file = fopen(path, perm);
     45 #ifdef SK_BUILD_FOR_IOS
     46     // if not found in default path and read-only, try to open from bundle
     47     if (!file && kRead_SkFILE_Flag == flags) {
     48         SkString bundlePath;
     49         if (ios_get_path_in_bundle(path, &bundlePath)) {
     50             file = fopen(bundlePath.c_str(), perm);
     51         }
     52     }
     53 #endif
     54 
     55     if (nullptr == file && (flags & kWrite_SkFILE_Flag)) {
     56         SkDEBUGF(("sk_fopen: fopen(\"%s\", \"%s\") returned nullptr (errno:%d): %s\n",
     57                   path, perm, errno, strerror(errno)));
     58     }
     59     return file;
     60 }
     61 
     62 size_t sk_fgetsize(FILE* f) {
     63     SkASSERT(f);
     64 
     65     long curr = ftell(f); // remember where we are
     66     if (curr < 0) {
     67         return 0;
     68     }
     69 
     70     fseek(f, 0, SEEK_END); // go to the end
     71     long size = ftell(f); // record the size
     72     if (size < 0) {
     73         size = 0;
     74     }
     75 
     76     fseek(f, curr, SEEK_SET); // go back to our prev location
     77     return size;
     78 }
     79 
     80 size_t sk_fwrite(const void* buffer, size_t byteCount, FILE* f) {
     81     SkASSERT(f);
     82     return fwrite(buffer, 1, byteCount, f);
     83 }
     84 
     85 void sk_fflush(FILE* f) {
     86     SkASSERT(f);
     87     fflush(f);
     88 }
     89 
     90 void sk_fsync(FILE* f) {
     91 #if !defined(_WIN32) && !defined(SK_BUILD_FOR_ANDROID) && !defined(__UCLIBC__) \
     92         && !defined(_NEWLIB_VERSION)
     93     int fd = fileno(f);
     94     fsync(fd);
     95 #endif
     96 }
     97 
     98 size_t sk_ftell(FILE* f) {
     99     long curr = ftell(f);
    100     if (curr < 0) {
    101         return 0;
    102     }
    103     return curr;
    104 }
    105 
    106 void sk_fclose(FILE* f) {
    107     if (f) {
    108         fclose(f);
    109     }
    110 }
    111 
    112 bool sk_isdir(const char *path) {
    113     struct stat status;
    114     if (0 != stat(path, &status)) {
    115 #ifdef SK_BUILD_FOR_IOS
    116         // check the bundle directory if not in default path
    117         SkString bundlePath;
    118         if (ios_get_path_in_bundle(path, &bundlePath)) {
    119             if (0 != stat(bundlePath.c_str(), &status)) {
    120                 return false;
    121             }
    122         }
    123 #else
    124         return false;
    125 #endif
    126     }
    127     return SkToBool(status.st_mode & S_IFDIR);
    128 }
    129 
    130 bool sk_mkdir(const char* path) {
    131     if (sk_isdir(path)) {
    132         return true;
    133     }
    134     if (sk_exists(path)) {
    135         fprintf(stderr,
    136                 "sk_mkdir: path '%s' already exists but is not a directory\n",
    137                 path);
    138         return false;
    139     }
    140 
    141     int retval;
    142 #ifdef _WIN32
    143     retval = _mkdir(path);
    144 #else
    145     retval = mkdir(path, 0777);
    146 #endif
    147     return 0 == retval;
    148 }
    149