source: cpp/common/virtfile/stdiofile.cpp @ 1328

Last change on this file since 1328 was 1328, checked in by Maciej Komosinski, 2 days ago

Added Vstat(), Vdelete(), Vsettime() to VirtFILE

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2024  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "stdiofile.h"
6#include <common/nonstd_dir.h>
7#include <common/nonstd_stdio.h>
8#include <common/log.h>
9#include <common/Convert.h>
10#ifdef __ANDROID__
11#include <common/dirs.h>
12#include <common/platform/android/AndroidAPK_DIR.h>
13#endif
14#include <sys/stat.h>
15#include <unistd.h>
16#ifdef _WIN32
17#include <sys/utime.h>
18#else
19#include <utime.h>
20#endif
21
22VirtFILE* StdioFileSystem::Vfopen(const char *path, const char *mode)
23{
24        //log_printf("Vfopen %s %s",path,mode);
25#if defined USE_MFILE || defined _WIN32
26        MFILE *f = mfopen(path, mode);
27#else
28        FILE *f = fopen(path, mode);
29#endif
30        //log_printf("%p",f);
31        if (f) return new StdioFILE(f, path); else return NULL;
32}
33
34VirtDIR* StdioFileSystem::Vopendir(const char* path)
35{
36        //log_printf("Vopendir %s",path);
37#ifdef __ANDROID__
38        int resources_prefix_length = getAppResourcesDir().length();
39        if (strncmp(path, getAppResourcesDir().c_str(), resources_prefix_length) == 0) //it is a resources dir
40        {
41                VirtDIR *vd = AndroidAPK_DIR::opendir(path + resources_prefix_length + 1); //+1 because we also skip '/' and start with a "relative" dir, otherwise it does not work.
42                return vd;
43        }
44#endif
45
46#ifdef _WIN32
47        DIRTYPE *d = wopendir(Convert::utf8ToUtf16(path).c_str());
48#else
49        DIR *d = opendir(path);
50#endif
51        //log_printf("%p",d);
52        if (d) return new StdioDIR(d); else return NULL;
53}
54
55bool StdioFileSystem::Vfexists(const char* path)
56{
57        return fileExists(path);
58}
59
60bool StdioFileSystem::Vdirexists(const char* path, bool is_writable)
61{
62#ifdef __ANDROID__
63        int resources_prefix_length = getAppResourcesDir().length();
64        if (strncmp(path, getAppResourcesDir().c_str(), resources_prefix_length) == 0) //it is a resources dir
65        {
66                if (is_writable)
67                        return false;
68                VirtDIR *vd = AndroidAPK_DIR::opendir(path + resources_prefix_length + 1); //+1 because we also skip '/' and start with a "relative" dir, otherwise it does not work.
69                if (vd != NULL)
70                {
71                        delete vd;
72                        return true;
73                }
74                else
75                {
76                        return false;
77                }
78        }
79#endif
80        return directoryExists(path, is_writable);
81}
82
83bool StdioFileSystem::Vdelete(const char* path)
84{
85        return removeFile(path);
86}
87
88bool StdioFileSystem::Vstat(const char* path, Stat* out)
89{
90#ifdef _WIN32
91        //under windows, there are a few choices of _statXX structures: 32bit, 64bit, ansi, widechar (and their corresponding _statXX() functions). For the future: ensure utf8 filenames work.
92        using stat = struct _stat64i32; //"struct" because there is also a function with the same name
93        //struct _stat64i32 info; //an alternative, simple way if one does not want to use "using" above
94#else
95        struct //if there was "using" earlier, then we cannot use "struct" in type name
96#endif
97        stat info;
98        if (_stat(path, &info) != 0) return false;
99        out->is_file = S_ISREG(info.st_mode);
100#if defined IPHONE && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
101        out->modification_time = info.st_mtimespec.tv_sec;
102#else
103        out->modification_time = info.st_mtime;
104#endif
105        return true;
106}
107
108bool StdioFileSystem::Vsettime(const char* path, double timestamp)
109{
110#ifdef _WIN32
111        //under windows, there are a few choices of _statXX structures: 32bit, 64bit, ansi, widechar (and their corresponding _statXX() functions). For the future: ensure utf8 filenames work.
112        using stat = struct _stat64i32; //"struct" because there is also a function with the same name
113        //struct _stat64i32 info; //an alternative, simple way if one does not want to use "using" above
114#else
115        struct //if there was "using" earlier, then we cannot use "struct" in type name
116#endif
117        stat info;
118        if (_stat(path, &info) != 0) return false;
119        struct utimbuf times;
120#if defined IPHONE && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
121        times.actime = info.st_atimespec.tv_sec;
122#else
123        times.actime = info.st_atime;
124#endif
125        times.modtime = (time_t)timestamp;
126        return utime(path, &times) == 0;
127}
128
129#ifndef NO_STD_IN_OUT_ERR
130void StdioFILE::setStdio()
131{
132        static StdioFILEDontClose si(stdin);
133        static StdioFILEDontClose so(stdout);
134        static StdioFILEDontClose se(stderr);
135        setVstdin(&si);
136        setVstdout(&so);
137        setVstderr(&se);
138}
139#endif
140
141dirent* StdioDIR::Vreaddir()
142{
143        //log_printf("Vreaddir %s",dir);
144#ifdef _WIN32
145        wdirent *wde = wreaddir(dir);
146        if (wde == NULL) return NULL;
147        strcpy(de.d_name, Convert::wstrToUtf8(wde->d_name).c_str());
148        return &de;
149#else
150        return readdir(dir);
151#endif
152}
Note: See TracBrowser for help on using the repository browser.