libreoffice-online/loolwsd/TileCache.cpp

155 lines
4.6 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2015-03-12 09:18:35 -05:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "config.h"
#include <cassert>
2015-03-12 09:18:35 -05:00
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
2015-03-12 09:18:35 -05:00
#include <Poco/File.h>
#include <Poco/Path.h>
#include <Poco/SHA1Engine.h>
#include <Poco/StringTokenizer.h>
#include <Poco/Util/Application.h>
2015-03-12 09:18:35 -05:00
#include "TileCache.hpp"
2015-03-12 18:34:42 -05:00
TileCache::TileCache(const std::string& docURL) :
_docURL(docURL)
{
Poco::File dir(cacheDirName());
2015-03-12 09:18:35 -05:00
// TODO: Actually handle URLs (file: and http:), not file names.
2015-03-12 18:34:42 -05:00
if (dir.exists() && dir.isDirectory() && Poco::File(_docURL).exists() && Poco::File(_docURL).isFile())
{
if (getLastModified() != Poco::File(_docURL).getLastModified())
{
dir.remove(true);
}
2015-03-12 09:18:35 -05:00
}
}
std::unique_ptr<std::fstream> TileCache::lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
2015-03-12 09:18:35 -05:00
{
2015-03-12 18:34:42 -05:00
std::string dirName = cacheDirName();
if (!Poco::File(dirName).exists() || !Poco::File(dirName).isDirectory())
return nullptr;
2015-03-12 09:18:35 -05:00
std::string fileName = dirName + "/" + cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
2015-03-12 18:34:42 -05:00
std::unique_ptr<std::fstream> result(new std::fstream(fileName, std::ios::in));
2015-03-12 09:18:35 -05:00
return result;
}
void TileCache::saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size)
2015-03-12 09:18:35 -05:00
{
2015-03-12 18:34:42 -05:00
std::string dirName = cacheDirName();
2015-03-12 09:18:35 -05:00
2015-03-12 18:34:42 -05:00
Poco::File(dirName).createDirectories();
2015-03-12 09:18:35 -05:00
std::string fileName = dirName + "/" + cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
2015-03-13 07:17:51 -05:00
2015-03-12 18:34:42 -05:00
std::fstream outStream(fileName, std::ios::out);
2015-03-12 09:18:35 -05:00
outStream.write(data, size);
outStream.close();
2015-03-12 18:34:42 -05:00
// TODO: Actually handle URLs (file: and http:), not file names.
if (!Poco::File(_docURL).exists() || !Poco::File(_docURL).isFile())
return;
2015-03-12 18:34:42 -05:00
std::fstream modTimeFile(dirName + "/modtime.txt", std::ios::out);
modTimeFile << Poco::File(_docURL).getLastModified().raw() << std::endl;
modTimeFile.close();
}
2015-03-13 07:17:51 -05:00
std::string TileCache::getStatus()
{
std::string dirName = cacheDirName();
if (!Poco::File(dirName).exists() || !Poco::File(dirName).isDirectory())
return "";
2015-03-13 07:17:51 -05:00
std::string fileName = dirName + "/status.txt";
std::fstream statusStream(fileName, std::ios::in);
if (!statusStream.is_open())
return "";
2015-03-13 07:17:51 -05:00
std::vector<char> result;
statusStream.seekg(0, std::ios_base::end);
std::streamsize size = statusStream.tellg();
result.resize(size);
statusStream.seekg(0, std::ios_base::beg);
statusStream.read(result.data(), size);
statusStream.close();
if (result[result.size()-1] == '\n')
result.resize(result.size() - 1);
2015-03-13 07:17:51 -05:00
return std::string(result.data(), result.size());
}
void TileCache::saveStatus(const std::string& status)
{
std::string dirName = cacheDirName();
Poco::File(dirName).createDirectories();
Poco::StringTokenizer tokens(status, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
assert(tokens[0] == "status:");
2015-03-13 07:17:51 -05:00
std::string fileName = dirName + "/status.txt";
std::fstream statusStream(fileName, std::ios::out);
2015-03-13 07:17:51 -05:00
if (!statusStream.is_open())
return;
statusStream << status << std::endl;
statusStream.close();
}
2015-03-12 18:34:42 -05:00
std::string TileCache::cacheDirName()
{
Poco::SHA1Engine digestEngine;
digestEngine.update(_docURL.c_str(), _docURL.size());
return (LOOLWSD_CACHEDIR "/" +
Poco::DigestEngine::digestToHex(digestEngine.digest()).insert(3, "/").insert(2, "/").insert(1, "/"));
}
std::string TileCache::cacheFileName(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
2015-03-12 18:34:42 -05:00
{
return (std::to_string(part) + "_" +
std::to_string(width) + "x" + std::to_string(height) + "." +
2015-03-12 18:34:42 -05:00
std::to_string(tilePosX) + "," + std::to_string(tilePosY) + "." +
std::to_string(tileWidth) + "x" + std::to_string(tileHeight) + ".png");
}
Poco::Timestamp TileCache::getLastModified()
{
std::fstream modTimeFile(cacheDirName() + "/modtime.txt", std::ios::in);
if (!modTimeFile.is_open())
return 0;
Poco::Timestamp::TimeVal result;
modTimeFile >> result;
modTimeFile.close();
return result;
2015-03-12 09:18:35 -05:00
}
2015-03-12 18:34:42 -05:00
2015-03-12 09:18:35 -05:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */