~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to ext/armips/Core/FileManager.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "stdafx.h"
 
2
#include "FileManager.h"
 
3
#include "Misc.h"
 
4
#include "Common.h"
 
5
 
 
6
inline u32 swapEndianness32(u32 value)
 
7
{
 
8
        return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) | ((value & 0xFF000000) >> 24);
 
9
}
 
10
 
 
11
inline u16 swapEndianness16(u16 value)
 
12
{
 
13
        return ((value & 0xFF) << 8) | ((value & 0xFF00) >> 8);
 
14
}
 
15
 
 
16
 
 
17
GenericAssemblerFile::GenericAssemblerFile(const std::wstring& fileName, u32 headerSize, bool overwrite)
 
18
{
 
19
        this->fileName = fileName;
 
20
        this->headerSize = headerSize;
 
21
        this->originalHeaderSize = headerSize;
 
22
        this->virtualAddress = headerSize;
 
23
        mode = overwrite == true ? Create : Open;
 
24
}
 
25
 
 
26
GenericAssemblerFile::GenericAssemblerFile(const std::wstring& fileName, const std::wstring& originalFileName, u32 headerSize)
 
27
{
 
28
        this->fileName = fileName;
 
29
        this->originalName = originalFileName;
 
30
        this->headerSize = headerSize;
 
31
        this->virtualAddress = headerSize;
 
32
        originalHeaderSize = headerSize;
 
33
        mode = Copy;
 
34
}
 
35
 
 
36
bool GenericAssemblerFile::open(bool onlyCheck)
 
37
{
 
38
        headerSize = originalHeaderSize;
 
39
        virtualAddress = headerSize;
 
40
 
 
41
        if (onlyCheck == false)
 
42
        {
 
43
                // actually open the file
 
44
                bool success;
 
45
                switch (mode)
 
46
                {
 
47
                case Open:
 
48
                        success = handle.open(fileName,BinaryFile::ReadWrite);
 
49
                        if (success == false)
 
50
                        {
 
51
                                Logger::printError(Logger::FatalError,L"Could not open file %s",fileName);
 
52
                                return false;
 
53
                        }
 
54
                        return true;
 
55
 
 
56
                case Create:
 
57
                        success = handle.open(fileName,BinaryFile::Write);
 
58
                        if (success == false)
 
59
                        {
 
60
                                Logger::printError(Logger::FatalError,L"Could not create file %s",fileName);
 
61
                                return false;
 
62
                        }
 
63
                        return true;
 
64
 
 
65
                case Copy:
 
66
                        success = copyFile(originalName,fileName);
 
67
                        if (success == false)
 
68
                        {
 
69
                                Logger::printError(Logger::FatalError,L"Could not copy file %s",originalName);
 
70
                                return false;
 
71
                        }
 
72
 
 
73
                        success = handle.open(fileName,BinaryFile::ReadWrite);
 
74
                        if (success == false)
 
75
                        {
 
76
                                Logger::printError(Logger::FatalError,L"Could not open file %s",fileName);
 
77
                                return false;
 
78
                        }
 
79
                        return true;
 
80
 
 
81
                default:
 
82
                        return false;
 
83
                }
 
84
        }
 
85
 
 
86
        // else only check if it can be done, don't actually do it permanently
 
87
        bool success, exists;
 
88
        BinaryFile temp;
 
89
        switch (mode)
 
90
        {
 
91
        case Open:
 
92
                success = temp.open(fileName,BinaryFile::ReadWrite);
 
93
                if (success == false)
 
94
                {
 
95
                        Logger::queueError(Logger::FatalError,L"Could not open file %s",fileName);
 
96
                        return false;
 
97
                }
 
98
                temp.close();
 
99
                return true;
 
100
 
 
101
        case Create:
 
102
                // if it exists, check if you can open it with read/write access
 
103
                // otherwise open it with write access and remove it afterwards
 
104
                exists = fileExists(fileName);
 
105
                success = temp.open(fileName,exists ? BinaryFile::ReadWrite : BinaryFile::Write);
 
106
                if (success == false)
 
107
                {
 
108
                        Logger::queueError(Logger::FatalError,L"Could not create file %s",fileName);
 
109
                        return false;
 
110
                }
 
111
                temp.close();
 
112
 
 
113
                if (exists == false)
 
114
                        deleteFile(fileName);
 
115
 
 
116
                return true;
 
117
 
 
118
        case Copy:
 
119
                // check original file
 
120
                success = temp.open(originalName,BinaryFile::ReadWrite);
 
121
                if (success == false)
 
122
                {
 
123
                        Logger::queueError(Logger::FatalError,L"Could not open file %s",originalName);
 
124
                        return false;
 
125
                }
 
126
                temp.close();
 
127
 
 
128
                // check new file, same as create
 
129
                exists = fileExists(fileName);
 
130
                success = temp.open(fileName,exists ? BinaryFile::ReadWrite : BinaryFile::Write);
 
131
                if (success == false)
 
132
                {
 
133
                        Logger::queueError(Logger::FatalError,L"Could not open file %s",fileName);
 
134
                        return false;
 
135
                }
 
136
                temp.close();
 
137
                
 
138
                if (exists == false)
 
139
                        deleteFile(fileName);
 
140
 
 
141
                return true;
 
142
 
 
143
        default:
 
144
                return false;
 
145
        };
 
146
 
 
147
        return false;
 
148
}
 
149
 
 
150
bool GenericAssemblerFile::write(void* data, size_t length)
 
151
{
 
152
        if (isOpen() == false)
 
153
                return false;
 
154
 
 
155
        size_t len = handle.write(data,length);
 
156
        virtualAddress += len;
 
157
        return len == length;
 
158
}
 
159
 
 
160
bool GenericAssemblerFile::seekVirtual(u64 virtualAddress)
 
161
{
 
162
        if (virtualAddress < headerSize)
 
163
        {
 
164
                Logger::queueError(Logger::Error,L"Seeking to invalid address");
 
165
                return false;
 
166
        }
 
167
 
 
168
        this->virtualAddress = virtualAddress;
 
169
        u64 physicalAddress = virtualAddress-headerSize;
 
170
 
 
171
        if (isOpen())
 
172
                handle.setPos((long)physicalAddress);
 
173
 
 
174
        return true;
 
175
}
 
176
 
 
177
bool GenericAssemblerFile::seekPhysical(u64 physicalAddress)
 
178
{
 
179
        if ((signed)physicalAddress < 0)
 
180
        {
 
181
                Logger::queueError(Logger::Error,L"Seeking to invalid address");
 
182
                return false;
 
183
        }
 
184
 
 
185
        virtualAddress = physicalAddress+headerSize;
 
186
 
 
187
        if (isOpen())
 
188
                handle.setPos((long)physicalAddress);
 
189
 
 
190
        return true;
 
191
}
 
192
 
 
193
 
 
194
 
 
195
FileManager::FileManager()
 
196
{
 
197
        // detect own endianness
 
198
        volatile union
 
199
        {
 
200
                u32 i;
 
201
                u8 c[4];
 
202
        } u;
 
203
        u.c[3] = 0xAA;
 
204
        u.c[2] = 0xBB;
 
205
        u.c[1] = 0xCC;
 
206
        u.c[0] = 0xDD;
 
207
 
 
208
        if (u.i == 0xDDCCBBAA)
 
209
                ownEndianness = Endianness::Big;
 
210
        else if (u.i == 0xAABBCCDD)
 
211
                ownEndianness = Endianness::Little;
 
212
        else
 
213
                Logger::printError(Logger::Error,L"Running on unknown endianness");
 
214
 
 
215
        reset();
 
216
}
 
217
 
 
218
FileManager::~FileManager()
 
219
{
 
220
 
 
221
}
 
222
 
 
223
void FileManager::reset()
 
224
{
 
225
        activeFile = NULL;
 
226
        setEndianness(Endianness::Little);
 
227
}
 
228
 
 
229
bool FileManager::checkActiveFile()
 
230
{
 
231
        if (activeFile == NULL)
 
232
        {
 
233
                Logger::queueError(Logger::Error,L"No file opened");
 
234
                return false;
 
235
        }
 
236
        return true;
 
237
}
 
238
 
 
239
bool FileManager::openFile(AssemblerFile* file, bool onlyCheck)
 
240
{
 
241
        if (activeFile != NULL)
 
242
        {
 
243
                Logger::queueError(Logger::Warning,L"File not closed before opening a new one");
 
244
                activeFile->close();
 
245
        }
 
246
 
 
247
        activeFile = file;
 
248
        return activeFile->open(onlyCheck);
 
249
}
 
250
 
 
251
void FileManager::addFile(AssemblerFile* file)
 
252
{
 
253
        files.push_back(file);
 
254
        activeFile = file;
 
255
}
 
256
 
 
257
void FileManager::closeFile()
 
258
{
 
259
        if (activeFile == NULL)
 
260
        {
 
261
                Logger::queueError(Logger::Warning,L"No file opened");
 
262
                return;
 
263
        }
 
264
 
 
265
        activeFile->close();
 
266
        activeFile = NULL;
 
267
}
 
268
 
 
269
bool FileManager::write(void* data, size_t length)
 
270
{
 
271
        if (checkActiveFile() == false)
 
272
                return false;
 
273
 
 
274
        if (activeFile->isOpen() == false)
 
275
        {
 
276
                Logger::queueError(Logger::Error,L"No file opened");
 
277
                return false;
 
278
        }
 
279
 
 
280
        return activeFile->write(data,length);
 
281
}
 
282
 
 
283
bool FileManager::writeU8(u8 data)
 
284
{
 
285
        return write(&data,1);
 
286
}
 
287
 
 
288
bool FileManager::writeU16(u16 data)
 
289
{
 
290
        if (endianness != ownEndianness)
 
291
                data = swapEndianness16(data);
 
292
 
 
293
        return write(&data,2);
 
294
}
 
295
 
 
296
bool FileManager::writeU32(u32 data)
 
297
{
 
298
        if (endianness != ownEndianness)
 
299
                data = swapEndianness32(data);
 
300
 
 
301
        return write(&data,4);
 
302
}
 
303
 
 
304
u64 FileManager::getVirtualAddress()
 
305
{
 
306
        if (activeFile == NULL)
 
307
                return -1;
 
308
        return activeFile->getVirtualAddress();
 
309
}
 
310
 
 
311
u64 FileManager::getPhysicalAddress()
 
312
{
 
313
        if (activeFile == NULL)
 
314
                return -1;
 
315
        return activeFile->getPhysicalAddress();
 
316
}
 
317
 
 
318
bool FileManager::seekVirtual(u64 virtualAddress)
 
319
{
 
320
        if (checkActiveFile() == false)
 
321
                return false;
 
322
 
 
323
        bool result = activeFile->seekVirtual(virtualAddress);
 
324
        if (result && Global.memoryMode)
 
325
        {
 
326
                int sec = Global.symbolTable.findSection(virtualAddress);
 
327
                if (sec != -1)
 
328
                        Global.Section = sec;
 
329
        }
 
330
 
 
331
        return result;
 
332
}
 
333
 
 
334
bool FileManager::seekPhysical(u64 virtualAddress)
 
335
{
 
336
        if (checkActiveFile() == false)
 
337
                return false;
 
338
        return activeFile->seekPhysical(virtualAddress);
 
339
}
 
340
 
 
341
bool FileManager::advanceMemory(size_t bytes)
 
342
{
 
343
        if (checkActiveFile() == false)
 
344
                return false;
 
345
 
 
346
        u64 pos = activeFile->getVirtualAddress();
 
347
        return activeFile->seekVirtual(pos+bytes);
 
348
}
 
 
b'\\ No newline at end of file'