Mercurial > hg > orthanc
diff Core/Toolbox.cpp @ 0:3959d33612cc
initial commit
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 19 Jul 2012 14:32:22 +0200 |
parents | |
children | 3a584803783e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/Toolbox.cpp Thu Jul 19 14:32:22 2012 +0200 @@ -0,0 +1,295 @@ +/** + * Palantir - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) 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 General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "Toolbox.h" + +#include "PalantirException.h" + +#include <string.h> +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> +#include <algorithm> + +#if defined(_WIN32) +#include <windows.h> +#endif + +#if defined(__linux) +#include <unistd.h> +#endif + +#include <signal.h> + +namespace Palantir +{ + static bool finish; + + static void SignalHandler(int) + { + finish = true; + } + + + void Toolbox::Sleep(uint32_t seconds) + { +#if defined(_WIN32) + ::Sleep(static_cast<DWORD>(seconds) * static_cast<DWORD>(1000)); +#elif defined(__linux) + usleep(static_cast<uint64_t>(seconds) * static_cast<uint64_t>(1000000)); +#else +#error Support your platform here +#endif + } + + void Toolbox::USleep(uint64_t microSeconds) + { +#if defined(_WIN32) + ::Sleep(microSeconds / static_cast<uint64_t>(1000)); +#elif defined(__linux) + usleep(microSeconds); +#else +#error Support your platform here +#endif + } + + + void Toolbox::ServerBarrier() + { + signal(SIGINT, SignalHandler); + +#if !defined(_WIN32) + signal(SIGQUIT, SignalHandler); +#endif + + finish = false; + while (!finish) + { + USleep(100000); + } + + signal(SIGINT, NULL); + +#if !defined(_WIN32) + signal(SIGQUIT, NULL); +#endif + } + + + + void Toolbox::ToUpperCase(std::string& s) + { + std::transform(s.begin(), s.end(), s.begin(), toupper); + } + + + void Toolbox::ToLowerCase(std::string& s) + { + std::transform(s.begin(), s.end(), s.begin(), tolower); + } + + + + void Toolbox::ReadFile(std::string& content, + const std::string& path) + { + boost::filesystem::ifstream f; + f.open(path, std::ifstream::in | std::ios::binary); + if (!f.good()) + { + throw PalantirException("Unable to open a file"); + } + + // http://www.cplusplus.com/reference/iostream/istream/tellg/ + f.seekg(0, std::ios::end); + std::streamsize size = f.tellg(); + f.seekg(0, std::ios::beg); + + content.resize(size); + if (size != 0) + { + f.read(reinterpret_cast<char*>(&content[0]), size); + } + + f.close(); + } + + + void Toolbox::RemoveFile(const std::string& path) + { + if (boost::filesystem::exists(path)) + { + if (boost::filesystem::is_regular_file(path)) + boost::filesystem::remove(path); + else + throw PalantirException("The path is not a regular file: " + path); + } + } + + + + void Toolbox::SplitUriComponents(UriComponents& components, + const std::string& uri) + { + static const char URI_SEPARATOR = '/'; + + components.clear(); + + if (uri.size() == 0 || + uri[0] != URI_SEPARATOR) + { + throw PalantirException(ErrorCode_UriSyntax); + } + + // Count the number of slashes in the URI to make an assumption + // about the number of components in the URI + unsigned int estimatedSize = 0; + for (unsigned int i = 0; i < uri.size(); i++) + { + if (uri[i] == URI_SEPARATOR) + estimatedSize++; + } + + components.reserve(estimatedSize - 1); + + unsigned int start = 1; + unsigned int end = 1; + while (end < uri.size()) + { + // This is the loop invariant + assert(uri[start - 1] == '/' && (end >= start)); + + if (uri[end] == '/') + { + components.push_back(std::string(&uri[start], end - start)); + end++; + start = end; + } + else + { + end++; + } + } + + if (start < uri.size()) + { + components.push_back(std::string(&uri[start], end - start)); + } + } + + + bool Toolbox::IsChildUri(const UriComponents& baseUri, + const UriComponents& testedUri) + { + if (testedUri.size() < baseUri.size()) + { + return false; + } + + for (size_t i = 0; i < baseUri.size(); i++) + { + if (baseUri[i] != testedUri[i]) + return false; + } + + return true; + } + + + std::string Toolbox::AutodetectMimeType(const std::string& path) + { + std::string contentType; + size_t lastDot = path.rfind('.'); + size_t lastSlash = path.rfind('/'); + + if (lastDot == std::string::npos || + (lastSlash != std::string::npos && lastDot < lastSlash)) + { + // No trailing dot, unable to detect the content type + } + else + { + const char* extension = &path[lastDot + 1]; + + // http://en.wikipedia.org/wiki/Mime_types + // Text types + if (!strcmp(extension, "txt")) + contentType = "text/plain"; + else if (!strcmp(extension, "html")) + contentType = "text/html"; + else if (!strcmp(extension, "xml")) + contentType = "text/xml"; + else if (!strcmp(extension, "css")) + contentType = "text/css"; + + // Application types + else if (!strcmp(extension, "js")) + contentType = "application/javascript"; + else if (!strcmp(extension, "json")) + contentType = "application/json"; + else if (!strcmp(extension, "pdf")) + contentType = "application/pdf"; + + // Images types + else if (!strcmp(extension, "jpg") || !strcmp(extension, "jpeg")) + contentType = "image/jpeg"; + else if (!strcmp(extension, "gif")) + contentType = "image/gif"; + else if (!strcmp(extension, "png")) + contentType = "image/png"; + } + + return contentType; + } + + + std::string Toolbox::FlattenUri(const UriComponents& components, + size_t fromLevel) + { + if (components.size() <= fromLevel) + { + return "/"; + } + else + { + std::string r; + + for (size_t i = fromLevel; i < components.size(); i++) + { + r += "/" + components[i]; + } + + return r; + } + } + + + + uint64_t Toolbox::GetFileSize(const std::string& path) + { + try + { + return static_cast<uint64_t>(boost::filesystem::file_size(path)); + } + catch (boost::filesystem::filesystem_error) + { + throw PalantirException(ErrorCode_InexistentFile); + } + } +}