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 20SkFILE* 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 38char* sk_fgets(char* str, int size, SkFILE* f) { 39 return ::fgets(str, size, (FILE *)f); 40} 41 42int sk_feof(SkFILE *f) { 43 // no :: namespace qualifier because it breaks android 44 return feof((FILE *)f); 45} 46 47size_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 65bool sk_frewind(SkFILE* f) { 66 SkASSERT(f); 67 ::rewind((FILE*)f); 68 return true; 69} 70 71size_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 91size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE* f) { 92 SkASSERT(f); 93 return ::fwrite(buffer, 1, byteCount, (FILE*)f); 94} 95 96void sk_fflush(SkFILE* f) { 97 SkASSERT(f); 98 ::fflush((FILE*)f); 99} 100 101bool sk_fseek(SkFILE* f, size_t byteCount) { 102 int err = ::fseek((FILE*)f, (long)byteCount, SEEK_SET); 103 return err == 0; 104} 105 106bool sk_fmove(SkFILE* f, long byteCount) { 107 int err = ::fseek((FILE*)f, byteCount, SEEK_CUR); 108 return err == 0; 109} 110 111size_t sk_ftell(SkFILE* f) { 112 long curr = ::ftell((FILE*)f); 113 if (curr < 0) { 114 return 0; 115 } 116 return curr; 117} 118 119void sk_fclose(SkFILE* f) { 120 SkASSERT(f); 121 ::fclose((FILE*)f); 122} 123 124bool 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 132bool 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