ManaPlus
rwops.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2013-2019 The ManaPlus Developers
4  * Copyright (C) 2009-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 /*
23  * This code provides a glue layer between PhysicsFS and Simple Directmedia
24  * Layer's (SDL) RWops i/o abstraction.
25  *
26  * License: this code is public domain. I make no warranty that it is useful,
27  * correct, harmless, or environmentally safe.
28  *
29  * This particular file may be used however you like, including copying it
30  * verbatim into a closed-source project, exploiting it commercially, and
31  * removing any trace of my name from the source (although I hope you won't
32  * do that). I welcome enhancements and corrections to this file, but I do
33  * not require you to send me patches if you make changes. This code has
34  * NO WARRANTY.
35  *
36  * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
37  * Please see LICENSE.txt in the root of the source tree.
38  *
39  * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
40  *
41  * This file was written by Ryan C. Gordon. ([email protected]).
42  *
43  * Copyright (C) 2012-2019 The ManaPlus Developers
44  * Copyright (C) 2009-2021 Andrei Karas
45  */
46 
47 #include "fs/virtfs/rwops.h"
48 
49 #include "fs/virtfs/file.h"
50 #include "fs/virtfs/fs.h"
51 #include "fs/virtfs/fsfuncs.h"
52 
53 #include "utils/checkutils.h"
54 #include "utils/fuzzer.h"
55 
56 PRAGMA48(GCC diagnostic push)
57 PRAGMA48(GCC diagnostic ignored "-Wshadow")
58 #include <SDL_rwops.h>
59 PRAGMA48(GCC diagnostic pop)
60 
61 #include "debug.h"
62 
63 namespace VirtFs
64 {
65 
66 SDL_RWops *create_rwops(File *const file,
67  const std::string &restrict fname)
68 {
69  SDL_RWops *retval = nullptr;
70 
71  if (file == nullptr)
72  {
73  reportAlways("VirtFs::rwops_seek: create rwops error: %s",
74  fname.c_str())
75  }
76  else
77  {
78  retval = SDL_AllocRW();
79  if (retval != nullptr)
80  {
81 #ifdef USE_SDL2
82  retval->size = file->funcs->rwops_size;
83 #endif // USE_SDL2
84 
85  retval->seek = file->funcs->rwops_seek;
86  retval->read = file->funcs->rwops_read;
87  retval->write = file->funcs->rwops_write;
88  retval->close = file->funcs->rwops_close;
89  retval->hidden.unknown.data1 = file;
90  } /* if */
91  } /* else */
92 
93  return retval;
94 } /* VirtFs::create_rwops */
95 
96 #ifdef __APPLE__
97 static bool checkFilePath(const std::string &restrict fname)
98 {
99  if (fname.empty())
100  return false;
101  if (!exists(fname) || isDirectory(fname))
102  return false;
103  return true;
104 }
105 #endif // __APPLE__
106 
107 SDL_RWops *rwopsOpenRead(const std::string &restrict fname)
108 {
109  BLOCK_START("RWopsopenRead")
110 #ifdef __APPLE__
111  if (!checkFilePath(fname))
112  return nullptr;
113 #endif // __APPLE__
114 #ifdef USE_FUZZER
115  if (Fuzzer::conditionTerminate(fname))
116  return nullptr;
117 #endif // USE_FUZZER
118 #ifdef USE_PROFILER
119 
120  SDL_RWops *const ret = create_rwops(openRead(fname),
121  fname);
122 
123  BLOCK_END("RWopsopenRead")
124  return ret;
125 #else // USE_PROFILER
126 
127  return create_rwops(openRead(fname),
128  fname);
129 #endif // USE_PROFILER
130 } /* RWopsopenRead */
131 
132 SDL_RWops *rwopsOpenWrite(const std::string &restrict fname)
133 {
134 #ifdef __APPLE__
135  if (!checkFilePath(fname))
136  return nullptr;
137 #endif // __APPLE__
138 
139  return create_rwops(openWrite(fname),
140  fname);
141 } /* RWopsopenWrite */
142 
143 SDL_RWops *rwopsOpenAppend(const std::string &restrict fname)
144 {
145 #ifdef __APPLE__
146  if (!checkFilePath(fname))
147  return nullptr;
148 #endif // __APPLE__
149 
150  return create_rwops(openAppend(fname),
151  fname);
152 } /* RWopsopenAppend */
153 
154 } // namespace VirtFs
155 
156 /* end of virtfsrwops.c ... */
#define reportAlways(...)
Definition: checkutils.h:253
#define restrict
Definition: localconsts.h:165
#define PRAGMA48(str)
Definition: localconsts.h:199
File * openRead(std::string filename)
Definition: fs.cpp:274
SDL_RWops * create_rwops(File *const file, const std::string &fname)
Definition: rwops.cpp:66
SDL_RWops * rwopsOpenWrite(const std::string &fname)
Definition: rwops.cpp:132
bool isDirectory(std::string name)
Definition: fs.cpp:239
SDL_RWops * rwopsOpenRead(const std::string &fname)
Definition: rwops.cpp:107
File * openWrite(std::string filename)
Definition: fs.cpp:293
SDL_RWops * rwopsOpenAppend(const std::string &fname)
Definition: rwops.cpp:143
File * openAppend(std::string filename)
Definition: fs.cpp:312
bool exists(std::string name)
Definition: fs.cpp:124
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
const FsFuncs * funcs
Definition: file.h:47
int(* seek)(File *const file, const uint64_t pos)
Definition: fsfuncs.h:83
int(* rwops_write)(SDL_RWops *const rw, const void *const ptr, const int size, const int num)
Definition: fsfuncs.h:125
int32_t(* rwops_seek)(SDL_RWops *const rw, const int32_t offset, const int whence)
Definition: fsfuncs.h:118
int(* rwops_read)(SDL_RWops *const rw, void *const ptr, const int size, const int maxnum)
Definition: fsfuncs.h:121
int(* rwops_close)(SDL_RWops *const rw)
Definition: fsfuncs.h:132