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