source: cpp/common/nonstd_stdio.cpp @ 371

Last change on this file since 371 was 297, checked in by Maciej Komosinski, 10 years ago

Updated for function name change

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "nonstd_stdio.h"
6#include "nonstd.h"
7#include "Convert.h" //utf8ToUtf16()
8#include <common/stl-util.h>
9
10#ifdef _WIN32
11#include "Shlwapi.h" //PathIsRelative()
12#ifdef __BORLANDC__
13#pragma link "Shlwapi.lib" //PathIsRelative()
14#endif
15#include <sys/stat.h> //_stat
16#else
17#include <unistd.h>
18#endif
19
20bool fileExists(const char* path)
21{
22        //lepiej gdyby uzywalo stat bo mfopen mogloby cos niepotrzebnie wczytywac przy otwarciu pliku ale mfopen wiadomo ze zadziala wszedzie tak samo
23#ifdef _WIN32
24        MFILE *f = mfopen(Convert::utf8ToUtf16(path).c_str(), Convert::strTOwstr(FOPEN_READ_BINARY).c_str());
25#else
26        MFILE *f = mfopen(path, FOPEN_READ_BINARY);
27#endif
28        if (f == NULL) return false;
29        mfclose(f);
30        return true;
31}
32
33#ifdef _WIN32
34bool isDirWritable(const char* path) //dir must not end with '\'
35{
36        wstring dir = Convert::utf8ToUtf16(path);
37        CreateDirectoryW(dir.c_str(), 0);
38        dir += L"\\test_file.write";
39        _wunlink(dir.c_str());
40        FILE *f = _wfopen(dir.c_str(), L"wt");
41        if (f)
42        {
43                fclose(f);
44                _wunlink(dir.c_str());
45                return true;
46        }
47        else
48                return false;
49}
50#endif
51
52bool directoryExists(const char* path, bool is_writable)
53{
54        struct _stat s;
55        if (path[0] == 0) path = ".";
56#ifdef _WIN32
57        if (_wstat(Convert::utf8ToUtf16(path).c_str(), &s) != 0) return false;
58#else
59        if (_stat(path, &s) != 0) return false;
60#endif
61        if (S_ISDIR(s.st_mode))
62        {
63                if (is_writable)
64                {
65#ifdef _WIN32
66#ifndef W_OK
67#define W_OK 2 //http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx
68#endif
69                        //under Windows, access() is not a reliable way to check if a directory is writable
70                        //http://stackoverflow.com/questions/198071/code-for-checking-write-permissions-for-directories-in-win2k-xp
71                        //bool writable_access = _waccess(Convert::utf8ToUtf16(path).c_str(), W_OK) == 0;
72                        bool writable_trial = isDirWritable(path);
73                        //printf("Checking '%s' for writing(%d) using access(): result=%d\n", path, is_writable, writable_access);
74                        //printf("File creation test: result=%d\n", writable_trial);
75                        //return writable_access;
76                        return writable_trial;
77#else
78                        return access(path, W_OK) == 0;
79#endif
80                }
81                else
82                        return true;
83        }
84        return false;
85}
86
87bool makeDirectory(const char* path)
88{
89#ifdef _WIN32
90        return _wmkdir(Convert::utf8ToUtf16(path).c_str()) == 0;
91#else
92        return mkdir(path,0777) == 0;
93#endif
94}
95
96bool makeDirectories(const char* path)
97{
98        if (directoryExists(path,false)) return true;
99        string parentdir = getFileDir(path);
100        if (!makeDirectories(parentdir.c_str())) return false;
101        return makeDirectory(path);
102}
103
104int getFileSize(const char* path)
105{
106        int size;
107#ifdef _WIN32
108        MFILE *f = mfopen(Convert::utf8ToUtf16(path).c_str(), Convert::strTOwstr(FOPEN_READ_BINARY).c_str());
109#else
110        MFILE *f = mfopen(path, FOPEN_READ_BINARY);
111#endif
112        if (f == NULL) return -1;
113        size = getFileSize(f);
114        mfclose(f);
115        return size;
116}
117
118int getFileSize(MFILE *f)
119{
120        int saved_pos = mftell(f);
121        mfseek(f, 0, SEEK_END);
122        int size = mftell(f);
123        mfseek(f, saved_pos, SEEK_SET);
124        return size;
125}
126
127bool removeFile(const char* path)
128{
129#ifdef _WIN32
130        return _wunlink(Convert::utf8ToUtf16(path).c_str()) == 0;
131#else
132        return _unlink(path) == 0; //VS: "The POSIX name is deprecated. Instead, use the ISO C++ conformant name: _unlink"
133#endif
134}
135
136bool isAbsolutePath(const char* fname)
137{
138        if (fname == NULL) return false; //SplitFileSystem never passes NULL but this function is public so we never know
139#ifdef _WIN32
140        return PathIsRelativeW(Convert::utf8ToUtf16(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
141#else
142        return fname[0] == PATH_SEPARATOR_CHAR;
143#endif
144}
145
146#if defined SHP && defined BADA_API_1
147
148MFILE *mfopen(const char *path, const char *mode)
149{
150        Osp::Io::File *f = new Osp::Io::File();
151        result r = f->Construct(path, mode);
152        if (IsFailed(r))
153        {
154                delete f;
155                f = NULL;
156        }
157        return f;
158}
159
160void mfclose(MFILE *f)
161{
162        delete f;
163}
164
165int mfread(void *ptr, int size, int count, MFILE *f)
166{
167        int bytes = size * count;
168        int przeczytane = f->Read(ptr, bytes);
169        return przeczytane != bytes ? przeczytane / size : count;
170}
171
172int mfwrite(const void *ptr, int size, int count, MFILE *f)
173{
174        result r = f->Write(ptr, size * count);
175        if (IsFailed(r))
176                return 0; //nie mozemy wykryc jesli udalo sie zapisac czêœæ
177        else
178                return count;
179}
180
181int mfputs(const char *txt, MFILE *f)
182{
183        int len = strlen(txt);
184        int res = mfwrite(txt, len, 1, f);
185        return res == 1 ? 1 : EOF;
186}
187
188char* mfgets(char *str, int num, MFILE *f)
189{
190        bool err = false;
191        int przeczytane = 0;
192        num--; //zeby zawsze zostalo miejsce na wpisanie koncz¹cego NULL
193        do
194        {
195                err = f->Read(str, 1) != 1;
196                if (!err)
197                {
198                        str++;
199                        przeczytane++;
200                }
201        } while (!err && przeczytane<num && *str != '\n');
202        if (*str == '\n' && przeczytane<num)
203                *(str + 1) = 0;
204        return przeczytane == 0 ? NULL : str;
205}
206
207int mfeof(MFILE *f)
208{
209        //brzydkie obejscie zeby w bada wykryc czy FILE jest w stanie EOF
210        static char buf[1];
211        int pos = f->Tell();
212        int przeczytane = f->Read(&buf, 1);
213        f->Seek(Osp::Io::FILESEEKPOSITION_BEGIN,pos);
214        return przeczytane == 1 ? 0 : 1;
215}
216
217int mfseek(MFILE *f, long position, int type)
218{
219        result r;
220        if (type == SEEK_SET)
221                r = f->Seek(Osp::Io::FILESEEKPOSITION_BEGIN, position);
222        else if (type == SEEK_CUR)
223                r = f->Seek(Osp::Io::FILESEEKPOSITION_CURRENT, position);
224        else if (type == SEEK_END)
225                r = f->Seek(Osp::Io::FILESEEKPOSITION_END, position);
226        else
227                return 1;
228        return IsFailed(r) ? 1 : 0;
229}
230
231long mftell(MFILE *f)
232{
233        return f->Tell();
234}
235
236#endif
237
238
239
240
241
242#ifdef __ANDROID__
243#include "framsg.h"
244#include "nonstd.h"
245#include "nonstd_stl.h"
246MFILE *mfopen(const char *path, const char *mode)
247{
248        string respath=getAppResourcesDir();
249        //printFM("Opening '%s', mode='%s'",path,mode);
250        //printFM("getAppResourcesDir()='%s'",respath.c_str());
251        NvFile *rfile=NULL; //can only read
252        FILE *rwfile=NULL;
253        if (strstr(path,respath.c_str())==path) //opening resource! so we use a dedicated way to read from assets
254        {
255                path+=respath.length(); //strip the prefix, we need a relative path in assets
256                if (strstr(mode,"w"))
257                        printFM("Warning: attempt to open a read-only resource '%s' in writable mode '%s'",path,mode);
258                rfile=NvFOpen(path); //"mode" not supported! can only read
259                //printFM("Opened RES file as %p",rfile);
260                if (rfile==NULL) return NULL;
261        } else //a "normal" access (HOME)
262        {
263                rwfile=fopen(path,mode);
264                //printFM("Opened HOME file as %p",rwfile);
265                if (rwfile==NULL) return NULL;
266        }
267        MFILE *mfile=new MFILE;
268        mfile->rfile=rfile;
269        mfile->rwfile=rwfile;
270        return mfile;
271}
272
273void mfclose(MFILE *f)
274{
275        if (f->rfile)
276                NvFClose(f->rfile);
277        else
278                fclose(f->rwfile);
279
280        delete f;
281}
282
283int mfread(void *ptr, int size, int count, MFILE *f)
284{
285        if (f->rfile)
286                return NvFRead(ptr, size, count, f->rfile); //nvidia introduced my corrections in SDK v10.14, so a fix is no longer needed here
287        else
288                return fread(ptr, size, count, f->rwfile);
289}
290
291int mfwrite(const void *ptr, int size, int count, MFILE *f)
292{
293        if (f->rfile)
294                return 0; //write not supported in assets using nvidia functions
295        else
296                return fwrite(ptr, size, count, f->rwfile);
297}
298
299int mfputs(const char *txt, MFILE *f)
300{
301        int len = strlen(txt);
302        int res = mfwrite(txt, len, 1, f);
303        return res == 1 ? 1 : EOF;
304}
305
306char* mfgets(char *str, int num, MFILE *f)
307{
308        if (f->rfile)
309        {
310                char *ret=NvFGets(str, num, f->rfile);
311                //fixing nvidia inconsistency... their function never returns NULL (fix submitted)
312                if (ret!=NULL && *ret==0 && num>0) //nothing has been read, must have been eof
313                        return NULL;
314                return ret;
315        }
316        else
317                return fgets(str,num,f->rwfile);
318}
319
320int mfeof(MFILE *f)
321{
322        if (f->rfile)
323                return NvFEOF(f->rfile);
324        else
325                return feof(f->rwfile);
326}
327
328int mfseek(MFILE *f, long position, int type)
329{
330        if (f->rfile)
331                return NvFSeek(f->rfile, position, type); //nvidia introduced my corrections in SDK v10.14, so a fix is no longer needed here
332        else
333                return fseek(f->rwfile, position, type);
334}
335
336long mftell(MFILE *f)
337{
338        if (f->rfile)
339                return NvFTell(f->rfile);
340        else
341                return ftell(f->rwfile);
342}
343#endif
Note: See TracBrowser for help on using the repository browser.