GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/fs/virtfs/fsziprwops.cpp Lines: 37 47 78.7 %
Date: 2017-11-29 Branches: 17 26 65.4 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2013-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "fs/virtfs/fsziprwops.h"
22
23
#include "logger.h"
24
25
#include "fs/virtfs/file.h"
26
#include "fs/virtfs/fsfuncs.h"
27
28
#include "utils/cast.h"
29
30
PRAGMA48(GCC diagnostic push)
31
PRAGMA48(GCC diagnostic ignored "-Wshadow")
32
#include <SDL_rwops.h>
33
PRAGMA48(GCC diagnostic pop)
34
35
#include "debug.h"
36
37
namespace VirtFs
38
{
39
40
namespace FsZip
41
{
42
370
    RWOPSINT rwops_seek(SDL_RWops *const rw,
43
                        const RWOPSINT offset,
44
                        const int whence)
45
    {
46
370
        if (rw == nullptr)
47
            return -1;
48
370
        File *const handle = static_cast<File *>(
49
            rw->hidden.unknown.data1);
50
370
        size_t mPos = handle->mPos;
51
370
        size_t mSize = handle->mSize;
52
53
370
        RWOPSINT pos = 0;
54
55
370
        if (whence == SEEK_SET)
56
        {
57
            pos = offset;
58
        }
59
308
        else if (whence == SEEK_CUR)
60
        {
61
284
            const int64_t current = mPos;
62
284
            if (current == -1)
63
            {
64
                logger->assertLog(
65
                    "VirtFs::rwops_seek: Can't find position in file.");
66
                return -1;
67
            }
68
69
284
            pos = CAST_S32(current);
70
284
            if (static_cast<int64_t>(pos) != current)
71
            {
72
                logger->assertLog("VirtFs::rwops_seek: "
73
                    "Can't fit current file position in an int!");
74
                return -1;
75
            }
76
77
284
            if (offset == 0)  /* this is a "tell" call. We're done. */
78
                return pos;
79
80
50
            pos += offset;
81
        }
82
24
        else if (whence == SEEK_END)
83
        {
84
24
            pos = static_cast<RWOPSINT>(mSize + offset);
85
        }
86
        else
87
        {
88
            logger->assertLog(
89
                "VirtFs::rwops_seek: Invalid 'whence' parameter.");
90
            return -1;
91
        }
92
93
136
        if (pos < 0)
94
        {
95
2
            logger->assertLog("VirtFs::rwops_seek: "
96
                "Attempt to seek past start of file.");
97
2
            return -1;
98
        }
99
100
134
        handle->mPos = pos;
101
102
134
        if (pos > static_cast<RWOPSINT>(mSize))
103
        {
104
            logger->assertLog("VirtFs::rwops_seek: seek error.");
105
            return -1;
106
        }
107
108
        return pos;
109
    }
110
111
350
    RWOPSSIZE rwops_read(SDL_RWops *const rw,
112
                         void *const ptr,
113
                         const RWOPSSIZE size,
114
                         const RWOPSSIZE maxnum)
115
    {
116
350
        if (rw == nullptr)
117
            return 0;
118
350
        File *const handle = static_cast<File *>(
119
            rw->hidden.unknown.data1);
120
121
350
        const int64_t rc = handle->funcs->read(handle,
122
            ptr,
123
            CAST_U32(size),
124
350
            CAST_U32(maxnum));
125
350
        return CAST_S32(rc);
126
    }
127
128
    RWOPSSIZE rwops_write(SDL_RWops *const rw A_UNUSED,
129
                          const void *const ptr A_UNUSED,
130
                          const RWOPSSIZE size A_UNUSED,
131
                          const RWOPSSIZE num A_UNUSED)
132
    {
133
        return 0;
134
    }
135
136
30
    int rwops_close(SDL_RWops *const rw)
137
    {
138
30
        if (rw == nullptr)
139
            return 0;
140
30
        File *const handle = static_cast<File*>(
141
            rw->hidden.unknown.data1);
142
30
        delete handle;
143
30
        SDL_FreeRW(rw);
144
30
        return 0;
145
    }
146
147
#ifdef USE_SDL2
148
4
    RWOPSINT rwops_size(SDL_RWops *const rw)
149
    {
150
4
        if (!rw)
151
            return 0;
152
4
        File *const handle = static_cast<File *>(
153
            rw->hidden.unknown.data1);
154
4
        return handle->mSize;
155
    }
156
#endif  // USE_SDL2
157
158
}  // namespace FsZip
159
160
}  // namespace VirtFs