/* open source routing machine Copyright (C) Dennis Luxen, others 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU AFFERO General Public License as published by the Free Software Foundation; either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. */ #include "TemporaryStorage.h" TemporaryStorage::TemporaryStorage() { tempDirectory = boost::filesystem::temp_directory_path(); } TemporaryStorage & TemporaryStorage::GetInstance(){ static TemporaryStorage runningInstance; return runningInstance; } TemporaryStorage::~TemporaryStorage() { removeAll(); } void TemporaryStorage::removeAll() { boost::mutex::scoped_lock lock(mutex); for(unsigned slot_id = 0; slot_id < vectorOfStreamDatas.size(); ++slot_id) { deallocateSlot(slot_id); } vectorOfStreamDatas.clear(); } int TemporaryStorage::allocateSlot() { boost::mutex::scoped_lock lock(mutex); try { vectorOfStreamDatas.push_back(StreamData()); //SimpleLogger().Write() << "created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile; } catch(boost::filesystem::filesystem_error & e) { abort(e); } return vectorOfStreamDatas.size() - 1; } void TemporaryStorage::deallocateSlot(int slotID) { try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); if(!boost::filesystem::exists(data.pathToTemporaryFile)) { return; } if(data.streamToTemporaryFile->is_open()) { data.streamToTemporaryFile->close(); } boost::filesystem::remove(data.pathToTemporaryFile); } catch(boost::filesystem::filesystem_error & e) { abort(e); } } void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize size) { try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); BOOST_ASSERT_MSG( data.writeMode, "Writing after first read is not allowed" ); data.streamToTemporaryFile->write(pointer, size); } catch(boost::filesystem::filesystem_error & e) { abort(e); } } void TemporaryStorage::readFromSlot(int slotID, char * pointer, std::streamsize size) { try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); if(data.writeMode) { data.writeMode = false; data.streamToTemporaryFile->seekg(0, data.streamToTemporaryFile->beg); } data.streamToTemporaryFile->read(pointer, size); } catch(boost::filesystem::filesystem_error & e) { abort(e); } } unsigned TemporaryStorage::getFreeBytesOnTemporaryDevice() { boost::filesystem::space_info tempSpaceInfo; try { tempSpaceInfo = boost::filesystem::space(tempDirectory); } catch(boost::filesystem::filesystem_error & e) { abort(e); } return tempSpaceInfo.available; } boost::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) { boost::filesystem::fstream::pos_type position; try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); position = data.streamToTemporaryFile->tellp(); } catch(boost::filesystem::filesystem_error & e) { abort(e); } return position; } void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) { removeAll(); } void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) { try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); data.streamToTemporaryFile->seekg(position); } catch(boost::filesystem::filesystem_error & e) { abort(e); } }