Mercurial > love-experiments
annotate src/modules/filesystem/physfs/File.cpp @ 1140:d8c70acb666e
Make love.sound.newDecoder accept FileData, and make File->read return FileData
| author | Bart van Strien <bart.bes+projects@gmail.com> |
|---|---|
| date | Sun, 14 Oct 2012 17:19:40 +0200 |
| parents | 86a44f2bc38f |
| children | 86908814f2d8 |
| rev | line source |
|---|---|
| 1096 | 1 /** |
| 2 * Copyright (c) 2006-2012 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 // STD | |
| 24 #include <cstring> | |
| 25 | |
| 26 // LOVE | |
| 27 #include "Filesystem.h" | |
| 28 #include "filesystem/FileData.h" | |
| 29 | |
| 30 namespace love | |
| 31 { | |
| 32 namespace filesystem | |
| 33 { | |
| 34 namespace physfs | |
| 35 { | |
| 36 | |
| 37 extern bool hack_setupWriteDirectory(); | |
| 38 | |
| 39 File::File(std::string filename) | |
| 40 : filename(filename) | |
| 41 , file(0) | |
| 42 , mode(filesystem::File::CLOSED) | |
| 43 { | |
| 44 } | |
| 45 | |
| 46 File::~File() | |
| 47 { | |
| 48 if (mode != CLOSED) | |
| 49 close(); | |
| 50 } | |
| 51 | |
| 52 bool File::open(Mode mode) | |
| 53 { | |
| 54 if (mode == CLOSED) | |
| 55 return true; | |
| 56 | |
| 57 // File must exist if read mode. | |
| 58 if ((mode == READ) && !PHYSFS_exists(filename.c_str())) | |
| 59 throw love::Exception("Could not open file %s. Does not exist.", filename.c_str()); | |
| 60 | |
| 61 // Check whether the write directory is set. | |
| 62 if ((mode == APPEND || mode == WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory()) | |
| 63 throw love::Exception("Could not set write directory."); | |
| 64 | |
| 65 // File already open? | |
| 66 if (file != 0) | |
| 67 return false; | |
| 68 | |
| 69 this->mode = mode; | |
| 70 | |
| 71 switch (mode) | |
| 72 { | |
| 73 case READ: | |
| 74 file = PHYSFS_openRead(filename.c_str()); | |
| 75 break; | |
| 76 case APPEND: | |
| 77 file = PHYSFS_openAppend(filename.c_str()); | |
| 78 break; | |
| 79 case WRITE: | |
| 80 file = PHYSFS_openWrite(filename.c_str()); | |
| 81 break; | |
| 82 default: | |
| 83 break; | |
| 84 } | |
| 85 | |
| 86 return (file != 0); | |
| 87 } | |
| 88 | |
| 89 bool File::close() | |
| 90 { | |
| 91 if (!PHYSFS_close(file)) | |
| 92 return false; | |
| 93 mode = CLOSED; | |
| 94 file = 0; | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 int64 File::getSize() | |
| 99 { | |
| 100 // If the file is closed, open it to | |
| 101 // check the size. | |
| 102 if (file == 0) | |
| 103 { | |
| 104 open(READ); | |
| 105 int64 size = (int64)PHYSFS_fileLength(file); | |
| 106 close(); | |
| 107 return size; | |
| 108 } | |
| 109 | |
| 110 return (int64)PHYSFS_fileLength(file); | |
| 111 } | |
| 112 | |
| 113 | |
|
1140
d8c70acb666e
Make love.sound.newDecoder accept FileData, and make File->read return FileData
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
114 FileData *File::read(int64 size) |
| 1096 | 115 { |
| 116 bool isOpen = (file != 0); | |
| 117 | |
| 118 if (!isOpen && !open(READ)) | |
| 119 throw love::Exception("Could not read file %s.", filename.c_str()); | |
| 120 | |
| 121 int64 max = (int64)PHYSFS_fileLength(file); | |
| 122 size = (size == ALL) ? max : size; | |
| 123 size = (size > max) ? max : size; | |
| 124 | |
| 125 FileData *fileData = new FileData(size, getFilename()); | |
| 126 | |
| 127 read(fileData->getData(), size); | |
| 128 | |
| 129 if (!isOpen) | |
| 130 close(); | |
| 131 | |
| 132 return fileData; | |
| 133 } | |
| 134 | |
| 135 int64 File::read(void *dst, int64 size) | |
| 136 { | |
| 137 bool isOpen = (file != 0); | |
| 138 | |
| 139 if (!isOpen) | |
| 140 open(READ); | |
| 141 | |
| 142 int64 max = (int64)PHYSFS_fileLength(file); | |
| 143 size = (size == ALL) ? max : size; | |
| 144 size = (size > max) ? max : size; | |
| 145 // Sadly, we'll have to clamp to 32 bits here | |
| 146 size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; | |
| 147 | |
| 148 int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size); | |
| 149 | |
| 150 if (!isOpen) | |
| 151 close(); | |
| 152 | |
| 153 return read; | |
| 154 } | |
| 155 | |
| 156 bool File::write(const void *data, int64 size) | |
| 157 { | |
| 158 if (file == 0) | |
| 159 throw love::Exception("Could not write to file. File not open."); | |
| 160 | |
| 161 // Another clamp, for the time being. | |
| 162 size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; | |
| 163 | |
| 164 // Try to write. | |
| 165 int64 written = static_cast<int64>(PHYSFS_write(file, data, 1, (int) size)); | |
| 166 | |
| 167 // Check that correct amount of data was written. | |
| 168 if (written != size) | |
| 169 return false; | |
| 170 | |
| 171 return true; | |
| 172 } | |
| 173 | |
| 174 bool File::write(const Data *data, int64 size) | |
| 175 { | |
| 176 return write(data->getData(), (size == ALL) ? data->getSize() : size); | |
| 177 } | |
| 178 | |
| 179 #ifdef LOVE_WINDOWS | |
| 180 // MSVC doesn't like the 'this' keyword | |
| 181 // well, we'll use 'that'. | |
| 182 // It zigs, we zag. | |
| 183 inline bool test_eof(File *that, PHYSFS_File *) | |
| 184 { | |
| 185 int64 pos = that->tell(); | |
| 186 int64 size = that->getSize(); | |
| 187 return pos == -1 || size == -1 || pos >= size; | |
| 188 } | |
| 189 #else | |
| 190 inline bool test_eof(File *, PHYSFS_File *file) | |
| 191 { | |
| 192 return PHYSFS_eof(file); | |
| 193 } | |
| 194 #endif | |
| 195 | |
| 196 bool File::eof() | |
| 197 { | |
| 198 if (file == 0 || test_eof(this, file)) | |
| 199 return true; | |
| 200 return false; | |
| 201 } | |
| 202 | |
| 203 int64 File::tell() | |
| 204 { | |
| 205 if (file == 0) | |
| 206 return -1; | |
| 207 | |
| 208 return (int64)PHYSFS_tell(file); | |
| 209 } | |
| 210 | |
| 211 bool File::seek(uint64 pos) | |
| 212 { | |
| 213 if (file == 0) | |
| 214 return false; | |
| 215 | |
| 216 if (!PHYSFS_seek(file, (PHYSFS_uint64)pos)) | |
| 217 return false; | |
| 218 return true; | |
| 219 } | |
| 220 | |
| 221 std::string File::getFilename() const | |
| 222 { | |
| 223 return filename; | |
| 224 } | |
| 225 | |
| 226 std::string File::getExtension() const | |
| 227 { | |
| 228 std::string::size_type idx = filename.rfind('.'); | |
| 229 | |
| 230 if (idx != std::string::npos) | |
| 231 return filename.substr(idx+1); | |
| 232 else | |
| 233 return std::string(); | |
| 234 } | |
| 235 | |
| 236 filesystem::File::Mode File::getMode() | |
| 237 { | |
| 238 return mode; | |
| 239 } | |
| 240 | |
| 241 } // physfs | |
| 242 } // filesystem | |
| 243 } // love |
