Implemented J2K desc to/from MD
[asdcplib.git] / src / KM_fileio.cpp
index 231f3b851032e20bb1eec819b0efe1490c47d716..27a5bfa01da23fc90918dbc5c4f381c786e74a0f 100644 (file)
@@ -666,7 +666,7 @@ Kumu::GetExecutablePath(const std::string& default_path)
   // This fails if the CWD changes after the program has started but before the
   // call to GetExecutablePath(). For least surprise, call GetExecutablePath()
   // immediately in main() and save the value for later use.
-  const,  char* p = getenv("_");
+  const  char* p = getenv("_");
   if ( p )
     {
       return Kumu::PathMakeAbsolute(p);
@@ -762,6 +762,55 @@ Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
 
 
 #ifdef KM_WIN32
+#ifdef KM_WIN32_UTF8
+
+//
+Kumu::Result_t
+Kumu::wbstr_to_utf8(const Kumu::ByteString& in, std::string& out)
+{
+  out.erase();
+  assert(in.Length()%sizeof(wchar_t)==0);
+  const wchar_t* p = (const wchar_t*)in.RoData();
+
+  int stringLength = static_cast<int>( in.Length() );
+  int len = WideCharToMultiByte(CP_UTF8, 0, p, stringLength, NULL, 0, NULL, NULL);
+  char *mb_buf = new char[len];
+  WideCharToMultiByte(CP_UTF8, 0, p, stringLength, mb_buf, len, NULL, NULL);
+  out = mb_buf;
+  delete [] mb_buf;
+  return RESULT_OK;
+}
+
+//
+Kumu::Result_t
+Kumu::utf8_to_wbstr(const std::string& in, Kumu::ByteString& out)
+{
+  Result_t result = out.Capacity((in.size()+1)*sizeof(wchar_t));
+
+  if ( KM_FAILURE(result) )
+    {
+      return result;
+    }
+
+  assert(in.size()*sizeof(wchar_t)<=out.Capacity());
+  const char* read_pos = in.c_str();
+  wchar_t character, *write_pos = (wchar_t*)out.Data();
+
+  int stringLength = static_cast<int>( in.length() ) + 1;
+  int len = MultiByteToWideChar(CP_UTF8, 0, in.c_str(), stringLength, 0, 0);
+  result = out.Capacity(len*sizeof(wchar_t));
+  if ( KM_FAILURE(result) )
+    {
+      return result;
+    }
+  MultiByteToWideChar(CP_UTF8, 0, in.c_str(), stringLength, write_pos, len);
+  out.Length(len*sizeof(wchar_t));
+
+  return RESULT_OK;
+}
+
+#endif // KM_WIN32_UTF8
+
 //------------------------------------------------------------------------------------------
 //
 
@@ -769,11 +818,25 @@ Kumu::Result_t
 Kumu::FileReader::OpenRead(const std::string& filename) const
 {
   const_cast<FileReader*>(this)->m_Filename = filename;
-  
+#ifdef KM_WIN32_UTF8
+  ByteString wb_filename;
+  Result_t result = utf8_to_wbstr(m_Filename, wb_filename);
+
+  if ( KM_FAILURE(result) )
+    {
+      return result;
+    }
+#endif
+
   // suppress popup window on error
   UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
 
+#ifdef KM_WIN32_UTF8
+  const_cast<FileReader*>(this)->m_Handle =
+            ::CreateFileW((wchar_t*)wb_filename.RoData(),
+#else
   const_cast<FileReader*>(this)->m_Handle = ::CreateFileA(filename.c_str(),
+#endif
                          (GENERIC_READ),                // open for reading
                          FILE_SHARE_READ,               // share for reading
                          NULL,                          // no security
@@ -888,16 +951,30 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
 //------------------------------------------------------------------------------------------
 //
 
+
 //
 Kumu::Result_t
 Kumu::FileWriter::OpenWrite(const std::string& filename)
 {
   m_Filename = filename;
-  
+#ifdef KM_WIN32_UTF8
+  ByteString wb_filename;
+  Result_t result = utf8_to_wbstr(m_Filename, wb_filename);
+
+  if ( KM_FAILURE(result) )
+    {
+      return result;
+    }
+#endif
+
   // suppress popup window on error
   UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
 
+#ifdef KM_WIN32_UTF8
+  m_Handle = ::CreateFileW((wchar_t*)wb_filename.RoData(),
+#else
   m_Handle = ::CreateFileA(filename.c_str(),
+#endif
                          (GENERIC_WRITE|GENERIC_READ),  // open for reading
                          FILE_SHARE_READ,               // share for reading
                          NULL,                          // no security
@@ -1178,8 +1255,8 @@ Kumu::ReadFileIntoString(const std::string& filename, std::string& outString, ui
 
       if ( fsize == 0 )
        {
-         DefaultLogSink().Error("%s: zero file size\n", filename.c_str());
-         return RESULT_READFAIL;
+         outString = "";
+         return RESULT_OK;
        }
 
       result = ReadBuf.Capacity((ui32_t)fsize);