Mercurial > hg > orthanc
comparison Core/Toolbox.cpp @ 948:e57e08ed510f dicom-rt
integration mainline -> dicom-rt
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Jun 2014 13:57:05 +0200 |
parents | 8cfc6119a5bd b3f6fb1130cd |
children | a6fda0806382 |
comparison
equal
deleted
inserted
replaced
767:c19552f604d5 | 948:e57e08ed510f |
---|---|
28 * You should have received a copy of the GNU General Public License | 28 * You should have received a copy of the GNU General Public License |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 29 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
30 **/ | 30 **/ |
31 | 31 |
32 | 32 |
33 #include "PrecompiledHeaders.h" | |
33 #include "Toolbox.h" | 34 #include "Toolbox.h" |
34 | 35 |
35 #include "OrthancException.h" | 36 #include "OrthancException.h" |
36 | 37 |
37 #include <stdint.h> | 38 #include <stdint.h> |
51 #if defined(__APPLE__) && defined(__MACH__) | 52 #if defined(__APPLE__) && defined(__MACH__) |
52 #include <mach-o/dyld.h> /* _NSGetExecutablePath */ | 53 #include <mach-o/dyld.h> /* _NSGetExecutablePath */ |
53 #include <limits.h> /* PATH_MAX */ | 54 #include <limits.h> /* PATH_MAX */ |
54 #endif | 55 #endif |
55 | 56 |
56 #if defined(__linux) | 57 #if defined(__linux) || defined(__FreeBSD_kernel__) |
57 #include <limits.h> /* PATH_MAX */ | 58 #include <limits.h> /* PATH_MAX */ |
58 #include <signal.h> | 59 #include <signal.h> |
59 #include <unistd.h> | 60 #include <unistd.h> |
60 #endif | 61 #endif |
61 | 62 |
62 #if BOOST_HAS_LOCALE == 1 | 63 #if BOOST_HAS_LOCALE != 1 |
64 #error Since version 0.7.6, Orthanc entirely relies on boost::locale | |
65 #endif | |
66 | |
63 #include <boost/locale.hpp> | 67 #include <boost/locale.hpp> |
64 #else | |
65 #include <iconv.h> | |
66 #endif | |
67 | 68 |
68 #include "../Resources/md5/md5.h" | 69 #include "../Resources/md5/md5.h" |
69 #include "../Resources/base64/base64.h" | 70 #include "../Resources/base64/base64.h" |
70 | 71 |
71 | 72 |
72 #ifdef _MSC_VER | 73 #ifdef _MSC_VER |
73 // Patch for the missing "_strtoll" symbol when compiling with Visual Studio | 74 // Patch for the missing "_strtoll" symbol when compiling with Visual Studio |
74 extern "C" | 75 extern "C" |
75 { | 76 { |
76 int64_t _strtoi64(const char *nptr, char **endptr, int base); | 77 int64_t _strtoi64(const char *nptr, char **endptr, int base); |
77 int64_t strtoll(const char *nptr, char **endptr, int base) | 78 int64_t strtoll(const char *nptr, char **endptr, int base) |
78 { | 79 { |
79 return _strtoi64(nptr, endptr, base); | 80 return _strtoi64(nptr, endptr, base); |
80 } | 81 } |
81 } | |
82 #endif | |
83 | |
84 | |
85 #if BOOST_HAS_LOCALE == 0 | |
86 namespace | |
87 { | |
88 class IconvRabi | |
89 { | |
90 private: | |
91 iconv_t context_; | |
92 | |
93 public: | |
94 IconvRabi(const char* tocode, const char* fromcode) | |
95 { | |
96 context_ = iconv_open(tocode, fromcode); | |
97 if (!context_) | |
98 { | |
99 throw Orthanc::OrthancException("Unknown code page"); | |
100 } | |
101 } | |
102 | |
103 ~IconvRabi() | |
104 { | |
105 iconv_close(context_); | |
106 } | |
107 | |
108 std::string Convert(const std::string& source) | |
109 { | |
110 if (source.size() == 0) | |
111 { | |
112 return ""; | |
113 } | |
114 | |
115 std::string result; | |
116 char* sourcePos = const_cast<char*>(&source[0]); | |
117 size_t sourceLeft = source.size(); | |
118 | |
119 std::vector<char> storage(source.size() + 10); | |
120 | |
121 while (sourceLeft > 0) | |
122 { | |
123 char* tmp = &storage[0]; | |
124 size_t outputLeft = storage.size(); | |
125 size_t err = iconv(context_, &sourcePos, &sourceLeft, &tmp, &outputLeft); | |
126 if (err < 0) | |
127 { | |
128 throw Orthanc::OrthancException("Bad character in sequence"); | |
129 } | |
130 | |
131 size_t count = storage.size() - outputLeft; | |
132 result += std::string(&storage[0], count); | |
133 } | |
134 | |
135 return result; | |
136 } | |
137 }; | |
138 } | 82 } |
139 #endif | 83 #endif |
140 | 84 |
141 | 85 |
142 namespace Orthanc | 86 namespace Orthanc |
159 | 103 |
160 void Toolbox::USleep(uint64_t microSeconds) | 104 void Toolbox::USleep(uint64_t microSeconds) |
161 { | 105 { |
162 #if defined(_WIN32) | 106 #if defined(_WIN32) |
163 ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000))); | 107 ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000))); |
164 #elif defined(__linux) | 108 #elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD_kernel__) |
165 usleep(microSeconds); | 109 usleep(microSeconds); |
166 #else | 110 #else |
167 #error Support your platform here | 111 #error Support your platform here |
168 #endif | 112 #endif |
169 } | 113 } |
489 result[2 * i + 1] = GetHexadecimalCharacter(actualHash[i] % 16); | 433 result[2 * i + 1] = GetHexadecimalCharacter(actualHash[i] % 16); |
490 } | 434 } |
491 } | 435 } |
492 | 436 |
493 | 437 |
494 std::string Toolbox::EncodeBase64(const std::string& data) | 438 void Toolbox::EncodeBase64(std::string& result, |
495 { | 439 const std::string& data) |
496 return base64_encode(data); | 440 { |
497 } | 441 result = base64_encode(data); |
498 | 442 } |
499 std::string Toolbox::DecodeBase64(const std::string& data) | 443 |
500 { | 444 void Toolbox::DecodeBase64(std::string& result, |
501 return base64_decode(data); | 445 const std::string& data) |
446 { | |
447 result = base64_decode(data); | |
502 } | 448 } |
503 | 449 |
504 | 450 |
505 #if defined(_WIN32) | 451 #if defined(_WIN32) |
506 std::string Toolbox::GetPathToExecutable() | 452 std::string Toolbox::GetPathToExecutable() |
510 std::vector<char> buffer(32768); | 456 std::vector<char> buffer(32768); |
511 /*int bytes =*/ GetModuleFileNameA(NULL, &buffer[0], static_cast<DWORD>(buffer.size() - 1)); | 457 /*int bytes =*/ GetModuleFileNameA(NULL, &buffer[0], static_cast<DWORD>(buffer.size() - 1)); |
512 return std::string(&buffer[0]); | 458 return std::string(&buffer[0]); |
513 } | 459 } |
514 | 460 |
515 #elif defined(__linux) | 461 #elif defined(__linux) || defined(__FreeBSD_kernel__) |
516 std::string Toolbox::GetPathToExecutable() | 462 std::string Toolbox::GetPathToExecutable() |
517 { | 463 { |
518 std::vector<char> buffer(PATH_MAX + 1); | 464 std::vector<char> buffer(PATH_MAX + 1); |
519 ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1); | 465 ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1); |
520 if (bytes == 0) | 466 if (bytes == 0) |
549 | 495 |
550 | 496 |
551 std::string Toolbox::ConvertToUtf8(const std::string& source, | 497 std::string Toolbox::ConvertToUtf8(const std::string& source, |
552 const char* fromEncoding) | 498 const char* fromEncoding) |
553 { | 499 { |
554 #if BOOST_HAS_LOCALE == 1 | |
555 try | 500 try |
556 { | 501 { |
557 return boost::locale::conv::to_utf<char>(source, fromEncoding); | 502 return boost::locale::conv::to_utf<char>(source, fromEncoding); |
558 } | 503 } |
559 catch (std::runtime_error&) | 504 catch (std::runtime_error&) |
560 { | 505 { |
561 // Bad input string or bad encoding | 506 // Bad input string or bad encoding |
562 return ConvertToAscii(source); | 507 return ConvertToAscii(source); |
563 } | 508 } |
564 #else | |
565 IconvRabi iconv("UTF-8", fromEncoding); | |
566 try | |
567 { | |
568 return iconv.Convert(source); | |
569 } | |
570 catch (OrthancException) | |
571 { | |
572 return ConvertToAscii(source); | |
573 } | |
574 #endif | |
575 } | 509 } |
576 | 510 |
577 | 511 |
578 std::string Toolbox::ConvertToAscii(const std::string& source) | 512 std::string Toolbox::ConvertToAscii(const std::string& source) |
579 { | 513 { |
580 std::string result; | 514 std::string result; |
581 | 515 |
582 result.reserve(source.size()); | 516 result.reserve(source.size() + 1); |
583 for (size_t i = 0; i < source.size(); i++) | 517 for (size_t i = 0; i < source.size(); i++) |
584 { | 518 { |
585 if (source[i] < 128 && source[i] >= 0 && !iscntrl(source[i])) | 519 if (source[i] < 128 && source[i] >= 0 && !iscntrl(source[i])) |
586 { | 520 { |
587 result.push_back(source[i]); | 521 result.push_back(source[i]); |
801 } | 735 } |
802 } | 736 } |
803 | 737 |
804 result.push_back(currentItem); | 738 result.push_back(currentItem); |
805 } | 739 } |
740 | |
741 | |
742 void Toolbox::DecodeDataUriScheme(std::string& mime, | |
743 std::string& content, | |
744 const std::string& source) | |
745 { | |
746 boost::regex pattern("data:([^;]+);base64,([a-zA-Z0-9=+/]*)", | |
747 boost::regex::icase /* case insensitive search */); | |
748 | |
749 boost::cmatch what; | |
750 if (regex_match(source.c_str(), what, pattern)) | |
751 { | |
752 mime = what[1]; | |
753 content = what[2]; | |
754 } | |
755 else | |
756 { | |
757 throw OrthancException(ErrorCode_BadFileFormat); | |
758 } | |
759 } | |
760 | |
761 | |
762 void Toolbox::CreateDirectory(const std::string& path) | |
763 { | |
764 if (boost::filesystem::exists(path)) | |
765 { | |
766 if (!boost::filesystem::is_directory(path)) | |
767 { | |
768 throw OrthancException("Cannot create the directory over an existing file: " + path); | |
769 } | |
770 } | |
771 else | |
772 { | |
773 if (!boost::filesystem::create_directories(path)) | |
774 { | |
775 throw OrthancException("Unable to create the directory: " + path); | |
776 } | |
777 } | |
778 } | |
806 } | 779 } |
807 | 780 |