Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1187537 into 
lp:zorba.

Commit message:
Eliminated MAX_PATH use on *nix (it's PATH_MAX there anyway).  In sole 
remaining use of PATH_MAX in fs::curdir(), its use is mitigated by increasing 
the buffer size as needed.

Also cleaned-up wide-to-narrow (and vice versa) WIN32 character conversion.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1187537 in Zorba: "Eliminate (or at least reduce) use of MAX_PATH"
  https://bugs.launchpad.net/zorba/+bug/1187537

For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-1187537/+merge/169567

Eliminated MAX_PATH use on *nix (it's PATH_MAX there anyway).  In sole 
remaining use of PATH_MAX in fs::curdir(), its use is mitigated by increasing 
the buffer size as needed.

Also cleaned-up wide-to-narrow (and vice versa) WIN32 character conversion.
-- 
https://code.launchpad.net/~paul-lucas/zorba/bug-1187537/+merge/169567
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-06-14 05:20:13 +0000
+++ ChangeLog	2013-06-14 23:50:38 +0000
@@ -23,6 +23,7 @@
   * Fixed bug in hoisting through try-catch expr
   * Fixed bug #1162631 (format-integer 'w' format of negative numbers)
   * Fixed bug #1190261 (relative paths bug in file module)
+  * Fixed bug #1187537 (Eliminate (or at least reduce) use of MAX_PATH)
   * Fixed bug #1180220 (Consolidate redundant path/file public APIs)
   * Fixed bug #1103115 (Timezone units as hours are wrong)
   * Fixed implementation of fn:deep-equal according to latest W3C spec.

=== modified file 'bin/zorbacmd.cpp'
--- bin/zorbacmd.cpp	2013-06-11 16:47:29 +0000
+++ bin/zorbacmd.cpp	2013-06-14 23:50:38 +0000
@@ -1062,7 +1062,7 @@
 
     if (asFile)
     {
-      fs::make_absolute( path );
+      fs::make_absolute( &path );
       qfile.reset( new std::ifstream( path.c_str() ) );
     }
     else

=== modified file 'include/zorba/util/fs_util.h'
--- include/zorba/util/fs_util.h	2013-06-13 18:12:45 +0000
+++ include/zorba/util/fs_util.h	2013-06-14 23:50:38 +0000
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#ifndef ZORBA_API_FS_UTIL_H
-#define ZORBA_API_FS_UTIL_H
+#ifndef ZORBA_FS_UTIL_API_H
+#define ZORBA_FS_UTIL_API_H
 
 // standard
 #include <cctype>
+#include <cstring>
 #include <iostream>
 #include <string>
 #ifdef WIN32
@@ -28,14 +29,6 @@
 # include <sys/types.h>                 /* for off_t */
 #endif /* WIN32 */
 
-#ifndef MAX_PATH
-/**
- * Maximum path length.  This is defined under Windows to be 1024.  There is no
- * equivalent constant/macro for *nix systems, so simply borrow Windows' value.
- */
-#define MAX_PATH 1024
-#endif /* MAX_PATH */
-
 // Zorba
 #include <zorba/config.h>
 #include <zorba/internal/cxx_util.h>
@@ -557,6 +550,23 @@
  * Appends a path component onto another path ensuring that exactly one
  * separator is used.
  *
+ * @param path1 The path to append to.  The buffer must be large enough to
+ * append \a path2 and a directory separator (if needed).
+ * @param path2 The path to append.
+ */
+inline void append( char *path1, char const *path2 ) {
+  size_t const path1_len = std::strlen( path1 );
+  if ( path1_len && path1[ path1_len - 1 ] != dir_separator
+       && path2[0] != dir_separator ) {
+    path1[ path1_len ] = dir_separator;
+    path1[ path1_len + 1 ] = '\0';
+  }
+}
+
+/**
+ * Appends a path component onto another path ensuring that exactly one
+ * separator is used.
+ *
  * @tparam PathStringType1 The \a path1 string type.
  * @param path1 The path to append to.
  * @param path2 The path to append.
@@ -590,30 +600,21 @@
 /**
  * Makes a relative path into an absolute path.
  *
- * @param path The path to make absolute.  It is assumes that the buffer to
- * which \a path points is at least MAX_PATH bytes.
- */
-ZORBA_DLL_PUBLIC
-void make_absolute( char *path );
-
-/**
- * Makes a relative path into an absolute path.
- *
  * @tparam PathStringType The \a path string type.
- * @param path The path to make absolute.
+ * @param path A pointer to the path to make absolute.
  */
 template<class PathStringType> inline
 typename std::enable_if<ZORBA_IS_STRING(PathStringType),void>::type
-make_absolute( PathStringType &path ) {
-  if ( !is_absolute( path ) ) {
+make_absolute( PathStringType *path ) {
+  if ( !is_absolute( *path ) ) {
 #ifndef WIN32
     typedef typename PathStringType::size_type size_type;
-    path.insert( static_cast<size_type>(0), 1, '/' );
-    path.insert( 0, curdir().c_str() );
+    path->insert( static_cast<size_type>(0), 1, '/' );
+    path->insert( 0, curdir().c_str() );
 #else
     char temp[ MAX_PATH ];
-    win32::make_absolute_impl( path.c_str(), temp );
-    path = temp;
+    win32::make_absolute_impl( path->c_str(), temp );
+    *path = temp;
 #endif /* WIN32 */
   }
 }
@@ -622,7 +623,7 @@
 
 } // namespace fs
 } // namespace zorba
-#endif /* ZORBA_API_FS_UTIL_H */
+#endif /* ZORBA_FS_UTIL_API_H */
 /*
 * Local variables:
 * mode: c++

=== modified file 'src/context/dynamic_loader.cpp'
--- src/context/dynamic_loader.cpp	2013-05-31 03:38:45 +0000
+++ src/context/dynamic_loader.cpp	2013-06-14 23:50:38 +0000
@@ -31,6 +31,7 @@
 #include <fstream>
 
 #include "diagnostics/xquery_diagnostics.h"
+#include "util/string_util.h"
 #include "zorbatypes/URI.h"
 
 #include <zorba/external_module.h>
@@ -144,16 +145,8 @@
   }
 
 #ifdef WIN32
-  WCHAR wpath_str[1024];
-  wpath_str[0] = 0;
-  if(MultiByteToWideChar(CP_UTF8,
-                      0, aFile.c_str(), -1,
-                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR)) == 0)
-  {//probably there is some invalid utf8 char, try the Windows ACP
-    MultiByteToWideChar(CP_ACP,
-                      0, aFile.c_str(), -1,
-                      wpath_str, sizeof(wpath_str)/sizeof(WCHAR));
-  }
+  WCHAR wpath_str[ MAX_PATH ];
+  win32::atow( aFile.c_str(), wpath_str, MAX_PATH );
   SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
   handle = LoadLibraryW(wpath_str);
   SetErrorMode(0);

=== modified file 'src/runtime/full_text/icu_tokenizer.cpp'
--- src/runtime/full_text/icu_tokenizer.cpp	2013-06-12 00:21:05 +0000
+++ src/runtime/full_text/icu_tokenizer.cpp	2013-06-14 23:50:38 +0000
@@ -109,12 +109,14 @@
 static Locale const& get_icu_locale_for( iso639_1::type lang ) {
   typedef map<iso639_1::type,Locale> locale_cache_t;
   static locale_cache_t locale_cache;
-  static Mutex mutex;
 
   if ( lang == iso639_1::unknown )
     lang = get_host_lang();
 
+#ifndef ZORBA_FOR_ONE_THREAD_ONLY
+  static Mutex mutex;
   AutoMutex const lock( &mutex );
+#endif /* ZORBA_FOR_ONE_THREAD_ONLY */
 
   locale_cache_t::const_iterator const i = locale_cache.find( lang );
   if ( i != locale_cache.end() )

=== modified file 'src/runtime/full_text/stemmer.cpp'
--- src/runtime/full_text/stemmer.cpp	2013-06-12 00:21:05 +0000
+++ src/runtime/full_text/stemmer.cpp	2013-06-14 23:50:38 +0000
@@ -49,12 +49,15 @@
   typedef unique_ptr<SnowballStemmer const> cache_ptr;
 
   static cache_ptr cached_stemmers[ iso639_1::NUM_ENTRIES ];
-  static Mutex mutex;
 
   if ( !lang )
     lang = get_host_lang();
 
+#ifndef ZORBA_FOR_ONE_THREAD_ONLY
+  static Mutex mutex;
   AutoMutex const lock( &mutex );
+#endif /* ZORBA_FOR_ONE_THREAD_ONLY */
+
   cache_ptr &ptr_ref = cached_stemmers[ lang ];
   if ( !ptr_ref )
     ptr_ref.reset( SnowballStemmer::create( lang ) );

=== modified file 'src/runtime/full_text/stemmer/sb_stemmer.cpp'
--- src/runtime/full_text/stemmer/sb_stemmer.cpp	2013-06-12 00:21:05 +0000
+++ src/runtime/full_text/stemmer/sb_stemmer.cpp	2013-06-14 23:50:38 +0000
@@ -80,10 +80,12 @@
 
 void SnowballStemmer::stem( zstring const &word, iso639_1::type,
                             zstring *result ) const {
+#ifndef ZORBA_FOR_ONE_THREAD_ONLY
   //
   // We need a mutex since the libstemmer library is not thread-safe.
   //
   AutoMutex const lock( &mutex_ );
+#endif /* ZORBA_FOR_ONE_THREAD_ONLY */
 
   sb_symbol const *const sb_word = sb_stemmer_stem(
     stemmer_, reinterpret_cast<sb_symbol const*>( word.c_str() ), word.length()

=== modified file 'src/runtime/full_text/stemmer/sb_stemmer.h'
--- src/runtime/full_text/stemmer/sb_stemmer.h	2013-02-07 17:24:36 +0000
+++ src/runtime/full_text/stemmer/sb_stemmer.h	2013-06-14 23:50:38 +0000
@@ -49,7 +49,9 @@
 
 private:
   sb_stemmer *const stemmer_;
+#ifndef ZORBA_FOR_ONE_THREAD_ONLY
   mutable Mutex mutex_;
+#endif /* ZORBA_FOR_ONE_THREAD_ONLY */
 
   SnowballStemmer( locale::iso639_1::type );
 

=== modified file 'src/runtime/full_text/thesauri/xqftts_thesaurus.cpp'
--- src/runtime/full_text/thesauri/xqftts_thesaurus.cpp	2013-02-07 17:24:36 +0000
+++ src/runtime/full_text/thesauri/xqftts_thesaurus.cpp	2013-06-14 23:50:38 +0000
@@ -233,16 +233,15 @@
   ZORBA_EXCEPTION( zerr::ZXQP0024_XML_DOES_NOT_MATCH_SCHEMA, \
                    ERROR_PARAMS( WHAT, ZED( ZED_KEY ) ) )
 
-void thesaurus::read_xqftts_file( zstring const &uri ) {
-  ZORBA_ASSERT( !uri.empty() );
-  zstring thesaurus_xml_path;
+void thesaurus::read_xqftts_file( zstring const &xqftts_uri ) {
+  ZORBA_ASSERT( !xqftts_uri.empty() );
   bool is_temp_file;
-  uri::fetch( uri, &thesaurus_xml_path, &is_temp_file );
+  zstring const thesaurus_xml_file( uri::fetch( xqftts_uri, &is_temp_file ) );
   fs::auto_remover<zstring> file_remover;
   if ( is_temp_file )
-    file_remover.reset( thesaurus_xml_path );
+    file_remover.reset( thesaurus_xml_file );
 
-  ifstream ifs( thesaurus_xml_path.c_str() );
+  ifstream ifs( thesaurus_xml_file.c_str() );
   store::LoadProperties props;
   props.setStoreDocument( false );
   store::Item_t doc = GENV_STORE.loadDocument( "", "", ifs, props );

=== modified file 'src/util/error_util.cpp'
--- src/util/error_util.cpp	2013-06-13 18:18:55 +0000
+++ src/util/error_util.cpp	2013-06-14 23:50:38 +0000
@@ -30,6 +30,7 @@
 #include "diagnostics/diagnostic.h"
 
 #include "stl_util.h"
+#include "string_util.h"
 
 namespace zorba {
 namespace os_error {
@@ -109,9 +110,7 @@
   int const err_size = ::wcslen( werr_string ) * 3;
   unique_ptr<char[]> const err_buf( new char[ err_size ] );
   char *const err_string = err_buf.get();
-  WideCharToMultiByte(
-    CP_UTF8, 0, werr_string, -1, err_string, err_size, NULL, NULL
-  );
+  win32::wtoa( werr_string, err_string, err_size );
   LocalFree( werr_string );
 #endif /* WIN32 */
   return format_err_string( function, code, err_string );

=== modified file 'src/util/fs_util.cpp'
--- src/util/fs_util.cpp	2013-06-13 18:12:45 +0000
+++ src/util/fs_util.cpp	2013-06-14 23:50:38 +0000
@@ -18,6 +18,7 @@
 #ifndef WIN32
 # include <climits>                     /* for PATH_MAX */
 # include <cstdio>
+# include <cstdlib>                     /* for getenv(3) */
 # include <fcntl.h>                     /* for creat(2) */
 # include <sys/stat.h>
 # include <sys/types.h>
@@ -29,6 +30,7 @@
 #include <zorba/internal/cxx_util.h>
 
 #include "diagnostics/xquery_diagnostics.h"
+#include "zorbautils/mutex.h"
 
 #include "ascii_util.h"
 #include "fs_util.h"
@@ -206,29 +208,15 @@
 
 #endif /* ZORBA_WITH_FILE_ACCESS */
 
-static bool to_char( LPCWSTR wpath, char *path ) {
-  return !!::WideCharToMultiByte(
-    CP_UTF8, 0, wpath, -1, path, MAX_PATH, NULL, NULL
-  );
-}
-
-static bool to_wchar( char const *path, LPWSTR wpath ) {
-  if ( ::MultiByteToWideChar( CP_UTF8, 0, path, -1, wpath, MAX_PATH ) )
-    return true;
-  return !!::MultiByteToWideChar( CP_ACP, 0, path, -1, wpath, MAX_PATH );
-}
-
 void make_absolute_impl( char const *path, char *abs_path ) {
 #ifndef WINCE
   WCHAR wpath[ MAX_PATH ];
-  to_wchar( path, wpath );
+  atow( path, wpath, MAX_PATH );
   WCHAR wfull_path[ MAX_PATH ];
-  DWORD const result = ::GetFullPathName(
-    wpath, sizeof( wfull_path ) / sizeof( wfull_path[0] ), wfull_path, NULL
-  );
+  DWORD const result = ::GetFullPathName( wpath, MAX_PATH, wfull_path, NULL );
   if ( !result )
     throw ZORBA_IO_EXCEPTION( "GetFullPathName()", path );
-  to_char( wfull_path, abs_path );
+  wtoa( wfull_path, abs_path, MAX_PATH );
 #else
   if ( abs_path != path )
     ::strcpy( abs_path, path );
@@ -249,7 +237,7 @@
     throw fs::exception( "chdir()", path );
 #else
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   if ( ::_wchdir( wpath ) != 0 )
     throw fs::exception( "_wchdir()", path );
 #endif /* WIN32 */
@@ -263,7 +251,7 @@
   ::close( fd );
 #else
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   HANDLE fd = ::CreateFile(
     wpath,
     GENERIC_READ | GENERIC_WRITE,
@@ -280,34 +268,58 @@
 
 string curdir() {
 #ifndef WIN32
+  static Mutex mutex;
   static size_t size = PATH_MAX;
-  static unique_ptr<char[]> path( new char[ size ] );
-  while ( !::getcwd( path.get(), size ) ) {
+  static unique_ptr<char[]> dir_buf( new char[ size ] );
+
+#ifndef ZORBA_FOR_ONE_THREAD_ONLY
+  AutoMutex const lock( &mutex );
+#endif /* ZORBA_FOR_ONE_THREAD_ONLY */
+  while ( !::getcwd( dir_buf.get(), size ) ) {
     if ( errno != ERANGE )
       throw ZORBA_IO_EXCEPTION( "getcwd()", "" );
-    path.reset( new char[ size *= 2 ] );
+    dir_buf.reset( new char[ size *= 2 ] );
   }
-  return path.get();
+  return dir_buf.get();
 #else
   WCHAR wpath[ MAX_PATH ];
-  if ( !::GetCurrentDirectory( sizeof( wpath ) / sizeof( wpath[0] ), wpath ) )
+  if ( !::GetCurrentDirectory( MAX_PATH, wpath ) )
     throw ZORBA_IO_EXCEPTION( "GetCurrentDirectory()", "" );
   char path[ MAX_PATH ];
-  win32::to_char( wpath, path );
-  if ( !is_absolute( path ) ) {
+  win32::wtoa( wpath, path, MAX_PATH );
+  string dir( path );
+  if ( !is_absolute( dir ) ) {
     // GetCurrentDirectory() sometimes misses drive letter.
-    make_absolute( path );
+    make_absolute( &dir );
   }
-  return path;
+  return dir;
 #endif /* WIN32 */
 }
 
 #ifdef ZORBA_WITH_FILE_ACCESS
 
-void get_temp_file( char *path ) {
+zstring get_temp_file() {
 #ifndef WIN32
-  if ( !::tmpnam( path ) )
-    throw fs::exception( "tmpnam()", static_cast<char const*>( path ) );
+  static char const mkdtemp_template[] = "zorba.XXXXXXXX";
+  static size_t const mkdtemp_template_len = ::strlen( mkdtemp_template );
+
+  char const *tmp_dir = ::getenv( "TMPDIR" );
+  if ( !tmp_dir )
+    tmp_dir = "/tmp";
+  unique_ptr<char[]> buf(
+    new char[
+      ::strlen( tmp_dir )
+      + 1 // dir_separator
+      + mkdtemp_template_len
+      + 1 // null
+    ]
+  );
+  ::strcpy( buf.get(), tmp_dir );
+  append( buf.get(), mkdtemp_template );
+  char const *const path = ::mkdtemp( buf.get() );
+  if ( !path )
+    throw fs::exception( "mkdtemp()", path );
+  return path;
 #else
   WCHAR wtemp[ MAX_PATH ];
   // GetTempFileName() needs a 14-character cushion.
@@ -318,7 +330,9 @@
   UINT const u_result = ::GetTempFileName( wtemp, TEXT("zxq"), 0, wpath );
   if ( !u_result )
     throw fs::exception( "GetTempFileName()", static_cast<char const*>(path) );
-  win32::to_char( wpath, path );
+  char path[ MAX_PATH ];
+  win32::wtoa( wpath, path, MAX_PATH );
+  return path;
 #endif /* WIN32 */
 }
 
@@ -363,23 +377,11 @@
   return type;
 #else
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   return win32::get_type( wpath, pinfo );
 #endif /* WIN32 */
 }
 
-void make_absolute( char *path ) {
-  if ( !is_absolute( path ) ) {
-#ifndef WIN32
-    string abs_path( curdir() );
-    append( abs_path, path );
-    abs_path.copy( path, abs_path.size() );
-#else
-    win32::make_absolute_impl( path, path );
-#endif /* WIN32 */
-  }
-}
-
 #ifdef ZORBA_WITH_FILE_ACCESS
 
 void mkdir_impl( char const *path, bool ignore_exists = false ) {
@@ -390,7 +392,7 @@
   }
 #else
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   if ( !::CreateDirectory( wpath, NULL ) &&
        !(ignore_exists && ::GetLastError() == ERROR_ALREADY_EXISTS) ) {
     throw fs::exception( "CreateDirectory()", path );
@@ -433,7 +435,7 @@
 }
 
 void iterator::ctor_impl() {
-  make_absolute( dir_path_ );
+  make_absolute( &dir_path_ );
 #ifndef WIN32
   if ( !(dir_ = ::opendir( dir_path_.c_str() )) )
     throw fs::exception( "iterator()", dir_path_.c_str() );
@@ -502,7 +504,7 @@
 
       if ( is_dots( ent_data_.cFileName ) )
         continue;                       // skip "." and ".." entries
-      win32::to_char( ent_data_.cFileName, entry_name_buf_ );
+      win32::wtoa( ent_data_.cFileName, entry_name_buf_, MAX_PATH );
       entry_.type = win32::map_type( ent_data_.dwFileAttributes );
       return true;
     }
@@ -528,7 +530,7 @@
 
 void iterator::win32_opendir( char const *path ) {
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   WCHAR wpattern[ MAX_PATH ];
   ::wcscpy( wpattern, wpath );
   ::PathAppend( wpattern, TEXT("*") );
@@ -553,7 +555,7 @@
   throw fs::exception( "remove()", path );
 #else
   WCHAR wpath[ MAX_PATH ];
-  win32::to_wchar( path, wpath );
+  win32::atow( path, wpath, MAX_PATH );
   char const *win32_fn_name;
 
   switch ( win32::get_type( wpath ) ) {
@@ -579,8 +581,8 @@
     throw fs::exception( "rename()", from );
 #else
   WCHAR wfrom[ MAX_PATH ], wto[ MAX_PATH ];
-  win32::to_wchar( from, wfrom );
-  win32::to_wchar( to, wto );
+  win32::atow( from, wfrom, MAX_PATH );
+  win32::atow( to, wto, MAX_PATH );
   if ( !::MoveFile( wfrom, wto ) )
     throw fs::exception( "MoveFile()", from );
 #endif /* WIN32 */

=== modified file 'src/util/fs_util.h'
--- src/util/fs_util.h	2013-06-12 00:32:27 +0000
+++ src/util/fs_util.h	2013-06-14 23:50:38 +0000
@@ -20,6 +20,7 @@
 #include <zorba/util/fs_util.h>
 
 #include "string_util.h"
+#include "zorbatypes/zstring.h"
 
 namespace zorba {
 namespace fs {
@@ -303,26 +304,10 @@
 /**
  * Gets a path for a temporary file.
  *
- * @param path_buf A buffer to receive the path.  It must be at least
- * \c MAX_PATH bytes long.
- * @throws fs::exception if the operation fails.
- */
-void get_temp_file( char *path_buf );
-
-/**
- * Gets a path for a temporary file.
- *
- * @tparam PathStringType The \a path string type.
- * @param path The string to receive the path.
- * @throws fs::exception if the operation fails.
- */
-template<class PathStringType> inline
-typename std::enable_if<ZORBA_IS_STRING(PathStringType),void>::type
-get_temp_file( PathStringType *path ) {
-  char path_buf[ MAX_PATH ];
-  get_temp_file( path_buf );
-  *path = path_buf;
-}
+ * @return Returns said path.
+ * @throws fs::exception if the operation fails.
+ */
+zstring get_temp_file();
 
 #endif /* ZORBA_WITH_FILE_ACCESS */
 

=== modified file 'src/util/locale.cpp'
--- src/util/locale.cpp	2013-06-12 00:21:05 +0000
+++ src/util/locale.cpp	2013-06-14 23:50:38 +0000
@@ -91,29 +91,13 @@
   }
 
   unique_ptr<WCHAR[]> wlocale_name( new WCHAR[ LOCALE_NAME_MAX_LENGTH ] );
-  MultiByteToWideChar(
-    CP_UTF8, 0, locale_name.c_str(), -1,
-    wlocale_name.get(), LOCALE_NAME_MAX_LENGTH
+  win32::atow(
+    locale_name.c_str(), wlocale_name.get(), LOCALE_NAME_MAX_LENGTH
   );
   return wlocale_name;
 }
 
 /**
- * Converts a wide character (UTF-16) string to a multibyte (UTF-8) string.
- *
- * @param ws The wide string to convert.
- * @return Returns the equivalent multi-byte string.
- */
-static unique_ptr<char[]> wtoa( LPCWSTR ws ) {
-  int const len = ::WideCharToMultiByte(
-    CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL
-  );
-  unique_ptr<char[]> s( new char[ len ] );
-  ::WideCharToMultiByte( CP_UTF8, 0, ws, -1, s.get(), len, NULL, NULL );
-  return s;
-}
-
-/**
  * Gets a particular piece of information from the user's default locale.
  *
  * @param constant The constant specifying which piece of locale information to
@@ -127,7 +111,7 @@
   unique_ptr<WCHAR[]> winfo( new WCHAR[ wlen ] );
   wlen = ::GetLocaleInfo( LOCALE_USER_DEFAULT, constant, winfo.get(), wlen );
   ZORBA_FATAL( wlen, "GetLocaleInfo() failed" );
-  unique_ptr<char[]> const info( wtoa( winfo.get() ) );
+  unique_ptr<char[]> const info( win32::wtoa( winfo.get() ) );
   return zstring( info.get() );
 }
 

=== modified file 'src/util/mmap_file.cpp'
--- src/util/mmap_file.cpp	2013-06-01 00:30:39 +0000
+++ src/util/mmap_file.cpp	2013-06-14 23:50:38 +0000
@@ -28,6 +28,7 @@
 #include "diagnostics/xquery_diagnostics.h"
 
 #include "mmap_file.h"
+#include "string_util.h"
 
 using namespace std;
 
@@ -95,11 +96,8 @@
 #else /* WIN32 */
 
 #ifdef UNICODE
-  TCHAR wPath[ 1024 ];
-  MultiByteToWideChar(
-    CP_ACP /* or CP_UTF8 */, 0, path, -1, wPath,
-    sizeof( wPath ) / sizeof( wPath[0] )
-  );
+  WCHAR wPath[ MAX_PATH ];
+  win32::atow( path, wPath, MAX_PATH );
 #else
   char const *const wPath = path;
 #endif /* UNICODE */

=== modified file 'src/util/string_util.h'
--- src/util/string_util.h	2013-06-01 00:30:39 +0000
+++ src/util/string_util.h	2013-06-14 23:50:38 +0000
@@ -25,9 +25,13 @@
 #include <sstream>
 #include <stdexcept>
 #include <string>
+#ifdef WIN32
+# include <windows.h>
+#endif /* WIN32 */
 
 // Zorba
 #include <zorba/internal/cxx_util.h>
+#include <zorba/internal/unique_ptr.h>
 #include <zorba/internal/ztd.h>
 #include "ascii_util.h"
 #include "stl_util.h"
@@ -1011,6 +1015,52 @@
   *out = s ? s : "<null>";
 }
 
+////////// Windows /////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+namespace win32 {
+
+/**
+ * Converts a wide-character (UTF-16) string to a multi-byte (UTF-8) string.
+ *
+ * @param ws The wide-character string to convert.
+ * @param s The string buffer to convert \a ws into.
+ * @param s_len The size of \a s (in bytes).
+ */
+inline bool wtoa( LPCWSTR ws, char *s, int s_len ) {
+  return !!::WideCharToMultiByte( CP_UTF8, 0, ws, -1, s, s_len, NULL, NULL );
+}
+
+/**
+ * Converts a wide character (UTF-16) string to a multibyte (UTF-8) string.
+ *
+ * @param ws The wide string to convert.
+ * @return Returns the equivalent multi-byte string.
+ */
+inline std::unique_ptr<char[]> wtoa( LPCWSTR ws ) {
+  int const s_len =
+    ::WideCharToMultiByte( CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL );
+  std::unique_ptr<char[]> s( new char[ s_len ] );
+  wtoa( ws, s.get(), s_len );
+  return s;
+}
+
+/**
+ * Converts a multi-byte (UTF-8) string to a wide-character (UTF-16) string.
+ *
+ * @param s The string to convert.
+ * @param ws The wide-character string buffer to convert \a s into.
+ * @param ws_len The size of \a ws (in characters).
+ */
+inline bool atow( char const *s, LPWSTR ws, int ws_len ) {
+  if ( ::MultiByteToWideChar( CP_UTF8, 0, s, -1, ws, ws_len ) )
+    return true;
+  return !!::MultiByteToWideChar( CP_ACP, 0, s, -1, ws, ws_len );
+}
+
+} // namespace win32
+#endif /* WIN32 */
+
 ////////// Miscellaneous ///////////////////////////////////////////////////////
 
 /**

=== modified file 'src/util/uri_util.cpp'
--- src/util/uri_util.cpp	2013-06-01 00:47:53 +0000
+++ src/util/uri_util.cpp	2013-06-14 23:50:38 +0000
@@ -105,29 +105,30 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void fetch_to_path_impl( char const *uri, char *path, bool *is_temp ) {
+zstring fetch( char const *uri, bool *is_temp ) {
 #ifdef ZORBA_WITH_FILE_ACCESS
-  zstring zpath;
-  bool temp = false;
+  zstring path;
+  bool temp;
+
   switch ( get_scheme( uri ) ) {
     case file:
     case none:
-      zpath = fs::normalize_path( uri );
+      path = fs::normalize_path( uri );
+      temp = false;
       break;
     default:
-      fs::get_temp_file( &zpath );
-      fstream stream( zpath.c_str() );
-      HttpStream lHttpStream(uri);
+      path = fs::get_temp_file();
+      temp = true;
+      fstream stream( path.c_str() );
+      HttpStream lHttpStream( uri );
       lHttpStream.init();
-      lHttpStream.getStream().get(*stream.rdbuf(), EOF);
+      lHttpStream.getStream().get( *stream.rdbuf(), EOF );
       //fetch( uri, stream );
-      temp = true;
       break;
   }
-  ::strncpy( path, zpath.c_str(), MAX_PATH );
-  path[ MAX_PATH - 1 ] = '\0';
   if ( is_temp )
     *is_temp = temp;
+  return path;
 #else
   throw ZORBA_EXCEPTION( zerr::ZXQP0017_FILE_ACCESS_DISABLED );
 #endif /* ZORBA_WITH_FILE_ACCESS */

=== modified file 'src/util/uri_util.h'
--- src/util/uri_util.h	2013-06-03 13:58:22 +0000
+++ src/util/uri_util.h	2013-06-14 23:50:38 +0000
@@ -201,46 +201,32 @@
   encode( s, &temp, encode_slash );
   s = temp;
 }
-  
+
 ////////// Fetching ///////////////////////////////////////////////////////////
 
-// Internal use only!
-void fetch_to_path_impl( char const *uri, char *path, bool *is_temp );
-  
 /**
  * Fetches a resource from the given URI to a local file.
  *
- * @tparam PathStringType The path's string type.
- * @param uri The URI specifying the resouce.
- * @param path On return, contains the path of the fetched resource.
+ * @param uri The URI specifying the resource.
  * @param is_temp If not \c nullptr, on return this is set to \c true if the
  * local file is a created temporary file; \c false otherwise.
+ * @return Returns the full path to the file the resource was fetched to.
  */
-template<class PathStringType> inline
-typename std::enable_if<ZORBA_IS_STRING(PathStringType),void>::type
-fetch( char const *uri, PathStringType *path, bool *is_temp = nullptr ) {
-  char path_buf[ MAX_PATH ];
-  fetch_to_path_impl( uri, path_buf, is_temp );
-  *path = path_buf;
-}
-  
+zstring fetch( char const *uri, bool *is_temp );
+
 /**
  * Fetches a resource from the given URI to a local file.
  *
  * @tparam URIStringType The URI's string type.
- * @tparam PathStringType The path's string type.
- * @param uri The URI specifying the resouce.
- * @param path On return, contains the path of the fetched resource.
+ * @param uri The URI specifying the resource.
  * @param is_temp If not \c nullptr, on return this is set to \c true if the
  * local file is a created temporary file; \c false otherwise.
+ * @return Returns the full path to the file the resource was fetched to.
  */
-template<class URIStringType,class PathStringType> inline
-typename std::enable_if<ZORBA_HAS_C_STR(URIStringType)
-                     && ZORBA_IS_STRING(PathStringType),
-                        void>::type
-fetch( URIStringType const &uri, PathStringType *file,
-       bool *is_temp = nullptr ) {
-  fetch( uri.c_str(), file, is_temp );
+template<class URIStringType> inline
+typename std::enable_if<ZORBA_HAS_C_STR(URIStringType),zstring>::type
+fetch( URIStringType const &uri, bool *is_temp = nullptr ) {
+  return fetch( uri.c_str(), is_temp );
 }
 
 ///////////////////////////////////////////////////////////////////////////////

=== modified file 'test/apitest.cpp'
--- test/apitest.cpp	2013-05-31 03:42:33 +0000
+++ test/apitest.cpp	2013-06-14 23:50:38 +0000
@@ -137,7 +137,7 @@
   if (! lProp->inlineQuery()) 
   {
     path = lProp->queryFile ();
-    fs::make_absolute( path );
+    fs::make_absolute( &path );
     qfile.reset (new ifstream (path.c_str ()));
     if (!qfile->good() || qfile->eof()) 
     {

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to