comparison Orthanc/Core/Toolbox.cpp @ 141:9362080e5e3d

sync
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 15 Jul 2016 12:00:11 +0200
parents d73006baca3f
children d850500b8ca6
comparison
equal deleted inserted replaced
140:31615831e42d 141:9362080e5e3d
109 #endif 109 #endif
110 110
111 111
112 namespace Orthanc 112 namespace Orthanc
113 { 113 {
114 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
114 static bool finish_; 115 static bool finish_;
115 static ServerBarrierEvent barrierEvent_; 116 static ServerBarrierEvent barrierEvent_;
116 117
117 #if defined(_WIN32) 118 #if defined(_WIN32)
118 static BOOL WINAPI ConsoleControlHandler(DWORD dwCtrlType) 119 static BOOL WINAPI ConsoleControlHandler(DWORD dwCtrlType)
186 ServerBarrierEvent Toolbox::ServerBarrier() 187 ServerBarrierEvent Toolbox::ServerBarrier()
187 { 188 {
188 const bool stopFlag = false; 189 const bool stopFlag = false;
189 return ServerBarrierInternal(&stopFlag); 190 return ServerBarrierInternal(&stopFlag);
190 } 191 }
192 #endif /* ORTHANC_SANDBOXED */
191 193
192 194
193 void Toolbox::ToUpperCase(std::string& s) 195 void Toolbox::ToUpperCase(std::string& s)
194 { 196 {
195 std::transform(s.begin(), s.end(), s.begin(), toupper); 197 std::transform(s.begin(), s.end(), s.begin(), toupper);
226 228
227 return size; 229 return size;
228 } 230 }
229 231
230 232
233 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
231 void Toolbox::ReadFile(std::string& content, 234 void Toolbox::ReadFile(std::string& content,
232 const std::string& path) 235 const std::string& path)
233 { 236 {
234 if (!IsRegularFile(path)) 237 if (!IsRegularFile(path))
235 { 238 {
251 f.read(reinterpret_cast<char*>(&content[0]), size); 254 f.read(reinterpret_cast<char*>(&content[0]), size);
252 } 255 }
253 256
254 f.close(); 257 f.close();
255 } 258 }
256 259 #endif
257 260
261
262 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
258 bool Toolbox::ReadHeader(std::string& header, 263 bool Toolbox::ReadHeader(std::string& header,
259 const std::string& path, 264 const std::string& path,
260 size_t headerSize) 265 size_t headerSize)
261 { 266 {
262 if (!IsRegularFile(path)) 267 if (!IsRegularFile(path))
296 301
297 f.close(); 302 f.close();
298 303
299 return full; 304 return full;
300 } 305 }
301 306 #endif
302 307
308
309 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
303 void Toolbox::WriteFile(const void* content, 310 void Toolbox::WriteFile(const void* content,
304 size_t size, 311 size_t size,
305 const std::string& path) 312 const std::string& path)
306 { 313 {
307 boost::filesystem::ofstream f; 314 boost::filesystem::ofstream f;
316 f.write(reinterpret_cast<const char*>(content), size); 323 f.write(reinterpret_cast<const char*>(content), size);
317 } 324 }
318 325
319 f.close(); 326 f.close();
320 } 327 }
321 328 #endif
322 329
330
331 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
323 void Toolbox::WriteFile(const std::string& content, 332 void Toolbox::WriteFile(const std::string& content,
324 const std::string& path) 333 const std::string& path)
325 { 334 {
326 WriteFile(content.size() > 0 ? content.c_str() : NULL, 335 WriteFile(content.size() > 0 ? content.c_str() : NULL,
327 content.size(), path); 336 content.size(), path);
328 } 337 }
329 338 #endif
330 339
340
341 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
331 void Toolbox::RemoveFile(const std::string& path) 342 void Toolbox::RemoveFile(const std::string& path)
332 { 343 {
333 if (boost::filesystem::exists(path)) 344 if (boost::filesystem::exists(path))
334 { 345 {
335 if (IsRegularFile(path)) 346 if (IsRegularFile(path))
340 { 351 {
341 throw OrthancException(ErrorCode_RegularFileExpected); 352 throw OrthancException(ErrorCode_RegularFileExpected);
342 } 353 }
343 } 354 }
344 } 355 }
345 356 #endif
346 357
347 358
348 void Toolbox::SplitUriComponents(UriComponents& components, 359 void Toolbox::SplitUriComponents(UriComponents& components,
349 const std::string& uri) 360 const std::string& uri)
350 { 361 {
511 } 522 }
512 } 523 }
513 524
514 525
515 526
527 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
516 uint64_t Toolbox::GetFileSize(const std::string& path) 528 uint64_t Toolbox::GetFileSize(const std::string& path)
517 { 529 {
518 try 530 try
519 { 531 {
520 return static_cast<uint64_t>(boost::filesystem::file_size(path)); 532 return static_cast<uint64_t>(boost::filesystem::file_size(path));
522 catch (boost::filesystem::filesystem_error&) 534 catch (boost::filesystem::filesystem_error&)
523 { 535 {
524 throw OrthancException(ErrorCode_InexistentFile); 536 throw OrthancException(ErrorCode_InexistentFile);
525 } 537 }
526 } 538 }
539 #endif
527 540
528 541
529 #if !defined(ORTHANC_ENABLE_MD5) || ORTHANC_ENABLE_MD5 == 1 542 #if !defined(ORTHANC_ENABLE_MD5) || ORTHANC_ENABLE_MD5 == 1
530 static char GetHexadecimalCharacter(uint8_t value) 543 static char GetHexadecimalCharacter(uint8_t value)
531 { 544 {
675 _NSGetExecutablePath( pathbuf, &bufsize); 688 _NSGetExecutablePath( pathbuf, &bufsize);
676 689
677 return std::string(pathbuf); 690 return std::string(pathbuf);
678 } 691 }
679 692
693 #elif defined(ORTHANC_SANDBOXED) && ORTHANC_SANDBOXED == 1
694 // Sandboxed Orthanc, no access to the executable
695
680 #else 696 #else
681 #error Support your platform here 697 #error Support your platform here
682 #endif 698 #endif
683 699
684 700
701 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
685 std::string Toolbox::GetPathToExecutable() 702 std::string Toolbox::GetPathToExecutable()
686 { 703 {
687 boost::filesystem::path p(GetPathToExecutableInternal()); 704 boost::filesystem::path p(GetPathToExecutableInternal());
688 return boost::filesystem::absolute(p).string(); 705 return boost::filesystem::absolute(p).string();
689 } 706 }
692 std::string Toolbox::GetDirectoryOfExecutable() 709 std::string Toolbox::GetDirectoryOfExecutable()
693 { 710 {
694 boost::filesystem::path p(GetPathToExecutableInternal()); 711 boost::filesystem::path p(GetPathToExecutableInternal());
695 return boost::filesystem::absolute(p.parent_path()).string(); 712 return boost::filesystem::absolute(p.parent_path()).string();
696 } 713 }
714 #endif
697 715
698 716
699 static const char* GetBoostLocaleEncoding(const Encoding sourceEncoding) 717 static const char* GetBoostLocaleEncoding(const Encoding sourceEncoding)
700 { 718 {
701 switch (sourceEncoding) 719 switch (sourceEncoding)
1135 1153
1136 result.push_back(currentItem); 1154 result.push_back(currentItem);
1137 } 1155 }
1138 1156
1139 1157
1158 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
1140 void Toolbox::MakeDirectory(const std::string& path) 1159 void Toolbox::MakeDirectory(const std::string& path)
1141 { 1160 {
1142 if (boost::filesystem::exists(path)) 1161 if (boost::filesystem::exists(path))
1143 { 1162 {
1144 if (!boost::filesystem::is_directory(path)) 1163 if (!boost::filesystem::is_directory(path))
1152 { 1171 {
1153 throw OrthancException(ErrorCode_MakeDirectory); 1172 throw OrthancException(ErrorCode_MakeDirectory);
1154 } 1173 }
1155 } 1174 }
1156 } 1175 }
1157 1176 #endif
1158 1177
1178
1179 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
1159 bool Toolbox::IsExistingFile(const std::string& path) 1180 bool Toolbox::IsExistingFile(const std::string& path)
1160 { 1181 {
1161 return boost::filesystem::exists(path); 1182 return boost::filesystem::exists(path);
1162 } 1183 }
1184 #endif
1163 1185
1164 1186
1165 #if ORTHANC_PUGIXML_ENABLED == 1 1187 #if ORTHANC_PUGIXML_ENABLED == 1
1166 class ChunkedBufferWriter : public pugi::xml_writer 1188 class ChunkedBufferWriter : public pugi::xml_writer
1167 { 1189 {
1282 } 1304 }
1283 1305
1284 #endif 1306 #endif
1285 1307
1286 1308
1309 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
1287 void Toolbox::ExecuteSystemCommand(const std::string& command, 1310 void Toolbox::ExecuteSystemCommand(const std::string& command,
1288 const std::vector<std::string>& arguments) 1311 const std::vector<std::string>& arguments)
1289 { 1312 {
1290 // Convert the arguments as a C array 1313 // Convert the arguments as a C array
1291 std::vector<char*> args(arguments.size() + 2); 1314 std::vector<char*> args(arguments.size() + 2);
1339 #endif 1362 #endif
1340 1363
1341 throw OrthancException(ErrorCode_SystemCommand); 1364 throw OrthancException(ErrorCode_SystemCommand);
1342 } 1365 }
1343 } 1366 }
1367 #endif
1344 1368
1345 1369
1346 bool Toolbox::IsInteger(const std::string& str) 1370 bool Toolbox::IsInteger(const std::string& str)
1347 { 1371 {
1348 std::string s = StripSpaces(str); 1372 std::string s = StripSpaces(str);
1459 return static_cast<int>(getpid()); 1483 return static_cast<int>(getpid());
1460 #endif 1484 #endif
1461 } 1485 }
1462 1486
1463 1487
1488 #if !defined(ORTHANC_SANDBOXED) || ORTHANC_SANDBOXED != 1
1464 bool Toolbox::IsRegularFile(const std::string& path) 1489 bool Toolbox::IsRegularFile(const std::string& path)
1465 { 1490 {
1466 namespace fs = boost::filesystem; 1491 namespace fs = boost::filesystem;
1467 1492
1468 try 1493 try
1478 { 1503 {
1479 } 1504 }
1480 1505
1481 return false; 1506 return false;
1482 } 1507 }
1508 #endif
1509
1510
1511 FILE* Toolbox::OpenFile(const std::string& path,
1512 FileMode mode)
1513 {
1514 #if defined(_WIN32)
1515 // TODO Deal with special characters by converting to the current locale
1516 #endif
1517
1518 const char* m;
1519 switch (mode)
1520 {
1521 case FileMode_ReadBinary:
1522 m = "rb";
1523 break;
1524
1525 case FileMode_WriteBinary:
1526 m = "wb";
1527 break;
1528
1529 default:
1530 throw OrthancException(ErrorCode_ParameterOutOfRange);
1531 }
1532
1533 return fopen(path.c_str(), m);
1534 }
1535
1536
1537
1538 static bool IsUnreservedCharacter(char c)
1539 {
1540 // This function checks whether "c" is an unserved character
1541 // wrt. an URI percent-encoding
1542 // https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding%5Fin%5Fa%5FURI
1543
1544 return ((c >= 'A' && c <= 'Z') ||
1545 (c >= 'a' && c <= 'z') ||
1546 (c >= '0' && c <= '9') ||
1547 c == '-' ||
1548 c == '_' ||
1549 c == '.' ||
1550 c == '~');
1551 }
1552
1553 void Toolbox::UriEncode(std::string& target,
1554 const std::string& source)
1555 {
1556 // Estimate the length of the percent-encoded URI
1557 size_t length = 0;
1558
1559 for (size_t i = 0; i < source.size(); i++)
1560 {
1561 if (IsUnreservedCharacter(source[i]))
1562 {
1563 length += 1;
1564 }
1565 else
1566 {
1567 // This character must be percent-encoded
1568 length += 3;
1569 }
1570 }
1571
1572 target.clear();
1573 target.reserve(length);
1574
1575 for (size_t i = 0; i < source.size(); i++)
1576 {
1577 if (IsUnreservedCharacter(source[i]))
1578 {
1579 target.push_back(source[i]);
1580 }
1581 else
1582 {
1583 // This character must be percent-encoded
1584 uint8_t byte = static_cast<uint8_t>(source[i]);
1585 uint8_t a = byte >> 4;
1586 uint8_t b = byte & 0x0f;
1587
1588 target.push_back('%');
1589 target.push_back(a < 10 ? a + '0' : a - 10 + 'A');
1590 target.push_back(b < 10 ? b + '0' : b - 10 + 'A');
1591 }
1592 }
1593 }
1594
1595
1596 static bool HasField(const Json::Value& json,
1597 const std::string& key,
1598 Json::ValueType expectedType)
1599 {
1600 if (json.type() != Json::objectValue ||
1601 !json.isMember(key))
1602 {
1603 return false;
1604 }
1605 else if (json[key].type() == expectedType)
1606 {
1607 return true;
1608 }
1609 else
1610 {
1611 throw OrthancException(ErrorCode_BadParameterType);
1612 }
1613 }
1614
1615
1616 std::string Toolbox::GetJsonStringField(const Json::Value& json,
1617 const std::string& key,
1618 const std::string& defaultValue)
1619 {
1620 if (HasField(json, key, Json::stringValue))
1621 {
1622 return json[key].asString();
1623 }
1624 else
1625 {
1626 return defaultValue;
1627 }
1628 }
1629
1630
1631 bool Toolbox::GetJsonBooleanField(const ::Json::Value& json,
1632 const std::string& key,
1633 bool defaultValue)
1634 {
1635 if (HasField(json, key, Json::booleanValue))
1636 {
1637 return json[key].asBool();
1638 }
1639 else
1640 {
1641 return defaultValue;
1642 }
1643 }
1644
1645
1646 int Toolbox::GetJsonIntegerField(const ::Json::Value& json,
1647 const std::string& key,
1648 int defaultValue)
1649 {
1650 if (HasField(json, key, Json::intValue))
1651 {
1652 return json[key].asInt();
1653 }
1654 else
1655 {
1656 return defaultValue;
1657 }
1658 }
1659
1660
1661 unsigned int Toolbox::GetJsonUnsignedIntegerField(const ::Json::Value& json,
1662 const std::string& key,
1663 unsigned int defaultValue)
1664 {
1665 int v = GetJsonIntegerField(json, key, defaultValue);
1666
1667 if (v < 0)
1668 {
1669 throw OrthancException(ErrorCode_ParameterOutOfRange);
1670 }
1671 else
1672 {
1673 return static_cast<unsigned int>(v);
1674 }
1675 }
1483 } 1676 }
1484