GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/fs/virtfs/fsziprwops.cpp Lines: 34 47 72.3 %
Date: 2021-03-17 Branches: 16 24 66.7 %

Line Branch Exec Source
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
185
    RWOPSINT rwops_seek(SDL_RWops *const rw,
44
                        const RWOPSINT offset,
45
                        const int whence)
46
    {
47
185
        if (rw == nullptr)
48
            return -1;
49
        File *const handle = static_cast<File *>(
50
185
            rw->hidden.unknown.data1);
51
185
        const size_t mPos = handle->mPos;
52
185
        const size_t mSize = handle->mSize;
53
54
185
        RWOPSINT pos = 0;
55
56
185
        if (whence == SEEK_SET)
57
        {
58
            pos = offset;
59
        }
60
154
        else if (whence == SEEK_CUR)
61
        {
62
142
            const int64_t current = mPos;
63
142
            if (current == -1)
64
            {
65
                logger->assertLog(
66
                    "VirtFs::rwops_seek: Can't find position in file.");
67
                return -1;
68
            }
69
70
142
            pos = CAST_S32(current);
71
142
            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
142
            if (offset == 0)  /* this is a "tell" call. We're done. */
79
                return pos;
80
81
25
            pos += offset;
82
        }
83
12
        else if (whence == SEEK_END)
84
        {
85
12
            pos = static_cast<RWOPSINT>(mSize + offset);
86
        }
87
        else
88
        {
89
            logger->assertLog(
90
                "VirtFs::rwops_seek: Invalid 'whence' parameter.");
91
            return -1;
92
        }
93
94
68
        if (pos < 0)
95
        {
96
1
            logger->assertLog("VirtFs::rwops_seek: "
97
1
                "Attempt to seek past start of file.");
98
1
            return -1;
99
        }
100
101
67
        handle->mPos = pos;
102
103
67
        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
175
    RWOPSSIZE rwops_read(SDL_RWops *const rw,
113
                         void *const ptr,
114
                         const RWOPSSIZE size,
115
                         const RWOPSSIZE maxnum)
116
    {
117
175
        if (rw == nullptr)
118
            return 0;
119
        File *const handle = static_cast<File *>(
120
175
            rw->hidden.unknown.data1);
121
122
175
        const int64_t rc = handle->funcs->read(handle,
123
            ptr,
124
            CAST_U32(size),
125
175
            CAST_U32(maxnum));
126
175
        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
15
    int rwops_close(SDL_RWops *const rw)
138
    {
139
15
        if (rw == nullptr)
140
            return 0;
141
        File *const handle = static_cast<File*>(
142
15
            rw->hidden.unknown.data1);
143
15
        delete handle;
144
15
        SDL_FreeRW(rw);
145
15
        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