changeset 2908:9d277f8ad698

new enumeration: MimeType
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Oct 2018 16:16:07 +0100
parents 0204af4ece6a
children a9a1554932a1 83133583183d
files Core/DicomParsing/ParsedDicomFile.cpp Core/DicomParsing/ParsedDicomFile.h Core/Enumerations.cpp Core/Enumerations.h Core/FileStorage/StorageAccessor.h Core/HttpServer/EmbeddedResourceHttpHandler.cpp Core/HttpServer/FilesystemHttpHandler.cpp Core/HttpServer/HttpFileSender.h Core/HttpServer/HttpOutput.cpp Core/HttpServer/HttpOutput.h Core/RestApi/RestApiOutput.cpp Core/RestApi/RestApiOutput.h Core/SystemToolbox.cpp Core/SystemToolbox.h OrthancServer/OrthancRestApi/OrthancRestApi.cpp OrthancServer/OrthancRestApi/OrthancRestArchive.cpp OrthancServer/OrthancRestApi/OrthancRestChanges.cpp OrthancServer/OrthancRestApi/OrthancRestModalities.cpp OrthancServer/OrthancRestApi/OrthancRestResources.cpp OrthancServer/OrthancRestApi/OrthancRestSystem.cpp OrthancServer/ServerEnumerations.cpp Plugins/Engine/OrthancPlugins.cpp UnitTestsSources/UnitTestsMain.cpp
diffstat 23 files changed, 392 insertions(+), 176 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomParsing/ParsedDicomFile.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/DicomParsing/ParsedDicomFile.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -258,7 +258,7 @@
 
       virtual std::string GetContentType()
       {
-        return "";
+        return EnumerationToString(MimeType_Binary);
       }
 
       virtual uint64_t  GetContentLength()
@@ -362,14 +362,14 @@
             {
               if (pixelItem->getLength() == 0)
               {
-                output.AnswerBuffer(NULL, 0, MIME_BINARY);
+                output.AnswerBuffer(NULL, 0, MimeType_Binary);
                 return true;
               }
 
               Uint8* buffer = NULL;
               if (pixelItem->getUint8Array(buffer).good() && buffer)
               {
-                output.AnswerBuffer(buffer, pixelItem->getLength(), MIME_BINARY);
+                output.AnswerBuffer(buffer, pixelItem->getLength(), MimeType_Binary);
                 return true;
               }
             }
@@ -825,7 +825,7 @@
     std::string serialized;
     if (FromDcmtkBridge::SaveToMemoryBuffer(serialized, *pimpl_->file_->getDataset()))
     {
-      output.AnswerBuffer(serialized, MIME_BINARY);
+      output.AnswerBuffer(serialized, MimeType_Binary);
     }
   }
 #endif
@@ -1064,44 +1064,46 @@
 
   bool ParsedDicomFile::EmbedContentInternal(const std::string& dataUriScheme)
   {
-    std::string mime, content;
-    if (!Toolbox::DecodeDataUriScheme(mime, content, dataUriScheme))
+    std::string mimeString, content;
+    if (!Toolbox::DecodeDataUriScheme(mimeString, content, dataUriScheme))
     {
       return false;
     }
 
-    Toolbox::ToLowerCase(mime);
+    Toolbox::ToLowerCase(mimeString);
+    MimeType mime = StringToMimeType(mimeString);
 
-    if (mime == MIME_PNG)
+    switch (mime)
     {
+      case MimeType_Png:
 #if ORTHANC_ENABLE_PNG == 1
-      EmbedImage(mime, content);
-#else
-      LOG(ERROR) << "Orthanc was compiled without support of PNG";
-      throw OrthancException(ErrorCode_NotImplemented);
-#endif
-    }
-    else if (mime == MIME_JPEG)
-    {
-#if ORTHANC_ENABLE_JPEG == 1
-      EmbedImage(mime, content);
+        EmbedImage(mime, content);
+        break;
 #else
-      LOG(ERROR) << "Orthanc was compiled without support of JPEG";
-      throw OrthancException(ErrorCode_NotImplemented);
+        LOG(ERROR) << "Orthanc was compiled without support of PNG";
+        throw OrthancException(ErrorCode_NotImplemented);
+#endif
+
+      case MimeType_Jpeg:
+#if ORTHANC_ENABLE_JPEG == 1
+        EmbedImage(mime, content);
+        break;
+#else
+        LOG(ERROR) << "Orthanc was compiled without support of JPEG";
+        throw OrthancException(ErrorCode_NotImplemented);
 #endif
-    }
-    else if (mime == MIME_PAM)
-    {
-      EmbedImage(mime, content);
-    }
-    else if (mime == MIME_PDF)
-    {
-      EmbedPdf(content);
-    }
-    else
-    {
-      LOG(ERROR) << "Unsupported MIME type for the content of a new DICOM file: " << mime;
-      throw OrthancException(ErrorCode_NotImplemented);
+
+      case MimeType_Pam:
+        EmbedImage(mime, content);
+        break;
+
+      case MimeType_Pdf:
+        EmbedPdf(content);
+        break;
+
+      default:
+        LOG(ERROR) << "Unsupported MIME type for the content of a new DICOM file: " << mime;
+        throw OrthancException(ErrorCode_NotImplemented);
     }
 
     return true;
@@ -1117,38 +1119,42 @@
   }
 
 
-  void ParsedDicomFile::EmbedImage(const std::string& mime,
+  void ParsedDicomFile::EmbedImage(MimeType mime,
                                    const std::string& content)
   {
-#if ORTHANC_ENABLE_JPEG == 1
-    if (mime == MIME_JPEG)
+    switch (mime)
     {
-      JpegReader reader;
-      reader.ReadFromMemory(content);
-      EmbedImage(reader);
-      return;
-    }
+    
+#if ORTHANC_ENABLE_JPEG == 1
+      case MimeType_Jpeg:
+      {
+        JpegReader reader;
+        reader.ReadFromMemory(content);
+        EmbedImage(reader);
+        break;
+      }
 #endif
     
 #if ORTHANC_ENABLE_PNG == 1
-    if (mime == MIME_PNG)
-    {
-      PngReader reader;
-      reader.ReadFromMemory(content);
-      EmbedImage(reader);
-      return;
-    }
+      case MimeType_Png:
+      {
+        PngReader reader;
+        reader.ReadFromMemory(content);
+        EmbedImage(reader);
+        break;
+      }
 #endif
 
-    if (mime == MIME_PAM)
-    {
-      PamReader reader;
-      reader.ReadFromMemory(content);
-      EmbedImage(reader);
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
+      case MimeType_Pam:
+      {
+        PamReader reader;
+        reader.ReadFromMemory(content);
+        EmbedImage(reader);
+        break;
+      }
+
+      default:
+        throw OrthancException(ErrorCode_NotImplemented);
     }
   }
 
@@ -1471,7 +1477,7 @@
 
 
   void ParsedDicomFile::GetRawFrame(std::string& target,
-                                    std::string& mime,
+                                    MimeType& mime,
                                     unsigned int frameId)
   {
     if (pimpl_->frameIndex_.get() == NULL)
@@ -1485,16 +1491,16 @@
     switch (transferSyntax)
     {
       case EXS_JPEGProcess1:
-        mime = MIME_JPEG;
+        mime = MimeType_Jpeg;
         break;
        
       case EXS_JPEG2000LosslessOnly:
       case EXS_JPEG2000:
-        mime = MIME_JPEG2000;
+        mime = MimeType_Jpeg2000;
         break;
 
       default:
-        mime = MIME_BINARY;
+        mime = MimeType_Binary;
         break;
     }
   }
--- a/Core/DicomParsing/ParsedDicomFile.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/DicomParsing/ParsedDicomFile.h	Tue Oct 30 16:16:07 2018 +0100
@@ -183,7 +183,7 @@
 
     void EmbedImage(const ImageAccessor& accessor);
 
-    void EmbedImage(const std::string& mime,
+    void EmbedImage(MimeType mime,
                     const std::string& content);
 
     Encoding GetEncoding() const;
@@ -220,7 +220,7 @@
     bool ExtractPdf(std::string& pdf);
 
     void GetRawFrame(std::string& target, // OUT
-                     std::string& mime,   // OUT
+                     MimeType& mime,   // OUT
                      unsigned int frameId);  // IN
 
     unsigned int GetFramesCount() const;
--- a/Core/Enumerations.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/Enumerations.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -1019,6 +1019,64 @@
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
   }
+
+
+  const char* EnumerationToString(MimeType mime)
+  {
+    switch (mime)
+    {
+      case MimeType_Binary:
+        return MIME_BINARY;
+        
+      case MimeType_Dicom:
+        return MIME_DICOM;
+        
+      case MimeType_Jpeg:
+        return MIME_JPEG;
+        
+      case MimeType_Jpeg2000:
+        return MIME_JPEG2000;
+        
+      case MimeType_Json:
+        return MIME_JSON;
+        
+      case MimeType_Pdf:
+        return MIME_PDF;
+        
+      case MimeType_Png:
+        return MIME_PNG;
+        
+      case MimeType_Xml:
+        return MIME_XML;
+        
+      case MimeType_PlainText:
+        return MIME_PLAIN_TEXT;
+                
+      case MimeType_Pam:
+        return MIME_PAM;
+                
+      case MimeType_Html:
+        return MIME_HTML;
+                
+      case MimeType_Gzip:
+        return MIME_GZIP;
+                
+      case MimeType_JavaScript:
+        return MIME_JAVASCRIPT;
+                
+      case MimeType_Css:
+        return MIME_CSS;
+                
+      case MimeType_WebAssembly:
+        return MIME_WEB_ASSEMBLY;
+                
+      case MimeType_Gif:
+        return MIME_GIF;
+                
+      default:
+        throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+  }
   
 
   Encoding StringToEncoding(const char* encoding)
@@ -1535,6 +1593,80 @@
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
   }
+
+
+  MimeType StringToMimeType(const std::string& mime)
+  {
+    if (mime == MIME_BINARY)
+    {
+      return MimeType_Binary;
+    }
+    else if (mime == MIME_DICOM)
+    {
+      return MimeType_Dicom;
+    }
+    else if (mime == MIME_JPEG)
+    {
+      return MimeType_Jpeg;
+    }
+    else if (mime == MIME_JPEG2000)
+    {
+      return MimeType_Jpeg2000;
+    }
+    else if (mime == MIME_JSON)
+    {
+      return MimeType_Json;
+    }
+    else if (mime == MIME_PDF)
+    {
+      return MimeType_Pdf;
+    }
+    else if (mime == MIME_PNG)
+    {
+      return MimeType_Png;
+    }
+    else if (mime == MIME_XML ||
+             mime == MIME_XML_2)
+    {
+      return MimeType_Xml;
+    }
+    else if (mime == MIME_PLAIN_TEXT)
+    {
+      return MimeType_PlainText;
+    }
+    else if (mime == MIME_PAM)
+    {
+      return MimeType_Pam;
+    }
+    else if (mime == MIME_HTML)
+    {
+      return MimeType_Html;
+    }
+    else if (mime == MIME_GZIP)
+    {
+      return MimeType_Gzip;
+    }
+    else if (mime == MIME_JAVASCRIPT)
+    {
+      return MimeType_JavaScript;
+    }
+    else if (mime == MIME_CSS)
+    {
+      return MimeType_Css;
+    }
+    else if (mime == MIME_WEB_ASSEMBLY)
+    {
+      return MimeType_WebAssembly;
+    }
+    else if (mime == MIME_GIF)
+    {
+      return MimeType_Gif;
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+  }
   
 
   unsigned int GetBytesPerPixel(PixelFormat format)
--- a/Core/Enumerations.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/Enumerations.h	Tue Oct 30 16:16:07 2018 +0100
@@ -54,10 +54,19 @@
   static const char* const MIME_JPEG = "image/jpeg";
   static const char* const MIME_JPEG2000 = "image/jp2";
   static const char* const MIME_JSON = "application/json";
+  static const char* const MIME_JSON_UTF8 = "application/json; charset=utf-8";
+  static const char* const MIME_XML_UTF8 = "application/xml; charset=utf-8";
   static const char* const MIME_PDF = "application/pdf";
   static const char* const MIME_PNG = "image/png";
   static const char* const MIME_XML = "application/xml";
+  static const char* const MIME_XML_2 = "text/xml";
+  static const char* const MIME_HTML = "text/html";
   static const char* const MIME_PLAIN_TEXT = "text/plain";
+  static const char* const MIME_GZIP = "application/gzip";
+  static const char* const MIME_JAVASCRIPT = "application/javascript";
+  static const char* const MIME_CSS = "text/css";
+  static const char* const MIME_GIF = "image/gif";
+  static const char* const MIME_WEB_ASSEMBLY = "application/wasm";
 
   /**
    * "No Internet Media Type (aka MIME type, content type) for PBM has
@@ -68,6 +77,27 @@
    **/
   static const char* const MIME_PAM = "image/x-portable-arbitrarymap";
 
+
+  enum MimeType
+  {
+    MimeType_Binary,
+    MimeType_Dicom,
+    MimeType_Html,
+    MimeType_Jpeg,
+    MimeType_Jpeg2000,
+    MimeType_Json,
+    MimeType_Pam,
+    MimeType_Pdf,
+    MimeType_PlainText,
+    MimeType_Png,
+    MimeType_Xml,
+    MimeType_Gzip,
+    MimeType_JavaScript,
+    MimeType_Css,
+    MimeType_WebAssembly,
+    MimeType_Gif
+  };
+
   
   enum Endianness
   {
@@ -684,6 +714,8 @@
 
   const char* EnumerationToString(JobState state);
 
+  const char* EnumerationToString(MimeType mime);
+
   Encoding StringToEncoding(const char* encoding);
 
   ResourceType StringToResourceType(const char* type);
@@ -704,6 +736,8 @@
   JobState StringToJobState(const std::string& state);
   
   RequestOrigin StringToRequestOrigin(const std::string& origin);
+
+  MimeType StringToMimeType(const std::string& mime);
   
   unsigned int GetBytesPerPixel(PixelFormat format);
 
--- a/Core/FileStorage/StorageAccessor.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/FileStorage/StorageAccessor.h	Tue Oct 30 16:16:07 2018 +0100
@@ -110,10 +110,24 @@
 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
     void AnswerFile(HttpOutput& output,
                     const FileInfo& info,
+                    MimeType mime)
+    {
+      AnswerFile(output, info, EnumerationToString(mime));
+    }
+
+    void AnswerFile(HttpOutput& output,
+                    const FileInfo& info,
                     const std::string& mime);
 
     void AnswerFile(RestApiOutput& output,
                     const FileInfo& info,
+                    MimeType mime)
+    {
+      AnswerFile(output, info, EnumerationToString(mime));
+    }
+
+    void AnswerFile(RestApiOutput& output,
+                    const FileInfo& info,
                     const std::string& mime);
 #endif
   };
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -78,14 +78,14 @@
     }
 
     std::string resourcePath = Toolbox::FlattenUri(uri, baseUri_.size());
-    std::string contentType = SystemToolbox::AutodetectMimeType(resourcePath);
+    MimeType contentType = SystemToolbox::AutodetectMimeType(resourcePath);
 
     try
     {
       const void* buffer = EmbeddedResources::GetDirectoryResourceBuffer(resourceId_, resourcePath.c_str());
       size_t size = EmbeddedResources::GetDirectoryResourceSize(resourceId_, resourcePath.c_str());
 
-      output.SetContentType(contentType.c_str());
+      output.SetContentType(contentType);
       output.Answer(buffer, size);
     }
     catch (OrthancException&)
--- a/Core/HttpServer/FilesystemHttpHandler.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/HttpServer/FilesystemHttpHandler.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -107,7 +107,7 @@
     s += "  </body>";
     s += "</html>";
 
-    output.SetContentType("text/html");
+    output.SetContentType(MimeType_Html);
     output.Answer(s);
   }
 
--- a/Core/HttpServer/HttpFileSender.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/HttpServer/HttpFileSender.h	Tue Oct 30 16:16:07 2018 +0100
@@ -44,6 +44,11 @@
     std::string filename_;
 
   public:
+    void SetContentType(MimeType contentType)
+    {
+      contentType_ = EnumerationToString(contentType);
+    }
+
     void SetContentType(const std::string& contentType)
     {
       contentType_ = contentType;
--- a/Core/HttpServer/HttpOutput.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/HttpServer/HttpOutput.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -322,6 +322,7 @@
     stateMachine_.SendBody(NULL, 0);
   }
 
+  
   void HttpOutput::Answer(const void* buffer, 
                           size_t length)
   {
--- a/Core/HttpServer/HttpOutput.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/HttpServer/HttpOutput.h	Tue Oct 30 16:16:07 2018 +0100
@@ -165,9 +165,14 @@
       SendStatus(status, message.c_str(), message.size());
     }
 
-    void SetContentType(const char* contentType)
+    void SetContentType(MimeType contentType)
     {
-      stateMachine_.SetContentType(contentType);
+      stateMachine_.SetContentType(EnumerationToString(contentType));
+    }
+    
+    void SetContentType(const std::string& contentType)
+    {
+      stateMachine_.SetContentType(contentType.c_str());
     }
 
     void SetContentFilename(const char* filename)
--- a/Core/RestApi/RestApiOutput.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/RestApi/RestApiOutput.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -97,9 +97,7 @@
       std::string s;
       Toolbox::JsonToXml(s, value);
 
-      std::string mime = std::string(MIME_XML) + "; charset=utf-8";
-      output_.SetContentType(mime.c_str());
-      
+      output_.SetContentType(MIME_XML_UTF8);
       output_.Answer(s);
 #else
       LOG(ERROR) << "Orthanc was compiled without XML support";
@@ -108,18 +106,18 @@
     }
     else
     {
-      std::string mime = std::string(MIME_JSON) + "; charset=utf-8";
-      output_.SetContentType(mime.c_str());
+      Json::StyledWriter writer;
+      std::string s = writer.write(value);
       
-      Json::StyledWriter writer;
-      output_.Answer(writer.write(value));
+      output_.SetContentType(MIME_JSON_UTF8);      
+      output_.Answer(s);
     }
 
     alreadySent_ = true;
   }
 
   void RestApiOutput::AnswerBuffer(const std::string& buffer,
-                                   const std::string& contentType)
+                                   MimeType contentType)
   {
     AnswerBuffer(buffer.size() == 0 ? NULL : buffer.c_str(),
                  buffer.size(), contentType);
@@ -127,10 +125,10 @@
 
   void RestApiOutput::AnswerBuffer(const void* buffer,
                                    size_t length,
-                                   const std::string& contentType)
+                                   MimeType contentType)
   {
     CheckStatus();
-    output_.SetContentType(contentType.c_str());
+    output_.SetContentType(contentType);
     output_.Answer(buffer, length);
     alreadySent_ = true;
   }
--- a/Core/RestApi/RestApiOutput.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/RestApi/RestApiOutput.h	Tue Oct 30 16:16:07 2018 +0100
@@ -75,11 +75,11 @@
     void AnswerJson(const Json::Value& value);
 
     void AnswerBuffer(const std::string& buffer,
-                      const std::string& contentType);
+                      MimeType contentType);
 
     void AnswerBuffer(const void* buffer,
                       size_t length,
-                      const std::string& contentType);
+                      MimeType contentType);
 
     void SignalError(HttpStatus status);
 
--- a/Core/SystemToolbox.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/SystemToolbox.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -580,7 +580,7 @@
   }
 
 
-  std::string SystemToolbox::AutodetectMimeType(const std::string& path)
+  MimeType SystemToolbox::AutodetectMimeType(const std::string& path)
   {
     std::string extension = boost::filesystem::extension(path);
     Toolbox::ToLowerCase(extension);
@@ -589,60 +589,60 @@
     // Text types
     if (extension == ".txt")
     {
-      return MIME_PLAIN_TEXT;
+      return MimeType_PlainText;
     }
     else if (extension == ".html")
     {
-      return "text/html";
+      return MimeType_Html;
     }
     else if (extension == ".xml")
     {
-      return MIME_XML;
+      return MimeType_Xml;
     }
     else if (extension == ".css")
     {
-      return "text/css";
+      return MimeType_Css;
     }
 
     // Application types
     else if (extension == ".js")
     {
-      return "application/javascript";
+      return MimeType_JavaScript;
     }
     else if (extension == ".json")
     {
-      return MIME_JSON;
+      return MimeType_Json;
     }
     else if (extension == ".pdf")
     {
-      return MIME_PDF;
+      return MimeType_Pdf;
     }
     else if (extension == ".wasm")
     {
-      return "application/wasm";
+      return MimeType_WebAssembly;
     }
 
     // Images types
     else if (extension == ".jpg" ||
              extension == ".jpeg")
     {
-      return MIME_JPEG;
+      return MimeType_Jpeg;
     }
     else if (extension == ".gif")
     {
-      return "image/gif";
+      return MimeType_Gif;
     }
     else if (extension == ".png")
     {
-      return MIME_PNG;
+      return MimeType_Png;
     }
     else if (extension == ".pam")
     {
-      return MIME_PAM;
+      return MimeType_Pam;
     }
     else
     {
-      return "";
+      return MimeType_Binary;
     }
   }
 }
--- a/Core/SystemToolbox.h	Tue Oct 30 13:53:29 2018 +0100
+++ b/Core/SystemToolbox.h	Tue Oct 30 16:16:07 2018 +0100
@@ -101,6 +101,6 @@
 
     unsigned int GetHardwareConcurrency();
 
-    std::string AutodetectMimeType(const std::string& path);
+    MimeType AutodetectMimeType(const std::string& path);
   }
 }
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -88,14 +88,14 @@
   {
     OrthancRestApi::GetApi(call).leaveBarrier_ = true;
     OrthancRestApi::GetApi(call).resetRequestReceived_ = true;
-    call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+    call.GetOutput().AnswerBuffer("{}", MimeType_Json);
   }
 
 
   void OrthancRestApi::ShutdownOrthanc(RestApiPostCall& call)
   {
     OrthancRestApi::GetApi(call).leaveBarrier_ = true;
-    call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+    call.GetOutput().AnswerBuffer("{}", MimeType_Json);
     LOG(WARNING) << "Shutdown request received";
   }
 
--- a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -84,7 +84,7 @@
     {
       // The archive is now created: Prepare the sending of the ZIP file
       FilesystemHttpSender sender(tmp->GetPath());
-      sender.SetContentType("application/zip");
+      sender.SetContentType(MimeType_Gzip);
       sender.SetContentFilename(filename);
 
       // Send the ZIP
--- a/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -98,7 +98,7 @@
   static void DeleteChanges(RestApiDeleteCall& call)
   {
     OrthancRestApi::GetIndex(call).DeleteChanges();
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
@@ -130,7 +130,7 @@
   static void DeleteExports(RestApiDeleteCall& call)
   {
     OrthancRestApi::GetIndex(call).DeleteExportedResources();
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
   
 
--- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -67,7 +67,7 @@
       if (connection.Echo())
       {
         // Echo has succeeded
-        call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+        call.GetOutput().AnswerBuffer("{}", MimeType_Json);
         return;
       }
     }
@@ -589,14 +589,14 @@
   static void GetQueryLevel(RestApiGetCall& call)
   {
     QueryAccessor query(call);
-    call.GetOutput().AnswerBuffer(EnumerationToString(query.GetHandler().GetLevel()), MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(EnumerationToString(query.GetHandler().GetLevel()), MimeType_PlainText);
   }
 
 
   static void GetQueryModality(RestApiGetCall& call)
   {
     QueryAccessor query(call);
-    call.GetOutput().AnswerBuffer(query.GetHandler().GetModalitySymbolicName(), MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(query.GetHandler().GetModalitySymbolicName(), MimeType_PlainText);
   }
 
 
@@ -604,7 +604,7 @@
   {
     ServerContext& context = OrthancRestApi::GetContext(call);
     context.GetQueryRetrieveArchive().Remove(call.GetUriComponent("id", ""));
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
@@ -798,7 +798,7 @@
     }
 
     // Move has succeeded
-    call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+    call.GetOutput().AnswerBuffer("{}", MimeType_Json);
   }
 
 
@@ -958,7 +958,7 @@
       RemoteModalityParameters modality;
       modality.Unserialize(json);
       Configuration::UpdateModality(context, call.GetUriComponent("id", ""), modality);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
   }
 
@@ -968,7 +968,7 @@
     ServerContext& context = OrthancRestApi::GetContext(call);
 
     Configuration::RemoveModality(context, call.GetUriComponent("id", ""));
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
@@ -983,7 +983,7 @@
       WebServiceParameters peer;
       peer.Unserialize(json);
       Configuration::UpdatePeer(context, call.GetUriComponent("id", ""), peer);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
   }
 
@@ -993,7 +993,7 @@
     ServerContext& context = OrthancRestApi::GetContext(call);
 
     Configuration::RemovePeer(context, call.GetUriComponent("id", ""));
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -201,7 +201,7 @@
   {
     std::string publicId = call.GetUriComponent("id", "");
     bool isProtected = OrthancRestApi::GetIndex(call).IsProtectedPatient(publicId);
-    call.GetOutput().AnswerBuffer(isProtected ? "1" : "0", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(isProtected ? "1" : "0", MimeType_PlainText);
   }
 
 
@@ -218,12 +218,12 @@
     if (body == "0")
     {
       context.GetIndex().SetProtectedPatient(publicId, false);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
     else if (body == "1")
     {
       context.GetIndex().SetProtectedPatient(publicId, true);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
     else
     {
@@ -256,7 +256,7 @@
     call.BodyToString(target);
     SystemToolbox::WriteFile(dicom, target);
 
-    call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+    call.GetOutput().AnswerBuffer("{}", MimeType_Json);
   }
 
 
@@ -284,7 +284,7 @@
       // is present
       std::string full;
       context.ReadDicomAsJson(full, publicId);
-      call.GetOutput().AnswerBuffer(full, MIME_JSON);
+      call.GetOutput().AnswerBuffer(full, MimeType_Json);
     }
   }
 
@@ -340,7 +340,7 @@
       std::auto_ptr<ImageAccessor>&  image_;
       ImageExtractionMode            mode_;
       bool                           invert_;
-      std::string                    format_;
+      MimeType                       format_;
       std::string                    answer_;
 
     public:
@@ -360,19 +360,19 @@
 
       void EncodeUsingPng()
       {
-        format_ = MIME_PNG;
+        format_ = MimeType_Png;
         DicomImageDecoder::ExtractPngImage(answer_, image_, mode_, invert_);
       }
 
       void EncodeUsingPam()
       {
-        format_ = MIME_PAM;
+        format_ = MimeType_Pam;
         DicomImageDecoder::ExtractPamImage(answer_, image_, mode_, invert_);
       }
 
       void EncodeUsingJpeg(uint8_t quality)
       {
-        format_ = MIME_JPEG;
+        format_ = MimeType_Jpeg;
         DicomImageDecoder::ExtractJpegImage(answer_, image_, mode_, invert_, quality);
       }
     };
@@ -596,7 +596,7 @@
     std::string result;
     decoded->ToMatlabString(result);
 
-    call.GetOutput().AnswerBuffer(result, MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(result, MimeType_PlainText);
   }
 
 
@@ -616,7 +616,8 @@
     }
 
     std::string publicId = call.GetUriComponent("id", "");
-    std::string raw, mime;
+    std::string raw;
+    MimeType mime;
 
     {
       ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), publicId);
@@ -628,7 +629,7 @@
       GzipCompressor gzip;
       std::string compressed;
       gzip.Compress(compressed, raw.empty() ? NULL : raw.c_str(), raw.size());
-      call.GetOutput().AnswerBuffer(compressed, "application/gzip");
+      call.GetOutput().AnswerBuffer(compressed, MimeType_Gzip);
     }
     else
     {
@@ -709,7 +710,7 @@
     std::string value;
     if (OrthancRestApi::GetIndex(call).LookupMetadata(value, publicId, metadata))
     {
-      call.GetOutput().AnswerBuffer(value, MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(value, MimeType_PlainText);
     }
   }
 
@@ -725,7 +726,7 @@
     if (IsUserMetadata(metadata))  // It is forbidden to modify internal metadata
     {      
       OrthancRestApi::GetIndex(call).DeleteMetadata(publicId, metadata);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
     else
     {
@@ -749,7 +750,7 @@
     {
       // It is forbidden to modify internal metadata
       OrthancRestApi::GetIndex(call).SetMetadata(publicId, metadata, value);
-      call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
     }
     else
     {
@@ -850,7 +851,7 @@
       // Return the raw data (possibly compressed), as stored on the filesystem
       std::string content;
       context.ReadAttachment(content, publicId, type, false);
-      call.GetOutput().AnswerBuffer(content, MIME_BINARY);
+      call.GetOutput().AnswerBuffer(content, MimeType_Binary);
     }
   }
 
@@ -860,7 +861,7 @@
     FileInfo info;
     if (GetAttachmentInfo(info, call))
     {
-      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetUncompressedSize()), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetUncompressedSize()), MimeType_PlainText);
     }
   }
 
@@ -870,7 +871,7 @@
     FileInfo info;
     if (GetAttachmentInfo(info, call))
     {
-      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetCompressedSize()), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetCompressedSize()), MimeType_PlainText);
     }
   }
 
@@ -881,7 +882,7 @@
     if (GetAttachmentInfo(info, call) &&
         info.GetUncompressedMD5() != "")
     {
-      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetUncompressedMD5()), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetUncompressedMD5()), MimeType_PlainText);
     }
   }
 
@@ -892,7 +893,7 @@
     if (GetAttachmentInfo(info, call) &&
         info.GetCompressedMD5() != "")
     {
-      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetCompressedMD5()), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(boost::lexical_cast<std::string>(info.GetCompressedMD5()), MimeType_PlainText);
     }
   }
 
@@ -942,7 +943,7 @@
     if (ok)
     {
       LOG(INFO) << "The attachment " << name << " of resource " << publicId << " has the right MD5";
-      call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+      call.GetOutput().AnswerBuffer("{}", MimeType_Json);
     }
     else
     {
@@ -963,7 +964,7 @@
     if (IsUserContentType(contentType) &&  // It is forbidden to modify internal attachments
         context.AddAttachment(publicId, StringToContentType(name), call.GetBodyData(), call.GetBodySize()))
     {
-      call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+      call.GetOutput().AnswerBuffer("{}", MimeType_Json);
     }
     else
     {
@@ -1001,7 +1002,7 @@
     if (allowed) 
     {
       OrthancRestApi::GetIndex(call).DeleteAttachment(publicId, contentType);
-      call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+      call.GetOutput().AnswerBuffer("{}", MimeType_Json);
     }
     else
     {
@@ -1020,7 +1021,7 @@
     FileContentType contentType = StringToContentType(name);
 
     OrthancRestApi::GetContext(call).ChangeAttachmentCompression(publicId, contentType, compression);
-    call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+    call.GetOutput().AnswerBuffer("{}", MimeType_Json);
   }
 
 
@@ -1030,7 +1031,7 @@
     if (GetAttachmentInfo(info, call))
     {
       std::string answer = (info.GetCompressionType() == CompressionType_None) ? "0" : "1";
-      call.GetOutput().AnswerBuffer(answer, MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(answer, MimeType_PlainText);
     }
   }
 
@@ -1467,7 +1468,7 @@
 
     if (locker.GetDicom().ExtractPdf(pdf))
     {
-      call.GetOutput().AnswerBuffer(pdf, MIME_PDF);
+      call.GetOutput().AnswerBuffer(pdf, MimeType_Pdf);
       return;
     }
   }
@@ -1529,7 +1530,7 @@
       }
     }
 
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
@@ -1538,7 +1539,7 @@
   {
     ServerContext& context = OrthancRestApi::GetContext(call);
     ServerToolbox::ReconstructResource(context, call.GetUriComponent("id", ""));
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
@@ -1555,7 +1556,7 @@
       ServerToolbox::ReconstructResource(context, *study);
     }
     
-    call.GetOutput().AnswerBuffer("", MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer("", MimeType_PlainText);
   }
 
 
--- a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -99,19 +99,19 @@
     std::string level = call.GetArgument("level", "");
     if (level == "patient")
     {
-      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient), MimeType_PlainText);
     }
     else if (level == "study")
     {
-      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study), MimeType_PlainText);
     }
     else if (level == "series")
     {
-      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series), MimeType_PlainText);
     }
     else if (level == "instance")
     {
-      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance), MIME_PLAIN_TEXT);
+      call.GetOutput().AnswerBuffer(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance), MimeType_PlainText);
     }
   }
 
@@ -128,13 +128,13 @@
       lock.GetLua().Execute(result, command);
     }
 
-    call.GetOutput().AnswerBuffer(result, MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(result, MimeType_PlainText);
   }
 
   template <bool UTC>
   static void GetNowIsoString(RestApiGetCall& call)
   {
-    call.GetOutput().AnswerBuffer(SystemToolbox::GetNowIsoString(UTC), MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(SystemToolbox::GetNowIsoString(UTC), MimeType_PlainText);
   }
 
 
@@ -142,14 +142,14 @@
   {
     std::string statement;
     GetFileResource(statement, EmbeddedResources::DICOM_CONFORMANCE_STATEMENT);
-    call.GetOutput().AnswerBuffer(statement, MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(statement, MimeType_PlainText);
   }
 
 
   static void GetDefaultEncoding(RestApiGetCall& call)
   {
     Encoding encoding = GetDefaultDicomEncoding();
-    call.GetOutput().AnswerBuffer(EnumerationToString(encoding), MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(EnumerationToString(encoding), MimeType_PlainText);
   }
 
 
@@ -159,7 +159,7 @@
 
     Configuration::SetDefaultEncoding(encoding);
 
-    call.GetOutput().AnswerBuffer(EnumerationToString(encoding), MIME_PLAIN_TEXT);
+    call.GetOutput().AnswerBuffer(EnumerationToString(encoding), MimeType_PlainText);
   }
 
 
@@ -265,7 +265,7 @@
 #endif
     }
 
-    call.GetOutput().AnswerBuffer(s, "application/javascript");
+    call.GetOutput().AnswerBuffer(s, MimeType_JavaScript);
   }
 
 
@@ -357,7 +357,7 @@
     
     if (ok)
     {
-      call.GetOutput().AnswerBuffer("{}", MIME_JSON);
+      call.GetOutput().AnswerBuffer("{}", MimeType_Json);
     }
   }
 
--- a/OrthancServer/ServerEnumerations.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/OrthancServer/ServerEnumerations.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -176,13 +176,13 @@
     switch (type)
     {
       case FileContentType_Dicom:
-        return MIME_DICOM;
+        return EnumerationToString(MimeType_Dicom);
 
       case FileContentType_DicomAsJson:
-        return MIME_JSON;
+        return MIME_JSON_UTF8;
 
       default:
-        return MIME_BINARY;
+        return EnumerationToString(MimeType_Binary);
     }
   }
 
--- a/Plugins/Engine/OrthancPlugins.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -1367,7 +1367,7 @@
       {
         PngWriter writer;
         writer.WriteToMemory(compressed, accessor);
-        translatedOutput->SetContentType("image/png");
+        translatedOutput->SetContentType(MimeType_Png);
         break;
       }
 
@@ -1376,7 +1376,7 @@
         JpegWriter writer;
         writer.SetQuality(p.quality);
         writer.WriteToMemory(compressed, accessor);
-        translatedOutput->SetContentType("image/jpeg");
+        translatedOutput->SetContentType(MimeType_Jpeg);
         break;
       }
 
--- a/UnitTestsSources/UnitTestsMain.cpp	Tue Oct 30 13:53:29 2018 +0100
+++ b/UnitTestsSources/UnitTestsMain.cpp	Tue Oct 30 16:16:07 2018 +0100
@@ -301,30 +301,30 @@
 
 TEST(Uri, AutodetectMimeType)
 {
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType("../NOTES"));
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType(""));
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType("/"));
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType("a/a"));
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType("..\\a\\"));
-  ASSERT_EQ("", SystemToolbox::AutodetectMimeType("..\\a\\a"));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType("../NOTES"));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType(""));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType("/"));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType("a/a"));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType("..\\a\\"));
+  ASSERT_EQ(MimeType_Binary, SystemToolbox::AutodetectMimeType("..\\a\\a"));
 
-  ASSERT_EQ("text/plain", SystemToolbox::AutodetectMimeType("../NOTES.txt"));
-  ASSERT_EQ("text/plain", SystemToolbox::AutodetectMimeType("../coucou.xml/NOTES.txt"));
-  ASSERT_EQ("application/xml", SystemToolbox::AutodetectMimeType("..\\coucou.\\NOTES.xml"));
-  ASSERT_EQ("application/xml", SystemToolbox::AutodetectMimeType("../.xml"));
-  ASSERT_EQ("application/xml", SystemToolbox::AutodetectMimeType("../.XmL"));
+  ASSERT_EQ(MimeType_PlainText, SystemToolbox::AutodetectMimeType("../NOTES.txt"));
+  ASSERT_EQ(MimeType_PlainText, SystemToolbox::AutodetectMimeType("../coucou.xml/NOTES.txt"));
+  ASSERT_EQ(MimeType_Xml, SystemToolbox::AutodetectMimeType("..\\coucou.\\NOTES.xml"));
+  ASSERT_EQ(MimeType_Xml, SystemToolbox::AutodetectMimeType("../.xml"));
+  ASSERT_EQ(MimeType_Xml, SystemToolbox::AutodetectMimeType("../.XmL"));
 
-  ASSERT_EQ("application/javascript", SystemToolbox::AutodetectMimeType("NOTES.js"));
-  ASSERT_EQ("application/json", SystemToolbox::AutodetectMimeType("NOTES.json"));
-  ASSERT_EQ("application/pdf", SystemToolbox::AutodetectMimeType("NOTES.pdf"));
-  ASSERT_EQ("text/css", SystemToolbox::AutodetectMimeType("NOTES.css"));
-  ASSERT_EQ("text/html", SystemToolbox::AutodetectMimeType("NOTES.html"));
-  ASSERT_EQ("text/plain", SystemToolbox::AutodetectMimeType("NOTES.txt"));
-  ASSERT_EQ("application/xml", SystemToolbox::AutodetectMimeType("NOTES.xml"));
-  ASSERT_EQ("image/gif", SystemToolbox::AutodetectMimeType("NOTES.gif"));
-  ASSERT_EQ("image/jpeg", SystemToolbox::AutodetectMimeType("NOTES.jpg"));
-  ASSERT_EQ("image/jpeg", SystemToolbox::AutodetectMimeType("NOTES.jpeg"));
-  ASSERT_EQ("image/png", SystemToolbox::AutodetectMimeType("NOTES.png"));
+  ASSERT_EQ(MimeType_JavaScript, SystemToolbox::AutodetectMimeType("NOTES.js"));
+  ASSERT_EQ(MimeType_Json, SystemToolbox::AutodetectMimeType("NOTES.json"));
+  ASSERT_EQ(MimeType_Pdf, SystemToolbox::AutodetectMimeType("NOTES.pdf"));
+  ASSERT_EQ(MimeType_Css, SystemToolbox::AutodetectMimeType("NOTES.css"));
+  ASSERT_EQ(MimeType_Html, SystemToolbox::AutodetectMimeType("NOTES.html"));
+  ASSERT_EQ(MimeType_PlainText, SystemToolbox::AutodetectMimeType("NOTES.txt"));
+  ASSERT_EQ(MimeType_Xml, SystemToolbox::AutodetectMimeType("NOTES.xml"));
+  ASSERT_EQ(MimeType_Gif, SystemToolbox::AutodetectMimeType("NOTES.gif"));
+  ASSERT_EQ(MimeType_Jpeg, SystemToolbox::AutodetectMimeType("NOTES.jpg"));
+  ASSERT_EQ(MimeType_Jpeg, SystemToolbox::AutodetectMimeType("NOTES.jpeg"));
+  ASSERT_EQ(MimeType_Png, SystemToolbox::AutodetectMimeType("NOTES.png"));
 }
 
 TEST(Toolbox, ComputeMD5)
@@ -709,6 +709,26 @@
   ASSERT_EQ(JobState_Paused, StringToJobState(EnumerationToString(JobState_Paused)));
   ASSERT_EQ(JobState_Retry, StringToJobState(EnumerationToString(JobState_Retry)));
   ASSERT_THROW(StringToJobState("nope"), OrthancException);
+
+  ASSERT_EQ(MimeType_Binary, StringToMimeType(EnumerationToString(MimeType_Binary)));
+  ASSERT_EQ(MimeType_Dicom, StringToMimeType(EnumerationToString(MimeType_Dicom)));
+  ASSERT_EQ(MimeType_Jpeg, StringToMimeType(EnumerationToString(MimeType_Jpeg)));
+  ASSERT_EQ(MimeType_Jpeg2000, StringToMimeType(EnumerationToString(MimeType_Jpeg2000)));
+  ASSERT_EQ(MimeType_Json, StringToMimeType(EnumerationToString(MimeType_Json)));
+  ASSERT_EQ(MimeType_Pdf, StringToMimeType(EnumerationToString(MimeType_Pdf)));
+  ASSERT_EQ(MimeType_Png, StringToMimeType(EnumerationToString(MimeType_Png)));
+  ASSERT_EQ(MimeType_Xml, StringToMimeType(EnumerationToString(MimeType_Xml)));
+  ASSERT_EQ(MimeType_Xml, StringToMimeType("application/xml"));
+  ASSERT_EQ(MimeType_Xml, StringToMimeType("text/xml"));
+  ASSERT_EQ(MimeType_PlainText, StringToMimeType(EnumerationToString(MimeType_PlainText)));
+  ASSERT_EQ(MimeType_Pam, StringToMimeType(EnumerationToString(MimeType_Pam)));
+  ASSERT_EQ(MimeType_Html, StringToMimeType(EnumerationToString(MimeType_Html)));
+  ASSERT_EQ(MimeType_Gzip, StringToMimeType(EnumerationToString(MimeType_Gzip)));
+  ASSERT_EQ(MimeType_JavaScript, StringToMimeType(EnumerationToString(MimeType_JavaScript)));
+  ASSERT_EQ(MimeType_Gif, StringToMimeType(EnumerationToString(MimeType_Gif)));
+  ASSERT_EQ(MimeType_WebAssembly, StringToMimeType(EnumerationToString(MimeType_WebAssembly)));
+  ASSERT_EQ(MimeType_Css, StringToMimeType(EnumerationToString(MimeType_Css)));
+  ASSERT_THROW(StringToMimeType("nope"), OrthancException);
 }