• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #import <CoreFoundation/CoreFoundation.h>
26 
ios_open_from_bundle(const char path[],const char * perm)27 static FILE* ios_open_from_bundle(const char path[], const char* perm) {
28     // Get a reference to the main bundle
29     CFBundleRef mainBundle = CFBundleGetMainBundle();
30 
31     // Get a reference to the file's URL
32     CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
33     CFURLRef imageURL = CFBundleCopyResourceURL(mainBundle, pathRef, NULL, NULL);
34     CFRelease(pathRef);
35     if (!imageURL) {
36         return nullptr;
37     }
38 
39     // Convert the URL reference into a string reference
40     CFStringRef imagePath = CFURLCopyFileSystemPath(imageURL, kCFURLPOSIXPathStyle);
41     CFRelease(imageURL);
42 
43     // Get the system encoding method
44     CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
45 
46     // Convert the string reference into a C string
47     const char *finalPath = CFStringGetCStringPtr(imagePath, encodingMethod);
48     FILE* fileHandle = fopen(finalPath, perm);
49     CFRelease(imagePath);
50     return fileHandle;
51 }
52 #endif
53 
54 
sk_fopen(const char path[],SkFILE_Flags flags)55 FILE* sk_fopen(const char path[], SkFILE_Flags flags) {
56     char    perm[4];
57     char*   p = perm;
58 
59     if (flags & kRead_SkFILE_Flag) {
60         *p++ = 'r';
61     }
62     if (flags & kWrite_SkFILE_Flag) {
63         *p++ = 'w';
64     }
65     *p++ = 'b';
66     *p = 0;
67 
68     //TODO: on Windows fopen is just ASCII or the current code page,
69     //convert to utf16 and use _wfopen
70     FILE* file = nullptr;
71 #ifdef SK_BUILD_FOR_IOS
72     // if read-only, try to open from bundle first
73     if (kRead_SkFILE_Flag == flags) {
74         file = ios_open_from_bundle(path, perm);
75     }
76     // otherwise just read from the Documents directory (default)
77     if (!file) {
78 #endif
79         file = fopen(path, perm);
80 #ifdef SK_BUILD_FOR_IOS
81     }
82 #endif
83     if (nullptr == file && (flags & kWrite_SkFILE_Flag)) {
84         SkDEBUGF(("sk_fopen: fopen(\"%s\", \"%s\") returned NULL (errno:%d): %s\n",
85                   path, perm, errno, strerror(errno)));
86     }
87     return file;
88 }
89 
sk_fgetsize(FILE * f)90 size_t sk_fgetsize(FILE* f) {
91     SkASSERT(f);
92 
93     long curr = ftell(f); // remember where we are
94     if (curr < 0) {
95         return 0;
96     }
97 
98     fseek(f, 0, SEEK_END); // go to the end
99     long size = ftell(f); // record the size
100     if (size < 0) {
101         size = 0;
102     }
103 
104     fseek(f, curr, SEEK_SET); // go back to our prev location
105     return size;
106 }
107 
sk_fwrite(const void * buffer,size_t byteCount,FILE * f)108 size_t sk_fwrite(const void* buffer, size_t byteCount, FILE* f) {
109     SkASSERT(f);
110     return fwrite(buffer, 1, byteCount, f);
111 }
112 
sk_fflush(FILE * f)113 void sk_fflush(FILE* f) {
114     SkASSERT(f);
115     fflush(f);
116 }
117 
sk_fsync(FILE * f)118 void sk_fsync(FILE* f) {
119 #if !defined(_WIN32) && !defined(SK_BUILD_FOR_ANDROID) && !defined(__UCLIBC__) \
120         && !defined(_NEWLIB_VERSION)
121     int fd = fileno(f);
122     fsync(fd);
123 #endif
124 }
125 
sk_ftell(FILE * f)126 size_t sk_ftell(FILE* f) {
127     long curr = ftell(f);
128     if (curr < 0) {
129         return 0;
130     }
131     return curr;
132 }
133 
sk_fclose(FILE * f)134 void sk_fclose(FILE* f) {
135     if (f) {
136         fclose(f);
137     }
138 }
139 
sk_isdir(const char * path)140 bool sk_isdir(const char *path) {
141     struct stat status;
142     if (0 != stat(path, &status)) {
143         return false;
144     }
145     return SkToBool(status.st_mode & S_IFDIR);
146 }
147 
sk_mkdir(const char * path)148 bool sk_mkdir(const char* path) {
149     if (sk_isdir(path)) {
150         return true;
151     }
152     if (sk_exists(path)) {
153         fprintf(stderr,
154                 "sk_mkdir: path '%s' already exists but is not a directory\n",
155                 path);
156         return false;
157     }
158 
159     int retval;
160 #ifdef _WIN32
161     retval = _mkdir(path);
162 #else
163     retval = mkdir(path, 0777);
164 #endif
165     if (0 == retval) {
166         return true;
167     } else {
168         fprintf(stderr, "sk_mkdir: error %d creating dir '%s'\n", errno, path);
169         return false;
170     }
171 }
172