diff options
author | Alexander Tkachev | 2016-07-08 13:31:47 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | b69cc3effbbe2cccefc29eb2db097945d78cf89b (patch) | |
tree | d35d741f9169950bb67cfd4f77a3e9847bb3494a /backends | |
parent | bca05b2720298b17f9078465cd0896cc5d627819 (diff) | |
download | scummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.tar.gz scummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.tar.bz2 scummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.zip |
CLOUD: Update Reader to delete temp files
Diffstat (limited to 'backends')
-rw-r--r-- | backends/networking/sdl_net/reader.cpp | 94 | ||||
-rw-r--r-- | backends/networking/sdl_net/reader.h | 7 |
2 files changed, 93 insertions, 8 deletions
diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp index 2037ef747e..7fe9d7b15a 100644 --- a/backends/networking/sdl_net/reader.cpp +++ b/backends/networking/sdl_net/reader.cpp @@ -29,9 +29,18 @@ #include "common/memstream.h" #include "backends/fs/fs-factory.h" +// This define lets us use the system function remove() on Symbian, which +// is disabled by default due to a macro conflict. +// See backends/platform/symbian/src/portdefs.h . +#define SYMBIAN_USE_SYSTEM_REMOVE + +#ifndef _WIN32_WCE +#include <errno.h> // for removeFile() +#endif + namespace Networking { -Reader::Reader() { +Reader::Reader(): _randomSource("Networking::Reader") { _state = RS_NONE; _content = nullptr; _bytesLeft = 0; @@ -49,10 +58,79 @@ Reader::Reader() { _isBadRequest = false; } +namespace { +bool removeFile(const char *filename) { + // FIXME: remove does not exist on all systems. If your port fails to + // compile because of this, please let us know (scummvm-devel). + // There is a nicely portable workaround, too: Make this method overloadable. + if (remove(filename) != 0) { +#ifndef _WIN32_WCE + if (errno == EACCES) + error("Reader: removeFile(): Search or write permission denied: %s", filename); + + if (errno == ENOENT) + error("Reader: removeFile(): '%s' does not exist or path is invalid", filename); +#endif + return false; + } else { + return true; + } +} +} + Reader::~Reader() { - //TODO: free everything + cleanup(); +} + +Reader &Reader::operator=(Reader &r) { + if (this == &r) return *this; + cleanup(); + + _state = r._state; + _content = r._content; + _bytesLeft = r._bytesLeft; + r._state = RS_NONE; + + _window = r._window; + _windowUsed = r._windowUsed; + _windowSize = r._windowSize; + r._window = nullptr; + + _headers = r._headers; + _stream = r._stream; + r._stream = nullptr; + + _headers = r._headers; + _method = r._method; + _path = r._path; + _query = r._query; + _anchor = r._anchor; + _queryParameters = r._queryParameters; + _attachedFiles = r._attachedFiles; + r._attachedFiles.clear(); + _contentLength = r._contentLength; + _boundary = r._boundary; + _availableBytes = r._availableBytes; + _currentFieldName = r._currentFieldName; + _currentFileName = r._currentFileName; + _currentTempFileName = r._currentTempFileName; + _isFileField = r._isFileField; + _isBadRequest = r._isBadRequest; + + return *this; +} + +void Reader::cleanup() { + //_content is not to be freed, it's not owned by Reader + if (_window != nullptr) freeWindow(); delete _stream; + + //delete temp files (by the time Reader is destucted those must be renamed or read) + for (Common::HashMap<Common::String, Common::String>::iterator i = _attachedFiles.begin(); i != _attachedFiles.end(); ++i) { + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(i->_value); + if (node->exists()) removeFile(node->getPath().c_str()); + } } bool Reader::readRequest() { @@ -264,14 +342,14 @@ void Reader::parseQueryParameters() { } namespace { -char generateRandomChar() { - int r = rand() % 36; +char generateRandomChar(Common::RandomSource &random) { + int r = random.getRandomNumber(36); char c = '0' + r; if (r > 9) c = 'a' + r - 10; return c; } -Common::String generateTempFileName(Common::String originalFilename) { +Common::String generateTempFileName(Common::String originalFilename, Common::RandomSource &random) { //generates "./<originalFilename>-<uniqueSequence>.scummtmp" //normalize <originalFilename> Common::String prefix = "./"; @@ -288,13 +366,13 @@ Common::String generateTempFileName(Common::String originalFilename) { //generate initial sequence Common::String uniqueSequence; for (uint32 i = 0; i < 5; ++i) - uniqueSequence += generateRandomChar(); + uniqueSequence += generateRandomChar(random); //update sequence while generate path exists AbstractFSNode *node; Common::String path; do { - uniqueSequence += generateRandomChar(); + uniqueSequence += generateRandomChar(random); path = prefix + uniqueSequence + ".scummtmp"; node = g_system->getFilesystemFactory()->makeFileNodePath(path); } while (node->exists()); @@ -311,7 +389,7 @@ bool Reader::readContent() { if (_stream) delete _stream; if (_isFileField) { //create temporary file - _currentTempFileName = generateTempFileName(_currentFileName); + _currentTempFileName = generateTempFileName(_currentFileName, _randomSource); AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(_currentTempFileName); _stream = node->createWriteStream(); if (_stream == nullptr) diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h index 20b2a6148f..09550e09c9 100644 --- a/backends/networking/sdl_net/reader.h +++ b/backends/networking/sdl_net/reader.h @@ -27,6 +27,7 @@ #include "common/str.h" #include "common/hashmap.h" #include "common/hash-str.h" +#include "common/random.h" namespace Common { class WriteStream; @@ -41,6 +42,8 @@ enum ReaderState { }; class Reader { + Common::RandomSource _randomSource; //for temp file names + ReaderState _state; byte *_content; uint32 _bytesLeft; @@ -62,6 +65,8 @@ class Reader { bool _isFileField; bool _isBadRequest; + void cleanup(); + bool readHeaders(); //true when ended reading bool readContent(); //true when ended reading void handleHeaders(Common::String headers); @@ -84,6 +89,8 @@ public: Reader(); ~Reader(); + Reader &operator=(Reader &r); + bool readRequest(); //true when ended reading void setContent(byte *buffer, uint32 size); bool badRequest(); |