1 /**
2 * Copyright (c) 2006-2016 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21 #include "File.h"
22
23 namespace love
24 {
25 namespace filesystem
26 {
27
~File()28 File::~File()
29 {
30 }
31
read(int64 size)32 FileData *File::read(int64 size)
33 {
34 bool isopen = isOpen();
35
36 if (!isopen && !open(MODE_READ))
37 throw love::Exception("Could not read file %s.", getFilename().c_str());
38
39 int64 max = getSize();
40 int64 cur = tell();
41 size = (size == ALL) ? max : size;
42
43 if (size < 0)
44 throw love::Exception("Invalid read size.");
45
46 // Clamping because the file offset may be in a weird position.
47 if (cur < 0)
48 cur = 0;
49 else if (cur > max)
50 cur = max;
51
52 if (cur + size > max)
53 size = max - cur;
54
55 FileData *fileData = new FileData(size, getFilename());
56 int64 bytesRead = read(fileData->getData(), size);
57
58 if (bytesRead < 0 || (bytesRead == 0 && bytesRead != size))
59 {
60 delete fileData;
61 throw love::Exception("Could not read from file.");
62 }
63
64 if (bytesRead < size)
65 {
66 FileData *tmpFileData = new FileData(bytesRead, getFilename());
67 memcpy(tmpFileData->getData(), fileData->getData(), (size_t) bytesRead);
68 fileData->release();
69 fileData = tmpFileData;
70 }
71
72 if (!isopen)
73 close();
74
75 return fileData;
76 }
77
write(const Data * data,int64 size)78 bool File::write(const Data *data, int64 size)
79 {
80 return write(data->getData(), (size == ALL) ? data->getSize() : size);
81 }
82
getExtension() const83 std::string File::getExtension() const
84 {
85 const std::string &filename = getFilename();
86 std::string::size_type idx = filename.rfind('.');
87
88 if (idx != std::string::npos)
89 return filename.substr(idx+1);
90 else
91 return std::string();
92 }
93
getConstant(const char * in,Mode & out)94 bool File::getConstant(const char *in, Mode &out)
95 {
96 return modes.find(in, out);
97 }
98
getConstant(Mode in,const char * & out)99 bool File::getConstant(Mode in, const char *&out)
100 {
101 return modes.find(in, out);
102 }
103
getConstant(const char * in,BufferMode & out)104 bool File::getConstant(const char *in, BufferMode &out)
105 {
106 return bufferModes.find(in, out);
107 }
108
getConstant(BufferMode in,const char * & out)109 bool File::getConstant(BufferMode in, const char *&out)
110 {
111 return bufferModes.find(in, out);
112 }
113
114 StringMap<File::Mode, File::MODE_MAX_ENUM>::Entry File::modeEntries[] =
115 {
116 {"c", File::MODE_CLOSED},
117 {"r", File::MODE_READ},
118 {"w", File::MODE_WRITE},
119 {"a", File::MODE_APPEND},
120 };
121
122 StringMap<File::Mode, File::MODE_MAX_ENUM> File::modes(File::modeEntries, sizeof(File::modeEntries));
123
124 StringMap<File::BufferMode, File::BUFFER_MAX_ENUM>::Entry File::bufferModeEntries[] =
125 {
126 {"none", File::BUFFER_NONE},
127 {"line", File::BUFFER_LINE},
128 {"full", File::BUFFER_FULL},
129 };
130
131 StringMap<File::BufferMode, File::BUFFER_MAX_ENUM> File::bufferModes(File::bufferModeEntries, sizeof(File::bufferModeEntries));
132
133 } // filesystem
134 } // love
135