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 10 #include <errno.h> 11 #include <stdio.h> 12 #include <sys/stat.h> 13 #include <sys/types.h> 14 15 #ifdef _WIN32 16 #include <direct.h> 17 #include <io.h> 18 #endif 19 20 SkFILE* sk_fopen(const char path[], SkFILE_Flags flags) { 21 char perm[4]; 22 char* p = perm; 23 24 if (flags & kRead_SkFILE_Flag) { 25 *p++ = 'r'; 26 } 27 if (flags & kWrite_SkFILE_Flag) { 28 *p++ = 'w'; 29 } 30 *p++ = 'b'; 31 *p = 0; 32 33 //TODO: on Windows fopen is just ASCII or the current code page, 34 //convert to utf16 and use _wfopen 35 return (SkFILE*)::fopen(path, perm); 36 } 37 38 char* sk_fgets(char* str, int size, SkFILE* f) { 39 return ::fgets(str, size, (FILE *)f); 40 } 41 42 int sk_feof(SkFILE *f) { 43 // no :: namespace qualifier because it breaks android 44 return feof((FILE *)f); 45 } 46 47 size_t sk_fgetsize(SkFILE* f) { 48 SkASSERT(f); 49 50 long curr = ::ftell((FILE*)f); // remember where we are 51 if (curr < 0) { 52 return 0; 53 } 54 55 ::fseek((FILE*)f, 0, SEEK_END); // go to the end 56 long size = ::ftell((FILE*)f); // record the size 57 if (size < 0) { 58 size = 0; 59 } 60 61 ::fseek((FILE*)f, curr, SEEK_SET); // go back to our prev location 62 return size; 63 } 64 65 bool sk_frewind(SkFILE* f) { 66 SkASSERT(f); 67 ::rewind((FILE*)f); 68 return true; 69 } 70 71 size_t sk_fread(void* buffer, size_t byteCount, SkFILE* f) { 72 SkASSERT(f); 73 if (buffer == NULL) { 74 size_t curr = ::ftell((FILE*)f); 75 if ((long)curr == -1) { 76 SkDEBUGF(("sk_fread: ftell(%p) returned -1 feof:%d ferror:%d\n", f, feof((FILE*)f), ferror((FILE*)f))); 77 return 0; 78 } 79 int err = ::fseek((FILE*)f, (long)byteCount, SEEK_CUR); 80 if (err != 0) { 81 SkDEBUGF(("sk_fread: fseek(%d) tell:%d failed with feof:%d ferror:%d returned:%d\n", 82 byteCount, curr, feof((FILE*)f), ferror((FILE*)f), err)); 83 return 0; 84 } 85 return byteCount; 86 } 87 else 88 return ::fread(buffer, 1, byteCount, (FILE*)f); 89 } 90 91 size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE* f) { 92 SkASSERT(f); 93 return ::fwrite(buffer, 1, byteCount, (FILE*)f); 94 } 95 96 void sk_fflush(SkFILE* f) { 97 SkASSERT(f); 98 ::fflush((FILE*)f); 99 } 100 101 bool sk_fseek(SkFILE* f, size_t byteCount) { 102 int err = ::fseek((FILE*)f, (long)byteCount, SEEK_SET); 103 return err == 0; 104 } 105 106 bool sk_fmove(SkFILE* f, long byteCount) { 107 int err = ::fseek((FILE*)f, byteCount, SEEK_CUR); 108 return err == 0; 109 } 110 111 size_t sk_ftell(SkFILE* f) { 112 long curr = ::ftell((FILE*)f); 113 if (curr < 0) { 114 return 0; 115 } 116 return curr; 117 } 118 119 void sk_fclose(SkFILE* f) { 120 SkASSERT(f); 121 ::fclose((FILE*)f); 122 } 123 124 bool sk_isdir(const char *path) { 125 struct stat status; 126 if (0 != stat(path, &status)) { 127 return false; 128 } 129 return SkToBool(status.st_mode & S_IFDIR); 130 } 131 132 bool sk_mkdir(const char* path) { 133 if (sk_isdir(path)) { 134 return true; 135 } 136 if (sk_exists(path)) { 137 fprintf(stderr, 138 "sk_mkdir: path '%s' already exists but is not a directory\n", 139 path); 140 return false; 141 } 142 143 int retval; 144 #ifdef _WIN32 145 retval = _mkdir(path); 146 #else 147 retval = mkdir(path, 0777); 148 #endif 149 if (0 == retval) { 150 return true; 151 } else { 152 fprintf(stderr, "sk_mkdir: error %d creating dir '%s'\n", errno, path); 153 return false; 154 } 155 } 156