ManaPlus
fsziprwops.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2013-2019 The ManaPlus Developers
4  * Copyright (C) 2019-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 #include "fs/virtfs/fsziprwops.h"
23 
24 #include "logger.h"
25 
26 #include "fs/virtfs/file.h"
27 #include "fs/virtfs/fsfuncs.h"
28 
29 #include "utils/cast.h"
30 
31 PRAGMA48(GCC diagnostic push)
32 PRAGMA48(GCC diagnostic ignored "-Wshadow")
33 #include <SDL_rwops.h>
34 PRAGMA48(GCC diagnostic pop)
35 
36 #include "debug.h"
37 
38 namespace VirtFs
39 {
40 
41 namespace FsZip
42 {
43  RWOPSINT rwops_seek(SDL_RWops *const rw,
44  const RWOPSINT offset,
45  const int whence)
46  {
47  if (rw == nullptr)
48  return -1;
49  File *const handle = static_cast<File *>(
50  rw->hidden.unknown.data1);
51  const size_t mPos = handle->mPos;
52  const size_t mSize = handle->mSize;
53 
54  RWOPSINT pos = 0;
55 
56  if (whence == SEEK_SET)
57  {
58  pos = offset;
59  }
60  else if (whence == SEEK_CUR)
61  {
62  const int64_t current = mPos;
63  if (current == -1)
64  {
66  "VirtFs::rwops_seek: Can't find position in file.");
67  return -1;
68  }
69 
70  pos = CAST_S32(current);
71  if (static_cast<int64_t>(pos) != current)
72  {
73  logger->assertLog("VirtFs::rwops_seek: "
74  "Can't fit current file position in an int!");
75  return -1;
76  }
77 
78  if (offset == 0) /* this is a "tell" call. We're done. */
79  return pos;
80 
81  pos += offset;
82  }
83  else if (whence == SEEK_END)
84  {
85  pos = static_cast<RWOPSINT>(mSize + offset);
86  }
87  else
88  {
90  "VirtFs::rwops_seek: Invalid 'whence' parameter.");
91  return -1;
92  }
93 
94  if (pos < 0)
95  {
96  logger->assertLog("VirtFs::rwops_seek: "
97  "Attempt to seek past start of file.");
98  return -1;
99  }
100 
101  handle->mPos = pos;
102 
103  if (pos > static_cast<RWOPSINT>(mSize))
104  {
105  logger->assertLog("VirtFs::rwops_seek: seek error.");
106  return -1;
107  }
108 
109  return pos;
110  }
111 
112  RWOPSSIZE rwops_read(SDL_RWops *const rw,
113  void *const ptr,
114  const RWOPSSIZE size,
115  const RWOPSSIZE maxnum)
116  {
117  if (rw == nullptr)
118  return 0;
119  File *const handle = static_cast<File *>(
120  rw->hidden.unknown.data1);
121 
122  const int64_t rc = handle->funcs->read(handle,
123  ptr,
124  CAST_U32(size),
125  CAST_U32(maxnum));
126  return CAST_S32(rc);
127  }
128 
129  RWOPSSIZE rwops_write(SDL_RWops *const rw A_UNUSED,
130  const void *const ptr A_UNUSED,
131  const RWOPSSIZE size A_UNUSED,
132  const RWOPSSIZE num A_UNUSED)
133  {
134  return 0;
135  }
136 
137  int rwops_close(SDL_RWops *const rw)
138  {
139  if (rw == nullptr)
140  return 0;
141  File *const handle = static_cast<File*>(
142  rw->hidden.unknown.data1);
143  delete handle;
144  SDL_FreeRW(rw);
145  return 0;
146  }
147 
148 #ifdef USE_SDL2
149  RWOPSINT rwops_size(SDL_RWops *const rw)
150  {
151  if (!rw)
152  return 0;
153  File *const handle = static_cast<File *>(
154  rw->hidden.unknown.data1);
155  return handle->mSize;
156  }
157 #endif // USE_SDL2
158 
159 } // namespace FsZip
160 
161 } // namespace VirtFs
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
void assertLog(const char *const log_text,...)
Definition: logger.cpp:316
#define PRAGMA48(str)
Definition: localconsts.h:199
#define A_UNUSED
Definition: localconsts.h:160
Logger * logger
Definition: logger.cpp:89
int size()
Definition: emotedb.cpp:306
int rwops_read(SDL_RWops *const rw, void *const ptr, const int size, const int maxnum)
Definition: fsziprwops.cpp:112
int rwops_write(SDL_RWops *const rw, const void *const ptr, const int size, const int num)
Definition: fsziprwops.cpp:129
int rwops_close(SDL_RWops *const rw)
Definition: fsziprwops.cpp:137
int32_t rwops_seek(SDL_RWops *const rw, const int32_t offset, const int whence)
Definition: fsziprwops.cpp:43
#define RWOPSSIZE
Definition: rwopstypes.h:32
#define RWOPSINT
Definition: rwopstypes.h:31
size_t mPos
Definition: file.h:53
size_t mSize
Definition: file.h:54
const FsFuncs * funcs
Definition: file.h:47
int64_t(* read)(File *const file, void *const buffer, const uint32_t objSize, const uint32_t objCount)
Definition: fsfuncs.h:73