changeset 12:9220cf4a63d5

sync
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 09 Nov 2016 14:14:34 +0100
parents 4b7e0244881f
children b1eb80ca0d2b
files Framework/Orthanc/Core/Enumerations.cpp Framework/Orthanc/Core/Enumerations.h Framework/Orthanc/Core/HttpClient.cpp Framework/Orthanc/Core/Logging.cpp Framework/Orthanc/Core/Logging.h Framework/Orthanc/Core/PrecompiledHeaders.h Framework/Orthanc/Core/Toolbox.cpp Framework/Orthanc/Core/Toolbox.h Framework/Orthanc/Resources/CMake/BoostConfiguration.cmake Framework/Orthanc/Resources/CMake/DownloadPackage.cmake Framework/Orthanc/Resources/CMake/LibIconvConfiguration.cmake Framework/Orthanc/Resources/CMake/LibJpegConfiguration.cmake Framework/Orthanc/Resources/CMake/LibPngConfiguration.cmake Framework/Orthanc/Resources/CMake/OpenSslConfiguration.cmake Framework/Orthanc/Resources/CMake/ZlibConfiguration.cmake Framework/Orthanc/Resources/ThirdParty/VisualStudio/stdint.h
diffstat 16 files changed, 183 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Orthanc/Core/Enumerations.cpp	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Enumerations.cpp	Wed Nov 09 14:14:34 2016 +0100
@@ -64,7 +64,7 @@
         return "Parameter out of range";
 
       case ErrorCode_NotEnoughMemory:
-        return "Not enough memory";
+        return "The server hosting Orthanc is running out of memory";
 
       case ErrorCode_BadParameterType:
         return "Bad type for a parameter";
@@ -156,6 +156,9 @@
       case ErrorCode_NotAcceptable:
         return "Cannot send a response which is acceptable according to the Accept HTTP header";
 
+      case ErrorCode_NullPointer:
+        return "Cannot handle a NULL pointer";
+
       case ErrorCode_SQLiteNotOpened:
         return "SQLite: The database is not opened";
 
--- a/Framework/Orthanc/Core/Enumerations.h	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Enumerations.h	Wed Nov 09 14:14:34 2016 +0100
@@ -52,7 +52,7 @@
     ErrorCode_Plugin = 1    /*!< Error encountered within the plugin engine */,
     ErrorCode_NotImplemented = 2    /*!< Not implemented yet */,
     ErrorCode_ParameterOutOfRange = 3    /*!< Parameter out of range */,
-    ErrorCode_NotEnoughMemory = 4    /*!< Not enough memory */,
+    ErrorCode_NotEnoughMemory = 4    /*!< The server hosting Orthanc is running out of memory */,
     ErrorCode_BadParameterType = 5    /*!< Bad type for a parameter */,
     ErrorCode_BadSequenceOfCalls = 6    /*!< Bad sequence of calls */,
     ErrorCode_InexistentItem = 7    /*!< Accessing an inexistent item */,
@@ -83,6 +83,7 @@
     ErrorCode_StorageAreaPlugin = 32    /*!< Error in the plugin implementing a custom storage area */,
     ErrorCode_EmptyRequest = 33    /*!< The request is empty */,
     ErrorCode_NotAcceptable = 34    /*!< Cannot send a response which is acceptable according to the Accept HTTP header */,
+    ErrorCode_NullPointer = 35    /*!< Cannot handle a NULL pointer */,
     ErrorCode_SQLiteNotOpened = 1000    /*!< SQLite: The database is not opened */,
     ErrorCode_SQLiteAlreadyOpened = 1001    /*!< SQLite: Connection is already open */,
     ErrorCode_SQLiteCannotOpen = 1002    /*!< SQLite: Unable to open the database */,
--- a/Framework/Orthanc/Core/HttpClient.cpp	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/HttpClient.cpp	Wed Nov 09 14:14:34 2016 +0100
@@ -44,7 +44,7 @@
 #include <boost/thread/mutex.hpp>
 
 
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
 // For OpenSSL initialization and finalization
 #  include <openssl/conf.h>
 #  include <openssl/engine.h>
@@ -54,7 +54,7 @@
 #endif
 
 
-#if ORTHANC_PKCS11_ENABLED == 1
+#if ORTHANC_ENABLE_PKCS11 == 1
 #  include "Pkcs11.h"
 #endif
 
@@ -161,7 +161,7 @@
       return timeout_;
     }
 
-#if ORTHANC_PKCS11_ENABLED == 1
+#if ORTHANC_ENABLE_PKCS11 == 1
     bool IsPkcs11Initialized()
     {
       boost::mutex::scoped_lock lock(mutex_);
@@ -435,7 +435,7 @@
       CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, &headerParameters));
     }
 
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
     // Setup HTTPS-related options
 
     if (verifyPeers_)
@@ -461,7 +461,7 @@
 
     if (pkcs11Enabled_)
     {
-#if ORTHANC_PKCS11_ENABLED == 1
+#if ORTHANC_ENABLE_PKCS11 == 1
       if (GlobalParameters::GetInstance().IsPkcs11Initialized())
       {
         CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLENGINE, Pkcs11::GetEngineIdentifier()));
@@ -480,7 +480,7 @@
     }
     else if (!clientCertificateFile_.empty())
     {
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
       CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERTTYPE, "PEM"));
       CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERT, clientCertificateFile_.c_str()));
 
@@ -671,7 +671,7 @@
   void HttpClient::ConfigureSsl(bool httpsVerifyPeers,
                                 const std::string& httpsVerifyCertificates)
   {
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
     if (httpsVerifyPeers)
     {
       if (httpsVerifyCertificates.empty())
@@ -696,7 +696,7 @@
   
   void HttpClient::GlobalInitialize()
   {
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
     CheckCode(curl_global_init(CURL_GLOBAL_ALL));
 #else
     CheckCode(curl_global_init(CURL_GLOBAL_ALL & ~CURL_GLOBAL_SSL));
@@ -708,7 +708,7 @@
   {
     curl_global_cleanup();
 
-#if ORTHANC_PKCS11_ENABLED == 1
+#if ORTHANC_ENABLE_PKCS11 == 1
     Pkcs11::Finalize();
 #endif
   }
@@ -796,7 +796,7 @@
                                     const std::string& pin,
                                     bool verbose)
   {
-#if ORTHANC_PKCS11_ENABLED == 1
+#if ORTHANC_ENABLE_PKCS11 == 1
     LOG(INFO) << "Initializing PKCS#11 using " << module 
               << (pin.empty() ? " (no PIN provided)" : " (PIN is provided)");
     GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose);    
@@ -809,7 +809,7 @@
 
   void HttpClient::InitializeOpenSsl()
   {
-#if ORTHANC_SSL_ENABLED == 1
+#if ORTHANC_ENABLE_SSL == 1
     // https://wiki.openssl.org/index.php/Library_Initialization
     SSL_library_init();
     SSL_load_error_strings();
@@ -821,7 +821,7 @@
 
   void HttpClient::FinalizeOpenSsl()
   {
- #if ORTHANC_SSL_ENABLED == 1
+ #if ORTHANC_ENABLE_SSL == 1
     // Finalize OpenSSL
     // https://wiki.openssl.org/index.php/Library_Initialization#Cleanup
     FIPS_mode_set(0);
--- a/Framework/Orthanc/Core/Logging.cpp	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Logging.cpp	Wed Nov 09 14:14:34 2016 +0100
@@ -318,113 +318,123 @@
         return;
       }
 
-      LogLevel l = StringToLogLevel(level);
-      
-      if ((l == LogLevel_Info  && !loggingContext_->infoEnabled_) ||
-          (l == LogLevel_Trace && !loggingContext_->traceEnabled_))
+      try
       {
-        // This logging level is disabled, directly exit and unlock
-        // the mutex to speed-up things. The stream is set to "/dev/null"
-        lock_.unlock();
-        return;
-      }
+        LogLevel l = StringToLogLevel(level);
+      
+        if ((l == LogLevel_Info  && !loggingContext_->infoEnabled_) ||
+            (l == LogLevel_Trace && !loggingContext_->traceEnabled_))
+        {
+          // This logging level is disabled, directly exit and unlock
+          // the mutex to speed-up things. The stream is set to "/dev/null"
+          lock_.unlock();
+          return;
+        }
 
-      // Compute the header of the line, temporary release the lock as
-      // this is a time-consuming operation
-      lock_.unlock();
-      std::string header;
+        // Compute the header of the line, temporary release the lock as
+        // this is a time-consuming operation
+        lock_.unlock();
+        std::string header;
 
-      {
-        boost::filesystem::path path(file);
-        boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
-        boost::posix_time::time_duration duration = now.time_of_day();
+        {
+          boost::filesystem::path path(file);
+          boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+          boost::posix_time::time_duration duration = now.time_of_day();
 
-        /**
-           From Google Log documentation:
+          /**
+             From Google Log documentation:
 
-           "Log lines have this form:
+             "Log lines have this form:
 
-           Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+             Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
 
-           where the fields are defined as follows:
+             where the fields are defined as follows:
 
-           L                A single character, representing the log level (eg 'I' for INFO)
-           mm               The month (zero padded; ie May is '05')
-           dd               The day (zero padded)
-           hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
-           threadid         The space-padded thread ID as returned by GetTID() (this matches the PID on Linux)
-           file             The file name
-           line             The line number
-           msg              The user-supplied message"
+             L                A single character, representing the log level (eg 'I' for INFO)
+             mm               The month (zero padded; ie May is '05')
+             dd               The day (zero padded)
+             hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
+             threadid         The space-padded thread ID as returned by GetTID() (this matches the PID on Linux)
+             file             The file name
+             line             The line number
+             msg              The user-supplied message"
 
-           In this implementation, "threadid" is not printed.
-         **/
+             In this implementation, "threadid" is not printed.
+          **/
 
-        char date[32];
-        sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ",
-                level[0],
-                now.date().month().as_number(),
-                now.date().day().as_number(),
-                duration.hours(),
-                duration.minutes(),
-                duration.seconds(),
-                static_cast<int>(duration.fractional_seconds()));
+          char date[32];
+          sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ",
+                  level[0],
+                  now.date().month().as_number(),
+                  now.date().day().as_number(),
+                  duration.hours(),
+                  duration.minutes(),
+                  duration.seconds(),
+                  static_cast<int>(duration.fractional_seconds()));
 
-        header = std::string(date) + path.filename().string() + ":" + boost::lexical_cast<std::string>(line) + "] ";
-      }
+          header = std::string(date) + path.filename().string() + ":" + boost::lexical_cast<std::string>(line) + "] ";
+        }
 
 
-      // The header is computed, we now re-lock the mutex to access
-      // the stream objects. Pay attention that "loggingContext_",
-      // "infoEnabled_" or "traceEnabled_" might have changed while
-      // the mutex was unlocked.
-      lock_.lock();
+        // The header is computed, we now re-lock the mutex to access
+        // the stream objects. Pay attention that "loggingContext_",
+        // "infoEnabled_" or "traceEnabled_" might have changed while
+        // the mutex was unlocked.
+        lock_.lock();
+
+        if (loggingContext_.get() == NULL)
+        {
+          fprintf(stderr, "ERROR: Trying to log a message after the finalization of the logging engine\n");
+          return;
+        }
 
-      if (loggingContext_.get() == NULL)
-      {
-        fprintf(stderr, "ERROR: Trying to log a message after the finalization of the logging engine\n");
-        return;
-      }
+        switch (l)
+        {
+          case LogLevel_Error:
+            stream_ = loggingContext_->error_;
+            break;
 
-      switch (l)
-      {
-        case LogLevel_Error:
-          stream_ = loggingContext_->error_;
-          break;
+          case LogLevel_Warning:
+            stream_ = loggingContext_->warning_;
+            break;
 
-        case LogLevel_Warning:
-          stream_ = loggingContext_->warning_;
-          break;
+          case LogLevel_Info:
+            if (loggingContext_->infoEnabled_)
+            {
+              stream_ = loggingContext_->info_;
+            }
+
+            break;
 
-        case LogLevel_Info:
-          if (loggingContext_->infoEnabled_)
-          {
-            stream_ = loggingContext_->info_;
-          }
+          case LogLevel_Trace:
+            if (loggingContext_->traceEnabled_)
+            {
+              stream_ = loggingContext_->info_;
+            }
 
-          break;
+            break;
 
-        case LogLevel_Trace:
-          if (loggingContext_->traceEnabled_)
-          {
-            stream_ = loggingContext_->info_;
-          }
+          default:
+            throw OrthancException(ErrorCode_InternalError);
+        }
 
-          break;
-
-        default:
-          throw OrthancException(ErrorCode_InternalError);
-      }
+        if (stream_ == &null_)
+        {
+          // The logging is disabled for this level. The stream is the
+          // "null_" member of this object, so we can release the global
+          // mutex.
+          lock_.unlock();
+        }
 
-      if (stream_ == &null_)
-      {
-        // The logging is disabled for this level. The stream is the
-        // "null_" member of this object, so we can release the global
-        // mutex.
-        lock_.unlock();
+        (*stream_) << header;
       }
-
-      (*stream_) << header;
+      catch (...)
+      { 
+        // Something is going really wrong, probably running out of
+        // memory. Fallback to a degraded mode.
+        stream_ = loggingContext_->error_;
+        (*stream_) << "E???? ??:??:??.?????? ] ";
+      }
     }
 
 
--- a/Framework/Orthanc/Core/Logging.h	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Logging.h	Wed Nov 09 14:14:34 2016 +0100
@@ -110,6 +110,12 @@
       {
         return (*stream_) << message;
       }
+
+      // This overload fixes build problems with Visual Studio 2015
+      std::ostream& operator<< (const char* message)
+      {
+        return (*stream_) << message;
+      }
     };
   }
 }
--- a/Framework/Orthanc/Core/PrecompiledHeaders.h	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/PrecompiledHeaders.h	Wed Nov 09 14:14:34 2016 +0100
@@ -48,7 +48,7 @@
 
 #include <json/value.h>
 
-#if ORTHANC_PUGIXML_ENABLED == 1
+#if ORTHANC_ENABLE_PUGIXML == 1
 #include <pugixml.hpp>
 #endif
 
--- a/Framework/Orthanc/Core/Toolbox.cpp	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Toolbox.cpp	Wed Nov 09 14:14:34 2016 +0100
@@ -103,7 +103,7 @@
 #endif
 
 
-#if ORTHANC_PUGIXML_ENABLED == 1
+#if ORTHANC_ENABLE_PUGIXML == 1
 #include "ChunkedBuffer.h"
 #include <pugixml.hpp>
 #endif
@@ -844,6 +844,23 @@
   }
 
 
+  bool Toolbox::IsAsciiString(const void* data,
+                              size_t size)
+  {
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
+
+    for (size_t i = 0; i < size; i++, p++)
+    {
+      if (*p > 127 || (*p != 0 && iscntrl(*p)))
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+
   std::string Toolbox::ConvertToAscii(const std::string& source)
   {
     std::string result;
@@ -1190,7 +1207,7 @@
 #endif
 
 
-#if ORTHANC_PUGIXML_ENABLED == 1
+#if ORTHANC_ENABLE_PUGIXML == 1
   class ChunkedBufferWriter : public pugi::xml_writer
   {
   private:
--- a/Framework/Orthanc/Core/Toolbox.h	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Core/Toolbox.h	Wed Nov 09 14:14:34 2016 +0100
@@ -163,6 +163,9 @@
     std::string ConvertFromUtf8(const std::string& source,
                                 Encoding targetEncoding);
 
+    bool IsAsciiString(const void* data,
+                       size_t size);
+
     std::string ConvertToAscii(const std::string& source);
 
     std::string StripSpaces(const std::string& source);
@@ -195,7 +198,7 @@
     bool IsExistingFile(const std::string& path);
 #endif
 
-#if ORTHANC_PUGIXML_ENABLED == 1
+#if ORTHANC_ENABLE_PUGIXML == 1
     void JsonToXml(std::string& target,
                    const Json::Value& source,
                    const std::string& rootElement = "root",
--- a/Framework/Orthanc/Resources/CMake/BoostConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/BoostConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -210,7 +210,8 @@
     ${BOOST_SOURCES_DIR}
     )
 
-  source_group(ThirdParty\\Boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
+  source_group(ThirdParty\\boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
+
 else()
   add_definitions(
     -DBOOST_HAS_LOCALE=1
--- a/Framework/Orthanc/Resources/CMake/DownloadPackage.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/DownloadPackage.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -15,12 +15,18 @@
 ## Setup the patch command-line tool
 ##
 
-if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
-  set(PATCH_EXECUTABLE ${CMAKE_SOURCE_DIR}/Resources/ThirdParty/patch/patch.exe)
-else ()
-  find_program(PATCH_EXECUTABLE patch)
-  if (${PATCH_EXECUTABLE} MATCHES "PATCH_EXECUTABLE-NOTFOUND")
-    message(FATAL_ERROR "Please install the 'patch' standard command-line tool")
+if (NOT ORTHANC_DISABLE_PATCH)
+  if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
+    set(PATCH_EXECUTABLE ${CMAKE_CURRENT_LIST_DIR}/../ThirdParty/patch/patch.exe)
+    if (NOT EXISTS ${PATCH_EXECUTABLE})
+      message(FATAL_ERROR "Unable to find the patch.exe tool that is shipped with Orthanc")
+    endif()
+
+  else ()
+    find_program(PATCH_EXECUTABLE patch)
+    if (${PATCH_EXECUTABLE} MATCHES "PATCH_EXECUTABLE-NOTFOUND")
+      message(FATAL_ERROR "Please install the 'patch' standard command-line tool")
+    endif()
   endif()
 endif()
 
--- a/Framework/Orthanc/Resources/CMake/LibIconvConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/LibIconvConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -48,3 +48,5 @@
   ${LIBICONV_SOURCES_DIR}/libcharset/lib/localcharset.c  
   ${LIBICONV_SOURCES_DIR}/libcharset/lib/relocatable.c
   )
+
+source_group(ThirdParty\\libiconv REGULAR_EXPRESSION ${LIBICONV_SOURCES_DIR}/.*)
--- a/Framework/Orthanc/Resources/CMake/LibJpegConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/LibJpegConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -81,6 +81,8 @@
     ${LIBJPEG_SOURCES_DIR}/jconfig.h COPYONLY
     )
 
+  source_group(ThirdParty\\libjpeg REGULAR_EXPRESSION ${LIBJPEG_SOURCES_DIR}/.*)
+
 else()
   include(FindJPEG)
 
--- a/Framework/Orthanc/Resources/CMake/LibPngConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/LibPngConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -46,7 +46,7 @@
     -DPNG_IMPEXP=
     )
 
-  source_group(ThirdParty\\Libpng REGULAR_EXPRESSION ${LIBPNG_SOURCES_DIR}/.*)
+  source_group(ThirdParty\\libpng REGULAR_EXPRESSION ${LIBPNG_SOURCES_DIR}/.*)
 
 else()
   include(FindPNG)
--- a/Framework/Orthanc/Resources/CMake/OpenSslConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/OpenSslConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -216,6 +216,8 @@
     endif()
   endif()
 
+  source_group(ThirdParty\\OpenSSL REGULAR_EXPRESSION ${OPENSSL_SOURCES_DIR}/.*)
+
 else()
   include(FindOpenSSL)
 
--- a/Framework/Orthanc/Resources/CMake/ZlibConfiguration.cmake	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/CMake/ZlibConfiguration.cmake	Wed Nov 09 14:14:34 2016 +0100
@@ -27,10 +27,10 @@
     ${ZLIB_SOURCES_DIR}/zutil.c
     )
 
+  source_group(ThirdParty\\zlib REGULAR_EXPRESSION ${ZLIB_SOURCES_DIR}/.*)
+
 else()
   include(FindZLIB)
   include_directories(${ZLIB_INCLUDE_DIRS})
   link_libraries(${ZLIB_LIBRARIES})
 endif()
-
-source_group(ThirdParty\\ZLib REGULAR_EXPRESSION ${ZLIB_SOURCES_DIR}/.*)
--- a/Framework/Orthanc/Resources/ThirdParty/VisualStudio/stdint.h	Wed Oct 26 12:14:03 2016 +0200
+++ b/Framework/Orthanc/Resources/ThirdParty/VisualStudio/stdint.h	Wed Nov 09 14:14:34 2016 +0100
@@ -1,7 +1,7 @@
 // ISO C9x  compliant stdint.h for Microsoft Visual Studio
 // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
 // 
-//  Copyright (c) 2006-2008 Alexander Chemeris
+//  Copyright (c) 2006-2013 Alexander Chemeris
 // 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
@@ -13,8 +13,9 @@
 //      notice, this list of conditions and the following disclaimer in the
 //      documentation and/or other materials provided with the distribution.
 // 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
+//   3. Neither the name of the product nor the names of its contributors may
+//      be used to endorse or promote products derived from this software
+//      without specific prior written permission.
 // 
 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -40,6 +41,10 @@
 #pragma once
 #endif
 
+#if _MSC_VER >= 1600 // [
+#include <stdint.h>
+#else // ] _MSC_VER >= 1600 [
+
 #include <limits.h>
 
 // For Visual Studio 6 in C++ mode and for many Visual Studio versions when
@@ -238,10 +243,17 @@
 #define UINT64_C(val) val##ui64
 
 // 7.18.4.2 Macros for greatest-width integer constants
-#define INTMAX_C   INT64_C
-#define UINTMAX_C  UINT64_C
+// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
+// Check out Issue 9 for the details.
+#ifndef INTMAX_C //   [
+#  define INTMAX_C   INT64_C
+#endif // INTMAX_C    ]
+#ifndef UINTMAX_C //  [
+#  define UINTMAX_C  UINT64_C
+#endif // UINTMAX_C   ]
 
 #endif // __STDC_CONSTANT_MACROS ]
 
+#endif // _MSC_VER >= 1600 ]
 
 #endif // _MSC_STDINT_H_ ]