← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/bug-942171 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-942171 into lp:zorba.

Commit message:
Added arbitrary encoding support.
Added missing functions from spec.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #942171 in Zorba: "file module to allow for arbitrary encodings"
  https://bugs.launchpad.net/zorba/+bug/942171

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Added arbitrary encoding support.
Added missing functions from spec.
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-08-02 14:56:12 +0000
+++ ChangeLog	2013-08-05 22:16:26 +0000
@@ -28,6 +28,7 @@
   * Fixed bug #1189636 (transcoding hexBinary streambuf)
   * Fixed bug in hoisting through try-catch expr
   * Fixed bug #1162631 (format-integer 'w' format of negative numbers)
+  * Fixed bug #942171 (file module to allow for arbitrary encodings)
   * Fixed bug #1192285 (Have JSON token know number subtype)
   * Fixed bug #1190261 (relative paths bug in file module)
   * Fixed bug #1189798 (Update core module "errors")

=== modified file 'include/zorba/util/base64_stream.h'
--- include/zorba/util/base64_stream.h	2013-06-19 23:15:33 +0000
+++ include/zorba/util/base64_stream.h	2013-08-05 22:16:26 +0000
@@ -29,8 +29,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
- * A %base64::streambuf is-a std::streambuf for encoding to and decoding from
- * Base64 on-the-fly.
+ * A %base64::streambuf is-a std::streambuf for decoding from and encoding to 
+ * Base64 on-the-fly while reading or writing, respectively.
  *
  * To use it, replace a stream's streambuf:
  * \code
@@ -149,9 +149,10 @@
  * @param ios The stream to attach the base64::streambuf to.  If the stream
  * already has a base64::streambuf attached to it, this function does
  * nothing.
+ * @return \c true only if a base64::streambuf was attached.
  */
 template<typename charT,class Traits> inline
-void attach( std::basic_ios<charT,Traits> &ios ) {
+bool attach( std::basic_ios<charT,Traits> &ios ) {
   int const index = internal::base64::get_streambuf_index();
   void *&pword = ios.pword( index );
   if ( !pword ) {
@@ -160,7 +161,9 @@
     ios.rdbuf( buf );
     pword = buf;
     ios.register_callback( internal::stream_callback, index );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -170,15 +173,18 @@
  * @param ios The stream to detach the base64::streambuf from.  If the
  * stream doesn't have a base64::streambuf attached to it, this function
  * does nothing.
+ * @return \c true only if a base64::streambuf was detached.
  */
 template<typename charT,class Traits> inline
-void detach( std::basic_ios<charT,Traits> &ios ) {
+bool detach( std::basic_ios<charT,Traits> &ios ) {
   int const index = internal::base64::get_streambuf_index();
   if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
     ios.pword( index ) = nullptr;
     ios.rdbuf( buf->orig_streambuf() );
     internal::dealloc_streambuf( buf );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -210,26 +216,82 @@
 class auto_attach {
 public:
   /**
+   * Default constructor; does nothing.
+   */
+  auto_attach() : stream_( 0 ) {
+  }
+
+  /**
    * Constructs an %auto_attach object calling attach() on the given stream.
    *
    * @param stream The stream to attach the base64::streambuf to.  If the
    * stream already has a base64::streambuf attached to it, this contructor
    * does nothing.
    */
-  auto_attach( StreamType &stream ) : stream_( stream ) {
-    attach( stream );
+  auto_attach( StreamType &stream ) : stream_( &stream ) {
+    base64::attach( stream );
+  }
+
+  /**
+   * Copy constructor that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   */
+  auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
+    from.stream_ = 0;
   }
 
   /**
    * Destroys this %auto_attach object calling detach() on the previously
-   * attached stream.
+   * attached stream, if any.
    */
   ~auto_attach() {
-    detach( stream_ );
+    detach();
+  }
+
+  /**
+   * Assignment operator that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   * @return \c *this.
+   */
+  auto_attach& operator=( auto_attach &from ) {
+    if ( &from != this ) {
+      stream_ = from.stream_;
+      from.stream_ = 0;
+    }
+    return *this;
+  }
+
+  /**
+   * Calls base64::attach() on the given stream.
+   *
+   * @param stream The stream to attach the base64::streambuf to.  If the
+   * stream already has a base64::streambuf attached to it, this contructor
+   * does nothing.
+   * @param charset The name of the character encoding to convert from/to.
+   * @return \c true only if a base64::streambuf was attached.
+   */
+  bool attach( StreamType &stream, char const *charset ) {
+    if ( base64::attach( stream, charset ) ) {
+      stream_ = &stream;
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Calls base64::detach().
+   */
+  void detach() {
+    if ( stream_ ) {
+      base64::detach( *stream_ );
+      stream_ = 0;
+    }
   }
 
 private:
-  StreamType &stream_;
+  StreamType *stream_;
 };
 
 ///////////////////////////////////////////////////////////////////////////////

=== modified file 'include/zorba/util/fs_util.h'
--- include/zorba/util/fs_util.h	2013-08-02 14:55:29 +0000
+++ include/zorba/util/fs_util.h	2013-08-05 22:16:26 +0000
@@ -47,9 +47,11 @@
 #ifdef WIN32
 char const dir_separator = '\\';
 char const path_separator = ';';
+char const newline[] = "\r\n";
 #else
 char const dir_separator = '/';
 char const path_separator = ':';
+char const newline[] = "\n";
 #endif /* WIN32 */
 
 ////////// types //////////////////////////////////////////////////////////////
@@ -74,7 +76,6 @@
   volume,
   other   // named pipe, character/block special, socket, etc.
 };
-extern char const *const type_string[];
 
 /**
  * Emits the string representation of a file type to the given ostream.
@@ -83,9 +84,8 @@
  * @param t The file type to emit.
  * @return Returns \a o.
  */
-inline std::ostream& operator<<( std::ostream &o, type t ) {
-  return o << type_string[ t ];
-}
+ZORBA_DLL_PUBLIC
+std::ostream& operator<<( std::ostream &o, type t );
 
 ////////// Directory //////////////////////////////////////////////////////////
 

=== modified file 'include/zorba/util/hexbinary_stream.h'
--- include/zorba/util/hexbinary_stream.h	2013-06-20 00:53:29 +0000
+++ include/zorba/util/hexbinary_stream.h	2013-08-05 22:16:26 +0000
@@ -133,9 +133,10 @@
  * @param ios The stream to attach the hexbinary::streambuf to.  If the stream
  * already has a hexbinary::streambuf attached to it, this function does
  * nothing.
+ * @return \c true only if a hexbinary::streambuf was attached.
  */
 template<typename charT,class Traits> inline
-void attach( std::basic_ios<charT,Traits> &ios ) {
+bool attach( std::basic_ios<charT,Traits> &ios ) {
   int const index = internal::hexbinary::get_streambuf_index();
   void *&pword = ios.pword( index );
   if ( !pword ) {
@@ -144,7 +145,9 @@
     ios.rdbuf( buf );
     pword = buf;
     ios.register_callback( internal::stream_callback, index );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -154,15 +157,18 @@
  * @param ios The stream to detach the hexbinary::streambuf from.  If the
  * stream doesn't have a hexbinary::streambuf attached to it, this function
  * does nothing.
+ * @return \c true only if a hexbinary::streambuf was detached.
  */
 template<typename charT,class Traits> inline
-void detach( std::basic_ios<charT,Traits> &ios ) {
+bool detach( std::basic_ios<charT,Traits> &ios ) {
   int const index = internal::hexbinary::get_streambuf_index();
   if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
     ios.pword( index ) = nullptr;
     ios.rdbuf( buf->orig_streambuf() );
     internal::dealloc_streambuf( buf );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -194,26 +200,81 @@
 class auto_attach {
 public:
   /**
+   * Default constructor; does nothing.
+   */
+  auto_attach() : stream_( 0 ) {
+  }
+
+  /**
    * Constructs an %auto_attach object calling attach() on the given stream.
    *
    * @param stream The stream to attach the hexbinary::streambuf to.  If the
    * stream already has a hexbinary::streambuf attached to it, this contructor
    * does nothing.
    */
-  auto_attach( StreamType &stream ) : stream_( stream ) {
+  auto_attach( StreamType &stream ) : stream_( &stream ) {
     attach( stream );
   }
 
   /**
+   * Copy constructor that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   */
+  auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
+    from.stream_ = 0;
+  }
+
+  /**
    * Destroys this %auto_attach object calling detach() on the previously
    * attached stream.
    */
   ~auto_attach() {
-    detach( stream_ );
+    detach();
+  }
+
+  /**
+   * Assignment operator that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   * @return \c *this.
+   */
+  auto_attach& operator=( auto_attach &from ) {
+    if ( &from != this ) {
+      stream_ = from.stream_;
+      from.stream_ = 0;
+    }
+    return *this;
+  }
+
+  /**
+   * Calls hexbinary::attach() on the given stream.
+   *
+   * @param stream The stream to attach the hexbinary::streambuf to.  If the
+   * stream already has a hexbinary::streambuf attached to it, this contructor
+   * does nothing.
+   * @return \c true only if a hexbinary::streambuf was attached.
+   */
+  bool attach( StreamType &stream ) {
+    if ( hexbinary::attach( stream ) ) {
+      stream_ = &stream;
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Calls hexbinary::detach().
+   */
+  void detach() {
+    if ( stream_ ) {
+      hexbinary::detach( *stream_ );
+      stream_ = 0;
+    }
   }
 
 private:
-  StreamType &stream_;
+  StreamType *stream_;
 };
 
 ///////////////////////////////////////////////////////////////////////////////

=== modified file 'include/zorba/util/transcode_stream.h'
--- include/zorba/util/transcode_stream.h	2013-06-12 00:21:05 +0000
+++ include/zorba/util/transcode_stream.h	2013-08-05 22:16:26 +0000
@@ -139,9 +139,10 @@
  * already has a transcode::streambuf attached to it, this function does
  * nothing.
  * @param charset The name of the character encoding to convert from/to.
+ * @return \c true only if a transcode::streambuf was attached.
  */
 template<typename charT,class Traits> inline
-void attach( std::basic_ios<charT,Traits> &ios, char const *charset ) {
+bool attach( std::basic_ios<charT,Traits> &ios, char const *charset ) {
   int const index = internal::transcode::get_streambuf_index();
   void *&pword = ios.pword( index );
   if ( !pword ) {
@@ -150,7 +151,9 @@
     ios.rdbuf( buf );
     pword = buf;
     ios.register_callback( internal::stream_callback, index );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -160,15 +163,18 @@
  * @param ios The stream to detach the transcode::streambuf from.  If the
  * stream doesn't have a transcode::streambuf attached to it, this function
  * does nothing.
+ * @return \c true only if a transcode::streambuf was detached.
  */
 template<typename charT,class Traits> inline
-void detach( std::basic_ios<charT,Traits> &ios ) {
+bool detach( std::basic_ios<charT,Traits> &ios ) {
   int const index = internal::transcode::get_streambuf_index();
   if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
     ios.pword( index ) = nullptr;
     ios.rdbuf( buf->orig_streambuf() );
     internal::dealloc_streambuf( buf );
+    return true;
   }
+  return false;
 }
 
 /**
@@ -214,6 +220,12 @@
 class auto_attach {
 public:
   /**
+   * Default constructor; does nothing.
+   */
+  auto_attach() : stream_( 0 ) {
+  }
+
+  /**
    * Constructs an %auto_attach object calling attach() on the given stream.
    *
    * @param stream The stream to attach the transcode::streambuf to.  If the
@@ -221,20 +233,70 @@
    * does nothing.
    * @param charset The name of the character encoding to convert from/to.
    */
-  auto_attach( StreamType &stream, char const *charset ) : stream_( stream ) {
-    attach( stream, charset );
+  auto_attach( StreamType &stream, char const *charset ) : stream_( &stream ) {
+    transcode::attach( stream, charset );
+  }
+
+  /**
+   * Copy constructor that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   */
+  auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
+    from.stream_ = 0;
   }
 
   /**
    * Destroys this %auto_attach object calling detach() on the previously
-   * attached stream.
+   * attached stream, if any.
    */
   ~auto_attach() {
-    detach( stream_ );
+    detach();
+  }
+
+  /**
+   * Assignment operator that takes ownership of the stream.
+   *
+   * @param from The %auto_attach to take ownership from.
+   * @return \c *this.
+   */
+  auto_attach& operator=( auto_attach &from ) {
+    if ( &from != this ) {
+      stream_ = from.stream_;
+      from.stream_ = 0;
+    }
+    return *this;
+  }
+
+  /**
+   * Calls transcode::attach() on the given stream.
+   *
+   * @param stream The stream to attach the transcode::streambuf to.  If the
+   * stream already has a transcode::streambuf attached to it, this contructor
+   * does nothing.
+   * @param charset The name of the character encoding to convert from/to.
+   * @return \c true only if a transcode::streambuf was attached.
+   */
+  bool attach( StreamType &stream, char const *charset ) {
+    if ( transcode::attach( stream, charset ) ) {
+      stream_ = &stream;
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Calls transcode::detach().
+   */
+  void detach() {
+    if ( stream_ ) {
+      transcode::detach( *stream_ );
+      stream_ = 0;
+    }
   }
 
 private:
-  StreamType &stream_;
+  StreamType *stream_;
 };
 
 ///////////////////////////////////////////////////////////////////////////////

=== modified file 'modules/org/expath/ns/file.xq'
--- modules/org/expath/ns/file.xq	2013-06-15 20:57:44 +0000
+++ modules/org/expath/ns/file.xq	2013-08-05 22:16:26 +0000
@@ -1,7 +1,7 @@
 xquery version "3.0";
 
 (:
- : Copyright 2006-2009 The FLWOR Foundation.
+ : Copyright 2006-2013 The FLWOR Foundation.
  :
  : Licensed under the Apache License, Version 2.0 (the "License");
  : you may not use this file except in compliance with the License.
@@ -24,68 +24,128 @@
  :)
 module namespace file = "http://expath.org/ns/file";;
 
-import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";;
 declare namespace an = "http://www.zorba-xquery.com/annotations";;
 declare namespace ver = "http://www.zorba-xquery.com/options/versioning";;
 declare option ver:module-version "2.0";
 
 (:~
- : Appends a sequence of items to a file. If the file pointed by <pre>$file</pre>
- : does not exist, a new file will be created. Before writing to the file, the items
- : are serialized according to the <pre>$serializer-params</pre>.
- :
- : The semantics of <pre>$serializer-params</pre> is the same as for the
- : <pre>$params</pre> parameter of the <a target="_blank"
- : href="http://www.w3.org/TR/xpath-functions-11/#func-serialize";>fn:serialize</a>
- : function.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @param $serializer-params Parameter to control the serialization of the
- :    content.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:append(
-  $file as xs:string,
-  $content as item()*,
-  $serializer-params as element(output:serialization-parameters)?
-) as empty-sequence()
-{
-  file:append-text(
-    $file,
-    fn:serialize($content, $serializer-params))
-};
-
-(:~
  : Appends a sequence of Base64 items as binary to a file. If the file pointed
  : by <pre>$file</pre> does not exist, a new file will be created.
  :
  : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:append-binary(
-  $file as xs:string,
-  $content as xs:base64Binary*
-) as empty-sequence() external;
-
-(:~
- : Appends a sequence of string items to a file.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %private %an:sequential function file:append-text(
-  $file as xs:string,
-  $content as xs:string*
-) as empty-sequence() external;
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:append-binary( $file as xs:string, $content as xs:base64Binary )
+  as empty-sequence() external;
+
+(:~
+ : Appends a sequence of string items to a file.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @param $encoding The character encoding to append <code>$content</code> as.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:append-text( $file as xs:string, $content as xs:string*,
+                           $encoding as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Appends a sequence of string items to a file.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:append-text( $file as xs:string, $content as xs:string* )
+  as empty-sequence()
+{
+  file:append-text( $file, $content, "UTF-8" )
+};
+
+(:~
+ : Appends a sequence of string items to a file, each followed by a
+ : platform-dependent newline character(s).
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @param $encoding The character encoding to append <code>$content</code> as.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:append-text-lines( $file as xs:string, $content as xs:string*,
+                                 $encoding as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Appends a sequence of string to a file, each followed by a
+ : platform-dependent newline character(s), using the UTF-8 character encoding.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:append-text-lines( $file as xs:string, $content as xs:string* )
+  as empty-sequence()
+{
+  file:append-text-lines( $file, $content, "UTF-8" )
+};
+
+(:~
+ : Returns the last component from the <pre>$path</pre>, deleting any
+ : trailing directory-separator characters. If <pre>$path</pre> consists
+ : entirely directory-separator characters, the empty string is returned. If
+ : <pre>$path</pre> is the empty string, the string <pre>"."</pre> is returned,
+ : signifying the current directory.
+ :
+ : No path existence check is made.
+ :
+ : @param $path A file path/URI.
+ : @return The base name of this file.
+ :)
+declare function file:base-name( $path as xs:string )
+  as xs:string external;
+
+(:~
+ : Returns the last component from the <pre>$path</pre>, deleting any
+ : trailing directory-separator characters and the <pre>$suffix</pre>. If path
+ : consists entirely directory-separator characters, the empty string is
+ : returned. If path is the empty string, the string <pre>"."</pre> is
+ : returned, signifying the current directory.
+ :
+ : No path existence check is made.
+ :
+ : The <pre>$suffix</pre> can be used for example to eliminate file extensions.
+ :
+ : @param $path A file path/URI.
+ : @param $suffix A suffix which should get deleted from the result.
+ : @return The base-name of $path with a deleted $suffix.
+ :)
+declare function file:base-name( $path as xs:string, $suffix as xs:string )
+  as xs:string
+{
+  let $res := file:base-name($path)
+  return
+    if (fn:ends-with($res, $suffix) and $res ne ".") then
+      fn:substring($res, 1, fn:string-length($res) - fn:string-length($suffix))
+    else
+      $res
+};
 
 (:~
  : Copies a file or a directory given a source and a destination path/URI.
@@ -100,10 +160,9 @@
  :    parent directory does not exist either.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:nondeterministic %an:sequential function file:copy(
-  $source as xs:string,
-  $destination as xs:string
-) as empty-sequence()
+declare %an:nondeterministic %an:sequential
+function file:copy( $source as xs:string, $destination as xs:string )
+  as empty-sequence()
 {
   if (file:exists($source)) then
     if (file:is-directory($source)) then
@@ -115,89 +174,6 @@
 };
 
 (:~
- : Copies a file given a source and a destination path/URI.
- :
- : @param $sourceFile The path/URI of the file to copy.
- : @param $destination The destination path/URI.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0002 If the computed destination points to directory.
- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
- :    parent directory does not exist either.
- : @error file:FOFL0004 If <pre>$sourceFile</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %private %an:sequential function file:copy-file-impl(
-  $sourceFile as xs:string,
-  $destination as xs:string
-) as empty-sequence() external;
-
-(:~
- : Copies a source directory recursively to a destination path/URI.
- :
- : @param $sourceDir The path/URI of the directory to copy.
- : @param $destination The destination path/URI.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0002 If <pre>$destination</pre> points to an existing file.
- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
- :    parent directory does not exist either.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %private %an:nondeterministic %an:sequential function file:copy-directory-impl(
-  $sourceDir as xs:string,
-  $destination as xs:string
-) as empty-sequence()
-{
-  if (file:is-file($destination)) then
-    fn:error(xs:QName("file:FOFL0002"), fn:concat("The specified destination path already exists: ", $destination))
-  else if (fn:not(file:exists($destination))) then
-    let $dirname := file:dir-name($destination)
-    return
-      if (fn:not(file:exists($dirname))) then
-        fn:error(xs:QName("file:FOFL0003"), fn:concat("The destination directory does not exist: ", $dirname))
-      else
-        {
-          file:create-directory($destination);
-          file:copy-directory-content($sourceDir, $destination)
-        }
-
-  else
-    let $basename := file:base-name($sourceDir)
-    let $newdir := fn:concat($destination, file:directory-separator(), $basename)
-    return
-      {
-        file:create-directory($newdir);
-        file:copy-directory-content($sourceDir, $newdir)
-      }
-};
-
-(:~
- : Copies the content of a given directory to an existing destination
- : directory.
- :
- : @param $sourceDir The path/URI of the directory to copy the content from.
- : @param $destination The destination directory path/URI.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0003 If <pre>$destination</pre> directory does not exist.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %private %an:nondeterministic %an:sequential function file:copy-directory-content(
-  $sourceDir as xs:string,
-  $destination as xs:string
-) as empty-sequence()
-{
-  if (file:is-directory($destination)) then
-    for $item in file:list($sourceDir)
-    let $fullPath := fn:concat($sourceDir, file:directory-separator(), $item)
-    return
-      file:copy($fullPath, $destination)
-  else
-    fn:error(xs:QName("file:FOFL0003"), fn:concat("The specified destination directory does not exist: ", $destination))    
-};
-
-(:~
  : Creates a directory.
  :
  : The operation is will create all the missing parent directories from the
@@ -209,9 +185,9 @@
  :    existing file.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:sequential function file:create-directory(
-  $dir as xs:string
-) as empty-sequence() external;
+declare %an:sequential function
+file:create-directory( $dir as xs:string )
+  as empty-sequence() external;
 
 (:~
  : Deletes a file or a directory from the file system.
@@ -224,9 +200,9 @@
  : @error file:FOFL0001 If the <pre>$path</pre> path does not exist.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:nondeterministic %an:sequential function file:delete(
-  $path as xs:string
-) as empty-sequence()
+declare %an:nondeterministic %an:sequential
+function file:delete( $path as xs:string )
+  as empty-sequence()
 {
   if (file:exists($path,false())) then
     if (not(file:is-symlink($path)) and file:is-directory($path)) then
@@ -238,40 +214,29 @@
 };
 
 (:~
- : Deletes a file from the file system.
+ : This function returns the value of the operating system specific directory
+ : separator. For example, <pre>/</pre> on Unix-based systems and <pre>\</pre>
+ : on Windows systems.
  :
- : @param $file The path/URI of the file to delete.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$file</pre> path does not exist.
- : @error file:FOFL9999 If any other error occurs.
+ : @return The operating system specific directory separator.
  :)
-declare %private %an:sequential function file:delete-file-impl(
-  $file as xs:string
-) as empty-sequence() external;
+declare function file:directory-separator()
+  as xs:string external;
 
 (:~
- : Deletes a directory from the file system.
- :
- : @param $dir The path/URI of the directory to delete.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$dir</pre> path does not exist.
- : @error file:FOFL0003 If <pre>$dir</pre> does not point to a directory.
- : @error file:FOFL9999 If any other error occurs.
+ : This function is the converse of <pre>file:base-name</pre>. It returns a
+ : string denoting the parent directory of the <pre>$path</pre>. Any trailing
+ : directory-separator characters are not counted as part of the directory
+ : name. If path is the empty string or contains no directory-separator string,
+ : <pre>"."</pre> is returned, signifying the current directory.
+ :
+ : No path existence check is made.
+ :
+ : @param $path The filename, of which the dirname should be get.
+ : @return The name of the directory the file is in.
  :)
-declare %private %an:nondeterministic %an:sequential function file:delete-directory-impl(
-  $dir as xs:string
-) as empty-sequence()
-{
-  for $item in file:list($dir)
-  let $fullPath := fn:concat($dir, file:directory-separator(), $item)
-  return
-    if (file:is-directory($fullPath)) then
-      file:delete-directory-impl($fullPath);
-    else
-      file:delete-file-impl($fullPath);
-    
-  file:delete-file-impl($dir)
-};
+declare function file:dir-name( $path as xs:string )
+  as xs:string external;
 
 (:~
  : Tests if a path/URI is already used in the file system.
@@ -280,9 +245,9 @@
  : @param $follow-symlinks if <code>true</code>, follows symbolic links.
  : @return true if <code>$path</code> points to an existing file system item.
  :)
-declare %an:nondeterministic function file:exists(
-  $path as xs:string, $follow-symlinks as xs:boolean
-) as xs:boolean external;
+declare %an:nondeterministic
+function file:exists( $path as xs:string, $follow-symlinks as xs:boolean )
+  as xs:boolean external;
 
 (:~
  : Tests if a path/URI is already used in the file system.
@@ -291,11 +256,27 @@
  : @return true if <code>$path</code> points to an existing file system item;
  : for symbolic links, retuns true if the linked-to item exists.
  :)
-declare %an:nondeterministic function file:exists(
-  $path as xs:string
-) as xs:boolean
-{
-  file:exists($path,true())
+declare %an:nondeterministic
+function file:exists( $path as xs:string )
+  as xs:boolean
+{
+  file:exists( $path, true() )
+};
+
+(:~
+ : A helper function that performs a trivial (not complete) glob to regex
+ : pattern translation.
+ : 
+ : @param $pattern The glob pattern.
+ : @return A regex pattern corresponding to the glob pattern provided.
+ :)
+declare function file:glob-to-regex( $pattern as xs:string )
+  as xs:string
+{
+  let $pattern := fn:replace($pattern, '(\.|\[|\]|\\|/|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
+  let $pattern := fn:replace($pattern, '\\\?', '.')
+  let $pattern := fn:replace($pattern, '\\\*', '.*')
+  return fn:concat( "^", $pattern, "$" )
 };
 
 (:~
@@ -306,9 +287,9 @@
  : @return true if <code>$path</code> points to a directory; for symbolic
  : links, returns true if the linked-to item is a directory.
  :)
-declare %an:nondeterministic function file:is-directory(
-  $path as xs:string
-) as xs:boolean external;
+declare %an:nondeterministic
+function file:is-directory( $path as xs:string )
+  as xs:boolean external;
 
 (:~
  : Tests if a path/URI points to a file.
@@ -317,9 +298,9 @@
  : @return true if <code>$path</code> points to a file; for symbolic links,
  : returns true if the linked-to item is a file.
  :)
-declare %an:nondeterministic function file:is-file(
-  $path as xs:string
-) as xs:boolean external;
+declare %an:nondeterministic
+function file:is-file( $path as xs:string )
+  as xs:boolean external;
 
 (:~
  : Tests if a path/URI points to symbolic link.  This works on all Unix-based
@@ -328,235 +309,22 @@
  : @param $path The path/URI to test.
  : @return true if <code>$path</code> points to a symbolic link.
  :)
-declare %an:nondeterministic function file:is-symlink(
-  $path as xs:string
-) as xs:boolean external;
-
-(:~
- : Moves a file or directory given a source and a destination paths/URIs.
- :
- : @param $source The path/URI of the file to move.
- : @param $destination The destination path/URI.
- : @return The empty sequence.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0002 If <pre>$source</pre> points to a directory and
- :    <pre>$destination</pre> points to an existing file.
- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's parent
- :    directory does not exist either.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:move(
-  $source as xs:string,
-  $destination as xs:string
-) as empty-sequence()
-{
-  file:copy($source, $destination);
-  file:delete($source);
-};
-
-(:~
- : Reads the content of a file and returns a Base64 representation of the
- : content.
- :
- : @param $file The file to read.
- : @return The content of the file as Base64.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:read-binary(
-  $file as xs:string
-) as xs:base64Binary external;
-
-(:~
- : Reads the content of a file and returns a string representation of the
- : content.
- :
- : The operation is equivalent to calling:
- : <pre>file:read-text($file, "UTF-8")</pre>.
- :
- : @param $file The file to read.
- : @return The content of the file as string.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:read-text(
-  $file as xs:string
-) as xs:string
-{
-  file:read-text($file, "UTF-8")
-};
-
-(:~
- : Reads the content of a file using the specified encoding and returns a
- : string representation of the content.
- :
- : @param $file The file to read.
- : @param $encoding The encoding used when reading the file.
- : If compiled with ICU, then Zorba supports any encoding that ICU supports;
- : otherwise Zorba only supports ASCII and UTF-8.
- : The encoding parameter is case insensitive.
- : @return The content of the file as string.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
- : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:read-text(
-  $file as xs:string,
-  $encoding as xs:string
-) as xs:string external;
-
-(:~
- : Reads the content of a file and returns a sequence of strings representing
- : the lines in the content of the file.
- :
- : The operation is equivalent to calling:
- : <pre>file:read-text-lines($file, "UTF-8")</pre>.
- :
- : @param $file The file to read.
- : @return The content of the file as a sequence of strings.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:read-text-lines(
-  $file as xs:string
-) as xs:string*
-{
-  file:read-text-lines($file, "UTF-8")
-};
-
-(:~
- : Reads the content of a file using the specified encoding and returns a
- : sequence of strings representing the lines in the content of the file.
- :
- : This implementation considers the LF (&#xA;) character as the line
- : separator. If a resulting line ends with the CR (&#xD;) character, this is
- : trimmed as well. This implementation will uniformly treat LF and CRLF as
- : line separators.
- :
- : @param $file The file to read.
- : @param $encoding The encoding used when reading the file.
- : If compiled with ICU, then Zorba supports any encoding that ICU supports;
- : otherwise Zorba only supports ASCII and UTF-8.
- : The encoding parameter is case insensitive.
- : @return The content of the file as a sequence of strings.
- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
- : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:read-text-lines(
-  $file as xs:string,
-  $encoding as xs:string
-) as xs:string* external;
-
-(:~
- : This is an internal function that copies an entire source directory to an
- : destination directory. The caller to this function must make sure that both
- : the source and destination point to existing directories.
- :
- : @param $sourceDir The existing source directory.
- : @param $destinationDir The existing destination directory.
- : @return The empty sequence.
- :)
-declare %private %an:nondeterministic %an:sequential function file:copy-directory(
-  $sourceDir as xs:string,
-  $destinationDir as xs:string
-) as empty-sequence()
-{
-  let $name := file:base-name($sourceDir)
-  let $destDir := fn:concat($destinationDir, file:directory-separator(), $name)
-  return
-    {
-      file:create-directory($destDir);
-
-      for $item in file:list($sourceDir)
-      let $fullSrcPath := fn:concat($sourceDir, file:directory-separator(), $item)
-      let $fullDestPath := fn:concat($destDir, file:directory-separator(), $item)
-      return
-        if (file:is-directory($fullSrcPath)) then
-          file:copy-directory($fullSrcPath, $fullDestPath)
-        else
-          file:copy($fullSrcPath, $fullDestPath)
-    }
-};
-
-(:~
- : Writes a sequence of items to a file. Before writing to the file, the items
- : are serialized according to the <pre>$serializer-params</pre>.
- :
- : The semantics of <pre>$serializer-params</pre> is the same as for the
- : <pre>$params</pre> parameter of the <a target="_blank"
- : href="http://www.w3.org/TR/xpath-functions-11/#func-serialize";>fn:serialize</a>
- : function.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @param $serializer-params Parameter to control the serialization of the
- :        content.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:write(
-  $file as xs:string,
-  $content as item()*,
-  $serializer-params as element(output:serialization-parameters)?
-) as empty-sequence()
-{
-  file:write-text($file, fn:serialize($content, $serializer-params))
-};
-
-(:~
- : Writes a sequence of Base64 items as binary to a file.
- :
- : The operation is equivalent to calling:
- : <pre>file:write-binary($file, $content, fn:true())</pre>.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:write-binary(
-  $file as xs:string,
-  $content as xs:base64Binary*
-) as empty-sequence() external;
-
-(:~
- : Writes a sequence of Base64 items as binary to a file.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:sequential function file:write-binary(
-  $file as xs:string,
-  $content as xs:base64Binary*
-) as empty-sequence() external;
-
-(:~
- : Writes a sequence of string items to a file.
- :
- : The operation is equivalent to calling:
- : <pre>file:write-text($file, $content, fn:true())</pre>.
- :
- : @param $file The path/URI of the file to write the content to.
- : @param $content The content to be serialized to the file.
- : @return The empty sequence.
- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %private %an:sequential function file:write-text(
-  $file as xs:string,
-  $content as xs:string*
-) as empty-sequence() external;
+declare %an:nondeterministic
+function file:is-symlink( $path as xs:string )
+  as xs:boolean external;
+
+(:~
+ : Retrieves the timestamp of the last modification of the file system item
+ : pointed by the path/URI.
+ :
+ : @param $path The file system item to read the last modification
+ :    timestamp from.
+ : @return The date and time of the last modification of the item.
+ : @error file:FOFL0001 If the <pre>$path</pre> does not exist.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic function file:last-modified( $path as xs:string )
+  as xs:dateTime external;
 
 (:~
  : Lists the file system items in a certain directory.
@@ -569,9 +337,9 @@
  : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:nondeterministic function file:list(
-  $dir as xs:string
-) as xs:string* external;
+declare %an:nondeterministic
+function file:list( $dir as xs:string )
+  as xs:string* external;
 
 (:~
  : Lists the file system items in a certain directory. The order of the items
@@ -588,10 +356,9 @@
  : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:nondeterministic function file:list(
-  $path as xs:string,
-  $recursive as xs:boolean
-) as xs:string*
+declare %an:nondeterministic
+function file:list( $path as xs:string, $recursive as xs:boolean )
+  as xs:string*
 {
   for $f in file:list($path)
   let $full := fn:concat($path, file:directory-separator(), $f)
@@ -625,81 +392,174 @@
  : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
  : @error file:FOFL9999 If any other error occurs.
  :)
-declare %an:nondeterministic function file:list(
-  $path as xs:string,
-  $recursive as xs:boolean,
-  $pattern as xs:string
-) as xs:string* {
-  for $file in file:list($path, $recursive)
-  let $name := file:base-name($file)
+declare %an:nondeterministic
+function file:list( $path as xs:string, $recursive as xs:boolean,
+                    $pattern as xs:string )
+  as xs:string*
+{
+  for $file in file:list( $path, $recursive )
+  let $name := file:base-name( $file )
   return
-    if (fn:matches($name, file:glob-to-regex($pattern))) then
+    if ( fn:matches( $name, file:glob-to-regex( $pattern ) ) ) then
       $file
     else
       ()
 };
 
 (:~
- : A helper function that performs a trivial (not complete) glob to regex
- : pattern translation.
- : 
- : @param $pattern The glob pattern.
- : @return A regex pattern corresponding to the glob pattern provided.
+ : Moves a file or directory given a source and a destination paths/URIs.
+ :
+ : @param $source The path/URI of the file to move.
+ : @param $destination The destination path/URI.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0002 If <pre>$source</pre> points to a directory and
+ : <pre>$destination</pre> points to an existing file.
+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and its
+ : parent directory does not exist either.
+ : @error file:FOFL9999 If any other error occurs.
  :)
-declare function file:glob-to-regex(
-  $pattern as xs:string
-) as xs:string {
-  let $pattern := fn:replace($pattern, '(\.|\[|\]|\\|/|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
-  let $pattern := fn:replace($pattern, '\\\?', '.')
-  let $pattern := fn:replace($pattern, '\\\*', '.*')
-  return
-    fn:concat("^", $pattern, "$")
+declare %an:sequential
+function file:move( $source as xs:string, $destination as xs:string )
+  as empty-sequence()
+{
+  file:copy( $source, $destination );
+  file:delete( $source );
 };
 
 (:~
- : Retrieves the timestamp of the last modification of the file system item
- : pointed by the path/URI.
- :
- : @param $path The file system item to read the last modification
- :    timestamp from.
- : @return The date and time of the last modification of the item.
- : @error file:FOFL0001 If the <pre>$path</pre> does not exist.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:last-modified(
-  $path as xs:string
-) as xs:dateTime external;
-
-(:~
- : Retrieves the size of a file.
- :
- : @param $file The file get the size.
- : @return An integer representing the size in bytes of the file.
- : @error file:FOFL0001 If the <pre>$file</pre> does not exist.
- : @error file:FOFL0004 If the <pre>$file</pre> points to a directory.
- : @error file:FOFL9999 If any other error occurs.
- :)
-declare %an:nondeterministic function file:size(
-  $file as xs:string
-) as xs:integer external;
-
-(:~
- : This function returns the value of the operating system specific directory
- : separator. For example, <pre>/</pre> on Unix-based systems and <pre>\</pre>
- : on Windows systems.
- :
- : @return The operating system specific directory separator.
- :)
-declare function file:directory-separator() as xs:string external;
-
-(:~
  : This function returns the value of the operating system specific path
  : separator. For example, <pre>:</pre> on Unix-based systems and <pre>;</pre>
  : on Windows systems.
  :
  : @return The operating system specific path separator.
  :)
-declare function file:path-separator() as xs:string external;
+declare function file:path-separator()
+  as xs:string external;
+
+(:~
+ : Transforms a URI, an absolute path, or relative path to a native path on the
+ : running platform.
+ :
+ : No path existence check is made.
+ :
+ : @param $path The uri or path to normalize.
+ : @return The native path corresponding to <pre>$path</pre>.
+ : @error file:FOFL9999 If an error occurs while trying to obtain the native
+ : path.
+ :)
+declare function file:path-to-native( $path as xs:string )
+  as xs:string external;
+
+(:~
+ : Transforms a file system path into a URI with the file:// scheme. If the
+ : path is relative, it is first resolved against the current working
+ : directory.
+ :
+ : No path existence check is made.
+ :
+ : @param $path The path to transform.
+ : @return The file URI corresponding to <pre>path</pre>.
+ :)
+declare function file:path-to-uri( $path as xs:string )
+  as xs:anyURI external;
+
+(:~
+ : Reads the content of a file and returns a Base64 representation of the
+ : content.
+ :
+ : @param $file The file to read.
+ : @return The content of the file as Base64.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic
+function file:read-binary( $file as xs:string )
+  as xs:base64Binary external;
+
+(:~
+ : Reads the content of a file using the specified encoding and returns a
+ : string representation of the content.
+ :
+ : @param $file The file to read.
+ : @param $encoding The encoding used when reading the file.
+ : If compiled with ICU, then Zorba supports any encoding that ICU supports;
+ : otherwise Zorba only supports ASCII and UTF-8.
+ : The encoding parameter is case insensitive.
+ : @return The content of the file as string.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
+ : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic
+function file:read-text( $file as xs:string, $encoding as xs:string )
+  as xs:string external;
+
+(:~
+ : Reads the content of a file and returns a string representation of the
+ : content.
+ :
+ : The operation is equivalent to calling:
+ : <pre>file:read-text($file, "UTF-8")</pre>.
+ :
+ : @param $file The file to read.
+ : @return The content of the file as string.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic
+function file:read-text( $file as xs:string )
+  as xs:string
+{
+  file:read-text( $file, "UTF-8" )
+};
+
+(:~
+ : Reads the content of a file and returns a sequence of strings representing
+ : the lines in the content of the file.
+ :
+ : The operation is equivalent to calling:
+ : <pre>file:read-text-lines($file, "UTF-8")</pre>.
+ :
+ : @param $file The file to read.
+ : @return The content of the file as a sequence of strings.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic
+function file:read-text-lines( $file as xs:string )
+  as xs:string*
+{
+  file:read-text-lines( $file, "UTF-8" )
+};
+
+(:~
+ : Reads the content of a file using the specified encoding and returns a
+ : sequence of strings representing the lines in the content of the file.
+ :
+ : This implementation considers the LF (&#xA;) character as the line
+ : separator. If a resulting line ends with the CR (&#xD;) character, this is
+ : trimmed as well. This implementation will uniformly treat LF and CRLF as
+ : line separators.
+ :
+ : @param $file The file to read.
+ : @param $encoding The encoding used when reading the file.
+ : If compiled with ICU, then Zorba supports any encoding that ICU supports;
+ : otherwise Zorba only supports ASCII and UTF-8.
+ : The encoding parameter is case insensitive.
+ : @return The content of the file as a sequence of strings.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
+ : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic
+function file:read-text-lines( $file as xs:string, $encoding as xs:string )
+  as xs:string* external;
 
 (:~
  : Transforms a relative path/URI into an absolute operating system path by
@@ -710,88 +570,247 @@
  : @param $path The path/URI to transform.
  : @return The operating system file path.
  :)
-declare function file:resolve-path(
-  $path as xs:string
-) as xs:string external;
-
-(:~
- : Transforms a file system path into a URI with the file:// scheme. If the
- : path is relative, it is first resolved against the current working
+declare function file:resolve-path( $path as xs:string )
+  as xs:string external;
+
+(:~
+ : Retrieves the size of a file.
+ :
+ : @param $file The file get the size.
+ : @return An integer representing the size in bytes of the file.
+ : @error file:FOFL0001 If the <pre>$file</pre> does not exist.
+ : @error file:FOFL0004 If the <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:nondeterministic function file:size( $file as xs:string )
+  as xs:integer external;
+
+(:~
+ : Writes a sequence of Base64 items as binary to a file.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:write-binary( $file as xs:string, $content as xs:base64Binary )
+  as empty-sequence() external;
+
+(:~
+ : Writes a sequence of strings to a file.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @param $encoding The character encoding to write <code>$content</code> as.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:write-text( $file as xs:string, $content as xs:string*,
+                          $encoding as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Writes a sequence of strings to a file using the UTF-8 character encoding.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:write-text( $file as xs:string, $content as xs:string* )
+  as empty-sequence()
+{
+  file:write-text( $file, $content, "UTF-8" )
+};
+
+(:~
+ : Writes a sequence of strings to a file, each followed by a
+ : platform-dependent newline character(s).
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @param $encoding The character encoding to write <code>$content</code> as.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:write-text-lines( $file as xs:string, $content as xs:string*,
+                                $encoding as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Writes a sequence of strings to a file, each followed by a
+ : platform-dependent newline character(s), using the UTF-8 character encoding.
+ :
+ : @param $file The path/URI of the file to write the content to.
+ : @param $content The content to be written to the file.
+ : @return The empty sequence.
+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %an:sequential
+function file:write-text-lines( $file as xs:string, $content as xs:string* )
+  as empty-sequence()
+{
+  file:write-text-lines( $file, $content, "UTF-8" )
+};
+
+(:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)
+
+(:~
+ : Copies a file given a source and a destination path/URI.
+ :
+ : @param $sourceFile The path/URI of the file to copy.
+ : @param $destination The destination path/URI.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0002 If the computed destination points to directory.
+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
+ :    parent directory does not exist either.
+ : @error file:FOFL0004 If <pre>$sourceFile</pre> points to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %private %an:sequential
+function file:copy-file-impl( $sourceFile as xs:string,
+                              $destination as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Copies a source directory recursively to a destination path/URI.
+ :
+ : @param $sourceDir The path/URI of the directory to copy.
+ : @param $destination The destination path/URI.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0002 If <pre>$destination</pre> points to an existing file.
+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
+ :    parent directory does not exist either.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %private %an:nondeterministic %an:sequential
+function file:copy-directory-impl( $sourceDir as xs:string,
+                                   $destination as xs:string )
+  as empty-sequence()
+{
+  if (file:is-file($destination)) then
+    fn:error(xs:QName("file:FOFL0002"), fn:concat("The specified destination path already exists: ", $destination))
+  else if (fn:not(file:exists($destination))) then
+    let $dirname := file:dir-name($destination)
+    return
+      if (fn:not(file:exists($dirname))) then
+        fn:error(xs:QName("file:FOFL0003"), fn:concat("The destination directory does not exist: ", $dirname))
+      else
+        {
+          file:create-directory($destination);
+          file:copy-directory-content($sourceDir, $destination)
+        }
+  else
+    let $basename := file:base-name($sourceDir)
+    let $newdir := fn:concat($destination, file:directory-separator(), $basename)
+    return
+      {
+        file:create-directory($newdir);
+        file:copy-directory-content($sourceDir, $newdir)
+      }
+};
+
+(:~
+ : This is an internal function that copies an entire source directory to an
+ : destination directory. The caller to this function must make sure that both
+ : the source and destination point to existing directories.
+ :
+ : @param $sourceDir The existing source directory.
+ : @param $destinationDir The existing destination directory.
+ : @return The empty sequence.
+ :)
+declare %private %an:nondeterministic %an:sequential
+function file:copy-directory( $sourceDir as xs:string,
+                              $destinationDir as xs:string )
+  as empty-sequence()
+{
+  let $name := file:base-name($sourceDir)
+  let $destDir := fn:concat($destinationDir, file:directory-separator(), $name)
+  return
+    {
+      file:create-directory($destDir);
+
+      for $item in file:list($sourceDir)
+      let $fullSrcPath := fn:concat($sourceDir, file:directory-separator(), $item)
+      let $fullDestPath := fn:concat($destDir, file:directory-separator(), $item)
+      return
+        if (file:is-directory($fullSrcPath)) then
+          file:copy-directory($fullSrcPath, $fullDestPath)
+        else
+          file:copy($fullSrcPath, $fullDestPath)
+    }
+};
+
+(:~
+ : Copies the content of a given directory to an existing destination
  : directory.
  :
- : No path existence check is made.
- :
- : @param $path The path to transform.
- : @return The file URI corresponding to <pre>path</pre>.
- :)
-declare function file:path-to-uri(
-  $path as xs:string
-) as xs:anyURI external;
-
-(:~
- : Transforms a URI, an absolute path, or relative path to a native path on the
- : running platform.
- :
- : No path existence check is made.
- :
- : @param $path The uri or path to normalize.
- : @return The native path corresponding to <pre>$path</pre>.
- : @error file:FOFL9999 If an error occurs while trying to obtain the native path.
- :)
-declare function file:path-to-native($path as xs:string) as xs:string external;
-
-(:~
- : Returns the last component from the <pre>$path</pre>, deleting any
- : trailing directory-separator characters. If <pre>$path</pre> consists
- : entirely directory-separator characters, the empty string is returned. If
- : <pre>$path</pre> is the empty string, the string <pre>"."</pre> is returned,
- : signifying the current directory.
- :
- : No path existence check is made.
- :
- : @param $path A file path/URI.
- : @return The base name of this file.
- :)
-declare function file:base-name($path as xs:string) as xs:string external;
-
-(:~
- : Returns the last component from the <pre>$path</pre>, deleting any
- : trailing directory-separator characters and the <pre>$suffix</pre>. If path
- : consists entirely directory-separator characters, the empty string is
- : returned. If path is the empty string, the string <pre>"."</pre> is
- : returned, signifying the current directory.
- :
- : No path existence check is made.
- :
- : The <pre>$suffix</pre> can be used for example to eliminate file extensions.
- :
- : @param $path A file path/URI.
- : @param $suffix A suffix which should get deleted from the result.
- : @return The base-name of $path with a deleted $suffix.
- :)
-declare function file:base-name($path as xs:string, $suffix as xs:string)
-  as xs:string
-{
-  let $res := file:base-name($path)
+ : @param $sourceDir The path/URI of the directory to copy the content from.
+ : @param $destination The destination directory path/URI.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
+ : @error file:FOFL0003 If <pre>$destination</pre> directory does not exist.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %private %an:nondeterministic %an:sequential
+function file:copy-directory-content( $sourceDir as xs:string,
+                                      $destination as xs:string )
+  as empty-sequence()
+{
+  if (file:is-directory($destination)) then
+    for $item in file:list($sourceDir)
+    let $fullPath := fn:concat($sourceDir, file:directory-separator(), $item)
+    return
+      file:copy($fullPath, $destination)
+  else
+    fn:error(xs:QName("file:FOFL0003"), fn:concat("The specified destination directory does not exist: ", $destination))    
+};
+
+(:~
+ : Deletes a file from the file system.
+ :
+ : @param $file The path/URI of the file to delete.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$file</pre> path does not exist.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %private %an:sequential
+function file:delete-file-impl( $file as xs:string )
+  as empty-sequence() external;
+
+(:~
+ : Deletes a directory from the file system.
+ :
+ : @param $dir The path/URI of the directory to delete.
+ : @return The empty sequence.
+ : @error file:FOFL0001 If the <pre>$dir</pre> path does not exist.
+ : @error file:FOFL0003 If <pre>$dir</pre> does not point to a directory.
+ : @error file:FOFL9999 If any other error occurs.
+ :)
+declare %private %an:nondeterministic %an:sequential
+function file:delete-directory-impl( $dir as xs:string )
+  as empty-sequence()
+{
+  for $item in file:list($dir)
+  let $fullPath := fn:concat($dir, file:directory-separator(), $item)
   return
-    if (fn:ends-with($res, $suffix) and $res ne ".") then
-      fn:substring($res, 1, fn:string-length($res) - fn:string-length($suffix))
+    if (file:is-directory($fullPath)) then
+      file:delete-directory-impl($fullPath);
     else
-      $res
+      file:delete-file-impl($fullPath);
+    
+  file:delete-file-impl($dir)
 };
 
-(:~
- : This function is the converse of <pre>file:base-name</pre>. It returns a
- : string denoting the parent directory of the <pre>$path</pre>. Any trailing
- : directory-separator characters are not counted as part of the directory
- : name. If path is the empty string or contains no directory-separator string,
- : <pre>"."</pre> is returned, signifying the current directory.
- :
- : No path existence check is made.
- :
- : @param $path The filename, of which the dirname should be get.
- : @return The name of the directory the file is in.
- :)
-declare function file:dir-name($path as xs:string) as xs:string external;
-
 (: vim:set et sw=2 ts=2: :)

=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
--- modules/org/expath/ns/file.xq.src/file.cpp	2013-08-05 11:54:06 +0000
+++ modules/org/expath/ns/file.xq.src/file.cpp	2013-08-05 22:16:26 +0000
@@ -38,10 +38,31 @@
 namespace zorba {
 namespace filemodule {
 
-//*****************************************************************************
-
-BaseNameFunction::BaseNameFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+///////////////////////////////////////////////////////////////////////////////
+
+AppendTextFunction::AppendTextFunction( FileModule const *m ) :
+  WriteTextFunctionImpl( m, "append-text", true, false )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+AppendTextLinesFunction::AppendTextLinesFunction( FileModule const *m ) :
+  WriteTextFunctionImpl( m, "append-text-lines", true, true )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+AppendBinaryFunction::AppendBinaryFunction( FileModule const *m ) :
+  WriteBinaryFunctionImpl( m, "append-binary", true )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+BaseNameFunction::BaseNameFunction( FileModule const *m ) :
+  FileFunction( m, "base-name" )
 {
 }
 
@@ -55,14 +76,63 @@
   while ( path.size() > 1 && path[ path.size() - 1 ] == fs::dir_separator )
     path.erase( path.size() - 1 );
   String const base_name( fs::base_name( path ) );
-  Item item( theModule->getItemFactory()->createString( base_name ) );
+  Item item( module_->getItemFactory()->createString( base_name ) );
   return ItemSequence_t( new SingletonItemSequence( item ) );
 }
 
-//*****************************************************************************
-
-CreateDirectoryFunction::CreateDirectoryFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+///////////////////////////////////////////////////////////////////////////////
+
+CopyFileImplFunction::CopyFileImplFunction( FileModule const *m ) :
+  FileFunction( m, "copy-file-impl" )
+{
+}
+
+ItemSequence_t
+CopyFileImplFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const src_path( getPathArg( args, 0 ) );
+  String dst_path( getPathArg( args, 1 ) );
+
+  fs::type const src_type = fs::get_type( src_path );
+  if ( !src_type )
+    raiseFileError( "FOFL0001", "file not found", src_path );
+  if ( src_type != fs::file )
+    raiseFileError( "FOFL0004", "not a plain file", src_path );
+
+  fs::type dst_type = fs::get_type( dst_path );
+  if ( dst_type == fs::directory ) {    // we are copying into a directory
+    fs::append( dst_path, fs::base_name( src_path ) );
+    dst_type = fs::get_type( dst_path );
+    if ( dst_type == fs::directory )
+      raiseFileError( "FOFL0002", "path already exists", dst_path );
+  }
+
+  if ( src_path == dst_path )
+    raiseFileError( "FOFL9999", "source and destination paths must not be equal", src_path );
+
+  try {
+    std::ifstream fin( src_path.c_str(), std::ios_base::binary );
+    std::ofstream fout( dst_path.c_str(), std::ios_base::binary | std::ios_base::trunc );
+    char buf[ 8192 ];
+    while ( !fin.eof() ) {
+      fin.read( buf, sizeof buf );
+      fout.write( buf, fin.gcount() );
+    }  
+  }
+  catch ( std::exception const &e ) {
+    throw raiseFileError( "FOFL9999", e.what(), src_path );
+  }
+
+  return ItemSequence_t( new EmptySequence() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+CreateDirectoryFunction::CreateDirectoryFunction( FileModule const *m ) :
+  FileFunction( m, "create-directory" )
 {
 }
 
@@ -75,31 +145,25 @@
   String const path( getPathArg( args, 0 ) );
 
   fs::type const fs_type = fs::get_type( path );
-  if ( !fs_type )
-  {
+  if ( !fs_type ) {
     try {
       fs::mkdir( path, true );
     }
     catch ( std::exception const &e ) {
       throw raiseFileError( "FOFL9999", e.what(), path );
     }
-  }
-  else if ( fs_type != fs::directory )
-  {
+  } else if ( fs_type != fs::directory )
     raiseFileError( "FOFL0002", "file already exists", path );
-  }
   else
-  {
     /* directory already exists: do nothing */;
-  }
 
   return ItemSequence_t( new EmptySequence() );
 }
 
-//*****************************************************************************
+///////////////////////////////////////////////////////////////////////////////
 
-DeleteFileImplFunction::DeleteFileImplFunction(const FileModule* aModule) :
-  FileFunction(aModule)
+DeleteFileImplFunction::DeleteFileImplFunction( FileModule const *m ) :
+  FileFunction( m, "delete-file-impl" )
 {
 }
 
@@ -124,10 +188,31 @@
   return ItemSequence_t( new EmptySequence() );
 }
 
-//*****************************************************************************
-
-DirNameFunction::DirNameFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+///////////////////////////////////////////////////////////////////////////////
+
+DirectorySeparator::DirectorySeparator( FileModule const *m ) :
+  FileFunction( m, "directory-separator" )
+{
+}
+
+ItemSequence_t
+DirectorySeparator::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const dir_separator( 1, fs::dir_separator );
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createString( dir_separator )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+DirNameFunction::DirNameFunction( FileModule const *m ) :
+  FileFunction( m, "dir-name" )
 {
 }
 
@@ -141,14 +226,235 @@
   while ( path.size() > 1 && path[ path.size() - 1 ] == fs::dir_separator )
     path.erase( path.size() - 1 );
   String const dir_name( fs::dir_name( path ) );
-  Item item( theModule->getItemFactory()->createString( dir_name ) );
+  Item item( module_->getItemFactory()->createString( dir_name ) );
   return ItemSequence_t( new SingletonItemSequence( item ) );
 }
 
-//*****************************************************************************
-
-ReadBinaryFunction::ReadBinaryFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
+///////////////////////////////////////////////////////////////////////////////
+
+ExistsFunction::ExistsFunction( FileModule const *m ) :
+  FileFunction( m, "exists" )
+{
+}
+
+ItemSequence_t
+ExistsFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path = getPathArg( args, 0 );
+  bool const follow_symlink = getItem( args, 1 ).getBooleanValue();
+  bool const exists = !!fs::get_type( path, follow_symlink );
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createBoolean( exists )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+IsDirectoryFunction::IsDirectoryFunction( FileModule const *m ) :
+  FileFunction( m, "is-directory" )
+{
+}
+
+ItemSequence_t
+IsDirectoryFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+  bool const is_directory = fs::get_type( path ) == fs::directory;
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createBoolean( is_directory )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+IsFileFunction::IsFileFunction( FileModule const *m ) :
+  FileFunction( m, "is-file" )
+{
+}
+
+ItemSequence_t
+IsFileFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+  bool const is_file = fs::get_type( path ) == fs::file;
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createBoolean( is_file )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+IsSymlinkFunction::IsSymlinkFunction( FileModule const *m ) :
+  FileFunction( m, "is-symlink" )
+{
+}
+
+ItemSequence_t
+IsSymlinkFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+  bool const is_symlink = fs::get_type( path, false ) == fs::link;
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createBoolean( is_symlink )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+LastModifiedFunction::LastModifiedFunction( FileModule const *m ) :
+  FileFunction( m, "last-modified" )
+{
+}
+
+ItemSequence_t
+LastModifiedFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+
+  fs::info info;
+  if ( !fs::get_type( path, &info ) )
+    raiseFileError( "FOFL0001", "file not found", path );
+
+  try {
+    time_t lTime = info.mtime;
+    // result of localtime needs to be copied.
+    // Otherwise, nasty side effecs do happen
+    struct tm lT( *localtime( &lTime ) );
+    int gmtOffset = LastModifiedFunction::getGmtOffset();
+
+    return ItemSequence_t(
+      new SingletonItemSequence(
+        module_->getItemFactory()->createDateTime(
+          1900 + lT.tm_year,
+          lT.tm_mon,
+          lT.tm_mday,
+          lT.tm_hour,
+          lT.tm_min, 
+          lT.tm_sec,
+          gmtOffset
+        )
+      )
+    );
+  }
+  catch ( std::exception const &e ) {
+    throw raiseFileError( "FOFL9999", e.what(), path );
+  }
+}
+
+int
+LastModifiedFunction::getGmtOffset()
+{
+  time_t t = ::time(0);
+  struct tm* data;
+  data = localtime(&t);
+  data->tm_isdst = 0;
+  time_t a = mktime(data);
+  data = gmtime(&t);
+  data->tm_isdst = 0;
+  time_t b = mktime(data);
+  return (int)(a - b)/3600; 
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ListFunction::ListFunction( FileModule const *m ) :
+  FileFunction( m, "list" )
+{
+}
+
+ItemSequence_t
+ListFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+
+  if ( fs::get_type( path ) != fs::directory )
+    raiseFileError( "FOFL0003", "path is not a directory", path );
+
+  try {
+    return ItemSequence_t(
+      new IteratorBackedItemSequence( path, module_->getItemFactory() )
+    );
+  }
+  catch ( std::exception const &e ) {
+    throw raiseFileError( "FOFL9999", e.what(), path );
+  }
+}
+
+ListFunction::IteratorBackedItemSequence::IteratorBackedItemSequence(
+  String const& path,
+  ItemFactory* aFactory
+) :
+  theIterator( path ),
+  theItemFactory( aFactory )
+{
+  is_open = false;
+  open_count = 0;
+}
+
+Iterator_t ListFunction::IteratorBackedItemSequence::getIterator()
+{
+  return this;
+}
+
+void ListFunction::IteratorBackedItemSequence::open()
+{
+  if (open_count) {
+    theIterator.reset();
+  }
+  open_count++;
+  is_open = true;
+}
+
+void ListFunction::IteratorBackedItemSequence::close()
+{
+  is_open = false;
+}
+
+bool ListFunction::IteratorBackedItemSequence::isOpen() const
+{
+  return is_open;
+}
+
+bool
+ListFunction::IteratorBackedItemSequence::next(Item& lItem)
+{
+  if ( !theIterator.next() )
+    return false;
+  String const lUriStr( theIterator->name );
+  lItem = theItemFactory->createString( lUriStr );
+  return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ReadBinaryFunction::ReadBinaryFunction( FileModule const *m ) :
+  FileFunction( m, "read-binary" )
 {
 }
 
@@ -170,7 +476,7 @@
     std::unique_ptr<std::ifstream> pin(
       new std::ifstream( path.c_str(), std::ios_base::binary )
     );
-    Item item = theModule->getItemFactory()->createStreamableBase64Binary(
+    Item item = module_->getItemFactory()->createStreamableBase64Binary(
       *pin, &FileModule::streamReleaser, true
     );
     pin.release();
@@ -181,10 +487,10 @@
   }
 }
 
-//*****************************************************************************
+///////////////////////////////////////////////////////////////////////////////
 
-ReadTextFunction::ReadTextFunction(const FileModule* aModule)
-  : StreamableFileFunction(aModule)
+ReadTextFunction::ReadTextFunction( FileModule const *m ) :
+  FileFunction( m, "read-text" )
 {
 }
 
@@ -221,7 +527,7 @@
 
   pin->open( path.c_str() );
   skip_utf8_bom( *pin );
-  lResult = theModule->getItemFactory()->createStreamableString(
+  lResult = module_->getItemFactory()->createStreamableString(
     *pin, &FileModule::streamReleaser, path.c_str(), true
   );
   pin.release();
@@ -229,10 +535,10 @@
   return ItemSequence_t( new SingletonItemSequence( lResult ) );
 }
 
-//*****************************************************************************
+///////////////////////////////////////////////////////////////////////////////
 
-ReadTextLinesFunction::ReadTextLinesFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+ReadTextLinesFunction::ReadTextLinesFunction( FileModule const *m ) :
+  FileFunction( m, "read-text-lines" )
 {
 }
 
@@ -285,14 +591,11 @@
 {
 }
 
-ReadTextLinesFunction::LinesItemSequence::LinesIterator::~LinesIterator()
-{
+ReadTextLinesFunction::LinesItemSequence::LinesIterator::~LinesIterator() {
   delete theStream;
 }
 
-void
-ReadTextLinesFunction::LinesItemSequence::LinesIterator::open()
-{
+void ReadTextLinesFunction::LinesItemSequence::LinesIterator::open() {
   if ( transcode::is_necessary( theEncoding.c_str() ) ) {
     try {
       theStream = new transcode::stream<std::ifstream>( theEncoding.c_str() );
@@ -307,8 +610,7 @@
 }
 
 bool
-ReadTextLinesFunction::LinesItemSequence::LinesIterator::next(Item& aRes)
-{
+ReadTextLinesFunction::LinesItemSequence::LinesIterator::next(Item& aRes) {
   if ( !theStream || !theStream->good() )
     return false;
 
@@ -317,7 +619,7 @@
   if ( theStream->bad() )
     return false;
   
-  aRes = theFunc->theModule->getItemFactory()->createString( s );
+  aRes = theFunc->module_->getItemFactory()->createString( s );
   return true;
 }
 
@@ -331,312 +633,13 @@
 bool
 ReadTextLinesFunction::LinesItemSequence::LinesIterator::isOpen() const
 {
-  return theStream != 0;
-}
-
-//*****************************************************************************
-
-ExistsFunction::ExistsFunction(const FileModule* aModule) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-ExistsFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path = getPathArg( args, 0 );
-  bool const follow_symlink = getItem( args, 1 ).getBooleanValue();
-  bool const exists = !!fs::get_type( path, follow_symlink );
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createBoolean( exists )
-    )
-  );
-}
-
-//*****************************************************************************
-
-IsDirectoryFunction::IsDirectoryFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-IsDirectoryFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-  bool const is_directory = fs::get_type( path ) == fs::directory;
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createBoolean( is_directory )
-    )
-  );
-}
-
-//*****************************************************************************
-
-IsFileFunction::IsFileFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-IsFileFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-  bool const is_file = fs::get_type( path ) == fs::file;
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createBoolean( is_file )
-    )
-  );
-}
-
-//*****************************************************************************
-
-IsSymlinkFunction::IsSymlinkFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-IsSymlinkFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-  bool const is_symlink = fs::get_type( path, false ) == fs::link;
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createBoolean( is_symlink )
-    )
-  );
-}
-
-//*****************************************************************************
-
-CopyFileImplFunction::CopyFileImplFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-CopyFileImplFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const src_path( getPathArg( args, 0 ) );
-  String dst_path( getPathArg( args, 1 ) );
-
-  fs::type const src_type = fs::get_type( src_path );
-  if ( !src_type )
-    raiseFileError( "FOFL0001", "file not found", src_path );
-  if ( src_type != fs::file )
-    raiseFileError( "FOFL0004", "not a plain file", src_path );
-
-  fs::type dst_type = fs::get_type( dst_path );
-  if ( dst_type == fs::directory ) {    // we are copying into a directory
-    fs::append( dst_path, fs::base_name( src_path ) );
-    dst_type = fs::get_type( dst_path );
-    if ( dst_type == fs::directory )
-      raiseFileError( "FOFL0002", "path already exists", dst_path );
-  }
-
-  if ( src_path == dst_path )
-    raiseFileError( "FOFL9999", "source and destination paths must not be equal", src_path );
-
-  try {
-    std::ifstream fin( src_path.c_str(), std::ios_base::binary );
-    std::ofstream fout( dst_path.c_str(), std::ios_base::binary | std::ios_base::trunc );
-    char buf[ 8192 ];
-    while ( !fin.eof() ) {
-      fin.read( buf, sizeof buf );
-      fout.write( buf, fin.gcount() );
-    }  
-  }
-  catch ( std::exception const &e ) {
-    throw raiseFileError( "FOFL9999", e.what(), src_path );
-  }
-
-  return ItemSequence_t( new EmptySequence() );
-}
-
-//*****************************************************************************
-
-ListFunction::ListFunction( FileModule const *aModule ) :
-  FileFunction( aModule )
-{
-}
-
-ItemSequence_t
-ListFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-
-  if ( fs::get_type( path ) != fs::directory )
-    raiseFileError( "FOFL0003", "path is not a directory", path );
-
-  try {
-    return ItemSequence_t(
-      new IteratorBackedItemSequence( path, theModule->getItemFactory() )
-    );
-  }
-  catch ( std::exception const &e ) {
-    throw raiseFileError( "FOFL9999", e.what(), path );
-  }
-}
-
-ListFunction::IteratorBackedItemSequence::IteratorBackedItemSequence(
-  String const& path,
-  ItemFactory* aFactory
-) :
-  theIterator( path ),
-  theItemFactory( aFactory )
-{
-  is_open = false;
-  open_count = 0;
-}
-
-ListFunction::IteratorBackedItemSequence::~IteratorBackedItemSequence()
-{
-}
-
-Iterator_t ListFunction::IteratorBackedItemSequence::getIterator()
-{
-  return this;
-}
-
-void ListFunction::IteratorBackedItemSequence::open()
-{
-  if (open_count) {
-    theIterator.reset();
-  }
-  open_count++;
-  is_open = true;
-}
-
-void ListFunction::IteratorBackedItemSequence::close()
-{
-  is_open = false;
-}
-
-bool ListFunction::IteratorBackedItemSequence::isOpen() const
-{
-  return is_open;
-}
-
-bool
-ListFunction::IteratorBackedItemSequence::next(Item& lItem)
-{
-  if ( !theIterator.next() )
-    return false;
-  String const lUriStr( theIterator->name );
-  lItem = theItemFactory->createString( lUriStr );
-  return true;
-}
-
-//*****************************************************************************
-
-LastModifiedFunction::LastModifiedFunction(const FileModule* aModule) :
-  FileFunction(aModule)
-{
-}
-
-ItemSequence_t
-LastModifiedFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-
-  fs::info info;
-  if ( !fs::get_type( path, &info ) )
-    raiseFileError( "FOFL0001", "file not found", path );
-
-  try {
-    time_t lTime = info.mtime;
-    // result of localtime needs to be copied.
-    // Otherwise, nasty side effecs do happen
-    struct tm lT(*localtime(&lTime));
-    int gmtOffset = LastModifiedFunction::getGmtOffset();
-
-    return ItemSequence_t(
-      new SingletonItemSequence(
-        theModule->getItemFactory()->createDateTime(
-          1900 + lT.tm_year,
-          lT.tm_mon,
-          lT.tm_mday,
-          lT.tm_hour,
-          lT.tm_min, 
-          lT.tm_sec,
-          gmtOffset
-        )
-      )
-    );
-  }
-  catch ( std::exception const &e ) {
-    throw raiseFileError( "FOFL9999", e.what(), path );
-  }
-}
-
-int
-LastModifiedFunction::getGmtOffset()
-{
-  time_t t = ::time(0);
-  struct tm* data;
-  data = localtime(&t);
-  data->tm_isdst = 0;
-  time_t a = mktime(data);
-  data = gmtime(&t);
-  data->tm_isdst = 0;
-  time_t b = mktime(data);
-  return (int)(a - b)/3600; 
-}
-
-//*****************************************************************************
-
-SizeFunction::SizeFunction(const FileModule* aModule)
-  : FileFunction(aModule)
-{
-}
-
-ItemSequence_t
-SizeFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-
-  fs::info info;
-  if ( !fs::get_type( path, &info ) )
-    raiseFileError( "FOFL0001", "file not found", path );
-  if ( info.type != fs::file )
-    raiseFileError( "FOFL0004", "not plain file", path );
-
-  return ItemSequence_t(new SingletonItemSequence(
-    theModule->getItemFactory()->createInteger(info.size)));
-}
-
-//*****************************************************************************
-
-PathSeparator::PathSeparator(const FileModule* aModule)
-  : FileFunction(aModule)
+  return !!theStream;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+PathSeparator::PathSeparator( FileModule const *m ) :
+  FileFunction( m, "path-separator" )
 {
 }
 
@@ -649,58 +652,15 @@
   String const path_separator( 1, fs::path_separator );
   return ItemSequence_t(
     new SingletonItemSequence(
-      theModule->getItemFactory()->createString( path_separator )
-    )
-  );
-}
-
-//*****************************************************************************
-
-DirectorySeparator::DirectorySeparator(const FileModule* aModule)
-  : FileFunction(aModule)
-{
-}
-
-ItemSequence_t
-DirectorySeparator::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const dir_separator( 1, fs::dir_separator );
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createString( dir_separator )
-    )
-  );
-}
-
-//*****************************************************************************
-
-ResolvePathFunction::ResolvePathFunction(const FileModule* aModule)
-  : FileFunction(aModule)
-{
-}
-
-ItemSequence_t
-ResolvePathFunction::evaluate(
-  ExternalFunction::Arguments_t const &args,
-  StaticContext const*,
-  DynamicContext const* ) const
-{
-  String const path( getPathArg( args, 0 ) );
-  String const result( pathToOSPath( path ) );
-  return ItemSequence_t(
-    new SingletonItemSequence(
-      theModule->getItemFactory()->createString( result )
-    )
-  );
-}
-
-//*****************************************************************************
-
-PathToNativeFunction::PathToNativeFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+      module_->getItemFactory()->createString( path_separator )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+PathToNativeFunction::PathToNativeFunction( FileModule const *m ) :
+  FileFunction( m, "path-to-native" )
 {
 }
 
@@ -715,7 +675,7 @@
     String const native_path( fs::normalize_path( path ) );
     return ItemSequence_t(
       new SingletonItemSequence(
-        theModule->getItemFactory()->createString( native_path )
+        module_->getItemFactory()->createString( native_path )
       )
     );
   }
@@ -724,10 +684,10 @@
   }
 }
 
-//*****************************************************************************
+///////////////////////////////////////////////////////////////////////////////
 
-PathToUriFunction::PathToUriFunction(const FileModule* aModule)
-  : FileFunction(aModule)
+PathToUriFunction::PathToUriFunction( FileModule const *m ) :
+  FileFunction( m, "path-to-uri" )
 {
 }
 
@@ -741,80 +701,87 @@
   String const result = pathToUriString( path );
   return ItemSequence_t(
     new SingletonItemSequence(
-      theModule->getItemFactory()->createAnyURI( result ) )
-  );
-}
-
-//*****************************************************************************
-
-WriteTextFunction::WriteTextFunction(const FileModule* aModule)
-  : WriterFileFunction(aModule)
-{
-}
-
-bool
-WriteTextFunction::isAppend() const {
-  return false;
-}
-
-bool
-WriteTextFunction::isBinary() const {
-  return false;
-}
-
-//*****************************************************************************
-
-WriteBinaryFunction::WriteBinaryFunction(const FileModule* aModule)
-  : WriterFileFunction(aModule)
-{
-}
-
-bool
-WriteBinaryFunction::isAppend() const {
-  return false;
-}
-
-bool
-WriteBinaryFunction::isBinary() const {
-  return true;
-}
-
-//*****************************************************************************
-
-AppendTextFunction::AppendTextFunction(const FileModule* aModule)
-  : WriterFileFunction(aModule)
-{
-}
-
-bool
-AppendTextFunction::isAppend() const {
-  return true;
-}
-
-bool
-AppendTextFunction::isBinary() const {
-  return false;
-}
-
-//*****************************************************************************
-
-AppendBinaryFunction::AppendBinaryFunction(const FileModule* aModule)
-  : WriterFileFunction(aModule)
-{
-}
-
-bool
-AppendBinaryFunction::isAppend() const {
-  return true;
-}
-
-bool
-AppendBinaryFunction::isBinary() const {
-  return true;
-}
-
-//*****************************************************************************
-
+      module_->getItemFactory()->createAnyURI( result )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ResolvePathFunction::ResolvePathFunction( FileModule const *m ) :
+  FileFunction( m, "resolve-path" )
+{
+}
+
+ItemSequence_t
+ResolvePathFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+  try {
+    return ItemSequence_t(
+      new SingletonItemSequence(
+        module_->getItemFactory()->createString( fs::normalize_path( path ) )
+      )
+    );
+  }
+  catch ( std::invalid_argument const &e ) {
+    throw raiseFileError( "FOFL9999", e.what(), path );
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SizeFunction::SizeFunction( FileModule const *m ) :
+  FileFunction( m, "size" )
+{
+}
+
+ItemSequence_t
+SizeFunction::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+
+  fs::info info;
+  if ( !fs::get_type( path, &info ) )
+    raiseFileError( "FOFL0001", "file not found", path );
+  if ( info.type != fs::file )
+    raiseFileError( "FOFL0004", "not plain file", path );
+
+  return ItemSequence_t(
+    new SingletonItemSequence(
+      module_->getItemFactory()->createInteger( info.size )
+    )
+  );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+WriteBinaryFunction::WriteBinaryFunction( FileModule const *m ) :
+  WriteBinaryFunctionImpl( m, "write-binary", false )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+WriteTextFunction::WriteTextFunction( FileModule const *m ) :
+  WriteTextFunctionImpl( m, "write-text", false, false )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+WriteTextLinesFunction::WriteTextLinesFunction( FileModule const *m ) :
+  WriteTextFunctionImpl( m, "write-text-lines", false, true )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 } // namespace filemodule
 } // namespace zorba

=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
--- modules/org/expath/ns/file.xq.src/file.h	2013-06-12 15:35:27 +0000
+++ modules/org/expath/ns/file.xq.src/file.h	2013-08-05 22:16:26 +0000
@@ -1,12 +1,12 @@
 /*
  * Copyright 2006-2008 The FLWOR Foundation.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,488 +20,361 @@
 
 #include "file_function.h"
 
-namespace zorba { 
-  
-  class ItemFactory;
-
-  namespace filemodule {
-
-//*****************************************************************************
-
-  class BaseNameFunction : public FileFunction
-  {
-    public:
-      BaseNameFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "base-name"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class CreateDirectoryFunction : public FileFunction
-  {
-    public:
-      CreateDirectoryFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "create-directory"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class DeleteFileImplFunction : public FileFunction
-  {
-    public:
-      DeleteFileImplFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "delete-file-impl"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class DirNameFunction : public FileFunction
-  {
-    public:
-      DirNameFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "dir-name"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class CopyFileImplFunction : public FileFunction
-  {
-    public:
-      CopyFileImplFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "copy-file-impl"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ExistsFunction : public FileFunction
-  {
-    public:
-      ExistsFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "exists"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ListFunction : public FileFunction
-  {
-    public:
-      ListFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "list"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-    private:
-      class IteratorBackedItemSequence : public ItemSequence , public Iterator{
-
-        public:
-          IteratorBackedItemSequence(
-              String const& path,
-              zorba::ItemFactory* aFactory);
-
-          virtual ~IteratorBackedItemSequence();
-
-          //ItemSequence interface
-          Iterator_t getIterator();
-
-          //Iterator interface
-          virtual void open();
-          virtual bool next(Item& aItem);
-          virtual void close();
-          virtual bool isOpen() const;
-        private:
-          bool is_open;
-          int  open_count;
-          fs::iterator theIterator;
-          ItemFactory* theItemFactory;
+namespace zorba {
+
+class ItemFactory;
+
+namespace filemodule {
+
+//*****************************************************************************
+
+class AppendTextFunction : public WriteTextFunctionImpl {
+public:
+  AppendTextFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+class AppendTextLinesFunction : public WriteTextFunctionImpl {
+public:
+  AppendTextLinesFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+class AppendBinaryFunction : public WriteBinaryFunctionImpl {
+public:
+  AppendBinaryFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+class BaseNameFunction : public FileFunction {
+public:
+  BaseNameFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class CopyFileImplFunction : public FileFunction {
+public:
+  CopyFileImplFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class CreateDirectoryFunction : public FileFunction {
+public:
+  CreateDirectoryFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class DeleteFileImplFunction : public FileFunction {
+public:
+  DeleteFileImplFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class DirectorySeparator : public FileFunction {
+public:
+  DirectorySeparator( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class DirNameFunction : public FileFunction {
+public:
+  DirNameFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class ExistsFunction : public FileFunction {
+public:
+  ExistsFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class ListFunction : public FileFunction {
+public:
+  ListFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+private:
+  class IteratorBackedItemSequence : public ItemSequence, public Iterator {
+  public:
+    IteratorBackedItemSequence( String const &path, zorba::ItemFactory* );
+
+    //ItemSequence interface
+    Iterator_t getIterator();
+
+    //Iterator interface
+    virtual void open();
+    virtual bool next(Item& aItem);
+    virtual void close();
+    virtual bool isOpen() const;
+
+  private:
+    bool is_open;
+    int  open_count;
+    fs::iterator theIterator;
+    ItemFactory *theItemFactory;
+  };
+};
+
+//*****************************************************************************
+
+class IsDirectoryFunction : public FileFunction {
+public:
+  IsDirectoryFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class IsFileFunction : public FileFunction {
+public:
+  IsFileFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class IsSymlinkFunction : public FileFunction {
+public:
+  IsSymlinkFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class LastModifiedFunction : public FileFunction {
+public:
+  LastModifiedFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+
+private:
+  static int getGmtOffset();
+};
+
+//*****************************************************************************
+
+class ResolvePathFunction : public FileFunction {
+public:
+  ResolvePathFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class PathSeparator : public FileFunction {
+public:
+  PathSeparator( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class PathToNativeFunction : public FileFunction {
+public:
+  PathToNativeFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class PathToUriFunction : public FileFunction {
+public:
+  PathToUriFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class ReadBinaryFunction : public FileFunction {
+public:
+  ReadBinaryFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class ReadTextFunction : public FileFunction {
+public:
+  ReadTextFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+};
+
+//*****************************************************************************
+
+class ReadTextLinesFunction : public FileFunction {
+public:
+  ReadTextLinesFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+
+protected:
+  class LinesItemSequence : public ItemSequence {
+  protected:
+    String            theFile;
+    String            theEncoding;
+    const ReadTextLinesFunction* theFunc;
+
+    class LinesIterator : public Iterator {
+    protected:
+      const String&     theFile;
+      const String&     theEncoding;
+      const ReadTextLinesFunction* theFunc;
+
+      std::ifstream* theStream;
+
+    public:
+      LinesIterator(
+          const String&,
+          const String&,
+          const ReadTextLinesFunction*);
+
+      virtual ~LinesIterator();
+
+      virtual void open();
+      virtual bool next(Item&);
+      virtual void close();
+      virtual bool isOpen() const;
     };
-  };
-
-//*****************************************************************************
-
-  class IsDirectoryFunction : public FileFunction
-  {
-    public:
-      IsDirectoryFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "is-directory"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class IsFileFunction : public FileFunction
-  {
-    public:
-      IsFileFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "is-file"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class IsSymlinkFunction : public FileFunction
-  {
-    public:
-      IsSymlinkFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "is-symlink"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class LastModifiedFunction : public FileFunction
-  {
-    public:
-      LastModifiedFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "last-modified"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-
-  private:
-      static int
-      getGmtOffset();
-
-  };
-
-//*****************************************************************************
-
-  class SizeFunction : public FileFunction
-  {
-    public:
-      SizeFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "size"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-
-  private:
-      static int
-      getGmtOffset();
-
-  };
-
-//*****************************************************************************
-
-  class PathSeparator : public FileFunction
-  {
-    public:
-      PathSeparator(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "path-separator"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class DirectorySeparator : public FileFunction
-  {
-    public:
-      DirectorySeparator(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "directory-separator"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ResolvePathFunction : public FileFunction
-  {
-    public:
-      ResolvePathFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "resolve-path"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class PathToUriFunction : public FileFunction
-  {
-    public:
-      PathToUriFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "path-to-uri"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class PathToNativeFunction : public FileFunction
-  {
-    public:
-      PathToNativeFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "path-to-native"; }
-
-      virtual ItemSequence_t
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aStctxCtx,
-               const DynamicContext* aDznCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ReadBinaryFunction : public FileFunction
-  {
-    public:
-      ReadBinaryFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "read-binary"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ReadTextFunction : public StreamableFileFunction
-  {
-    public:
-      ReadTextFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "read-text"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-  };
-
-//*****************************************************************************
-
-  class ReadTextLinesFunction : public FileFunction
-  {
-    public:
-      ReadTextLinesFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "read-text-lines"; }
-  
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-
-    protected:
-      class LinesItemSequence : public ItemSequence
-      {
-        protected:
-          String            theFile;
-          String            theEncoding;
-          const ReadTextLinesFunction* theFunc;
-
-          class LinesIterator : public Iterator
-          {
-            protected:
-              const String&     theFile;
-              const String&     theEncoding;
-              const ReadTextLinesFunction* theFunc;
-
-              std::ifstream* theStream;
-
-            public:
-              LinesIterator(
-                  const String&,
-                  const String&,
-                  const ReadTextLinesFunction*);
-
-              virtual ~LinesIterator();
-
-              virtual void
-              open();
-
-              virtual bool
-              next(Item&);
-
-              virtual void
-              close();
-
-              virtual bool
-              isOpen() const;
-          };
-
-        public:
-          LinesItemSequence(
-              const String& aFile,
-              const String& aEncoding,
-              const ReadTextLinesFunction*);
-
-          Iterator_t
-          getIterator();
-      };
-  };
-
-//*****************************************************************************
-
-  class WriteTextFunction : public WriterFileFunction
-  {
-    public:
-      WriteTextFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "write-text"; }
-  
-    protected:
-      virtual bool
-      isAppend() const;
-
-      virtual bool
-      isBinary() const;
-  };
-
-//*****************************************************************************
-
-  class WriteBinaryFunction : public WriterFileFunction
-  {
-    public:
-      WriteBinaryFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "write-binary"; }
-  
-    protected:
-      virtual bool
-      isAppend() const;
-
-      virtual bool
-      isBinary() const;
-  };
-
-//*****************************************************************************
-
-  class AppendTextFunction : public WriterFileFunction
-  {
-    public:
-      AppendTextFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "append-text"; }
-  
-    protected:
-      virtual bool
-      isAppend() const;
-
-      virtual bool
-      isBinary() const;
-  };
-
-//*****************************************************************************
-
-  class AppendBinaryFunction : public WriterFileFunction
-  {
-    public:
-      AppendBinaryFunction(const FileModule* aModule);
-
-      virtual String
-      getLocalName() const { return "append-binary"; }
-  
-    protected:
-      virtual bool
-      isAppend() const;
-
-      virtual bool
-      isBinary() const;
-  };
-
-//*****************************************************************************
-
-} /* namespace filemodule */ } /* namespace zorba */
-
+
+  public:
+    LinesItemSequence(
+        const String& aFile,
+        const String& aEncoding,
+        const ReadTextLinesFunction*);
+
+    Iterator_t getIterator();
+  };
+};
+
+//*****************************************************************************
+
+class SizeFunction : public FileFunction {
+public:
+  SizeFunction( FileModule const* );
+
+  virtual ItemSequence_t
+  evaluate( ExternalFunction::Arguments_t const&,
+            StaticContext const*,
+            DynamicContext const* ) const;
+
+private:
+  static int getGmtOffset();
+};
+
+//*****************************************************************************
+
+class WriteTextFunction : public WriteTextFunctionImpl {
+public:
+  WriteTextFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+class WriteTextLinesFunction : public WriteTextFunctionImpl {
+public:
+  WriteTextLinesFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+class WriteBinaryFunction : public WriteBinaryFunctionImpl {
+public:
+  WriteBinaryFunction( FileModule const* );
+};
+
+//*****************************************************************************
+
+} // namespace filemodule
+} // namespace zorba
 #endif /* ZORBA_FILEMODULE_FILE_H */
+/* vim:set et sw=2 ts=2: */

=== modified file 'modules/org/expath/ns/file.xq.src/file_function.cpp'
--- modules/org/expath/ns/file.xq.src/file_function.cpp	2013-06-12 23:54:27 +0000
+++ modules/org/expath/ns/file.xq.src/file_function.cpp	2013-08-05 22:16:26 +0000
@@ -14,280 +14,228 @@
  * limitations under the License.
  */
 
-#include "file_function.h"
-
+// standard
+#include <cstdio>
+#include <cstdlib>
 #include <sstream>
+#ifdef WIN32
+#include <windows.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif /* WIN32 */
 
+// Zorba
+#include <zorba/diagnostic_list.h>
 #include <zorba/empty_sequence.h>
-#include <zorba/diagnostic_list.h>
 #include <zorba/serializer.h>
+#include <zorba/singleton_item_sequence.h>
 #include <zorba/store_consts.h>
 #include <zorba/user_exception.h>
+#include <zorba/util/base64_util.h>
 #include <zorba/util/fs_util.h>
+#include <zorba/util/transcode_stream.h>
 #include <zorba/xquery_functions.h>
-#include <zorba/singleton_item_sequence.h>
 #include <zorba/zorba.h>
 
+// local
+#include "file_function.h"
 #include "file_module.h"
 
-#include <cassert>
-
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef WIN32
-#include <Windows.h>
-#include <direct.h>
-#else
-#include <unistd.h>
-#endif
-
-namespace zorba { namespace filemodule {
-
-FileFunction::FileFunction(const FileModule* aModule)
-  : theModule(aModule)
-{
-}
-
-FileFunction::~FileFunction()
-{
-}
-
-int
-FileFunction::raiseFileError(
-  char const *aQName,
-  char const *aMessage,
-  String const &aPath ) const
-{
+using namespace std;
+
+namespace zorba {
+namespace filemodule {
+
+///////////////////////////////////////////////////////////////////////////////
+
+FileFunction::FileFunction( FileModule const *m, char const *local_name ) :
+  module_( m ),
+  local_name_( local_name )
+{
+}
+
+String FileFunction::getLocalName() const {
+  return local_name_;
+}
+
+int FileFunction::raiseFileError( char const *aQName, char const *aMessage,
+                                  String const &aPath ) const {
   Item const lQName(
-    theModule->getItemFactory()->createQName( getURI(), "file", aQName )
+    module_->getItemFactory()->createQName( getURI(), "file", aQName )
   );
-  std::ostringstream lErrorMessage;
+  ostringstream lErrorMessage;
   lErrorMessage << '"' << aPath << "\": " << aMessage;
   throw USER_EXCEPTION( lQName, lErrorMessage.str() );
 }
 
-String
-FileFunction::getURI() const
-{
-  return theModule->getURI();
+String FileFunction::getURI() const {
+  return module_->getURI();
 }
 
-String
-FileFunction::getEncodingArg(
-  const ExternalFunction::Arguments_t& aArgs,
-  unsigned int aPos) const
-{
-  String encoding( getStringArg( aArgs, aPos ) );
+String FileFunction::getEncodingArg( ExternalFunction::Arguments_t const &args,
+                                     unsigned pos ) const {
+  String encoding( getStringArg( args, pos ) );
   if ( encoding.empty() )
     encoding = "UTF-8";                 // the default file encoding
   return encoding;
 }
 
-String
-FileFunction::getPathArg(
-  const ExternalFunction::Arguments_t& aArgs,
-  unsigned int aPos) const
-{
-  String const path( getStringArg( aArgs, aPos ) );
+String FileFunction::getPathArg( ExternalFunction::Arguments_t const &args,
+                                 unsigned pos ) const {
+  String const path( getStringArg( args, pos ) );
   if ( path.empty() )
     return path;
   try {
     return fs::normalize_path( path, fs::curdir() );
   }
-  catch ( std::invalid_argument const &e ) {
+  catch ( invalid_argument const &e ) {
     throw raiseFileError( "FOFL9999", e.what(), path );
   }
 }
 
-String
-FileFunction::getStringArg(
-  const ExternalFunction::Arguments_t& aArgs,
-  unsigned int aPos) const
-{
-  String str;
-  if ( aPos < aArgs.size() ) {
-    Iterator_t i( aArgs[ aPos ]->getIterator() );
-    i->open();
+String FileFunction::getStringArg( ExternalFunction::Arguments_t const &args,
+                                   unsigned pos ) const {
+  String s;
+  if ( pos < args.size() ) {
+    Iterator_t it( args[ pos ]->getIterator() );
+    it->open();
     Item item;
-    if ( i->next( item ) )
-      str = item.getStringValue();
-    i->close();
-  }
-  return str;
-}
-
-String
-FileFunction::pathToFullOSPath(const String& aPath) const {
-  try {
-    return fs::normalize_path( aPath );
-  }
-  catch ( std::invalid_argument const &e ) {
-    throw raiseFileError( "FOFL9999", e.what(), aPath );
-  }
-}
-
-String
-FileFunction::pathToOSPath(const String& aPath) const {
-  try {
-    return fs::normalize_path( aPath );
-  }
-  catch ( std::invalid_argument const &e ) {
-    throw raiseFileError( "FOFL9999", e.what(), aPath );
-  }
-}
-
-String
-FileFunction::pathToUriString(const String& aPath) const {
-
+    if ( it->next( item ) )
+      s = item.getStringValue();
+    it->close();
+  }
+  return s;
+}
+
+String FileFunction::pathToUriString(const String& aPath) const {
   if ( fn::starts_with( aPath,"file://" ) ) {
-    std::stringstream lErrorMessage;
-    lErrorMessage << "Please provide a path, not a URI";
-    Item lQName = theModule->getItemFactory()->createQName(
-        "http://www.w3.org/2005/xqt-errors";,
-        "err",
-        "XPTY0004");
-    throw USER_EXCEPTION( lQName, lErrorMessage.str() );
+    stringstream msg;
+    msg << '"' << aPath << "\": path must not be a URI";
+    Item const lQName(
+      module_->getItemFactory()->createQName(
+        "http://www.w3.org/2005/xqt-errors";, "err", "XPTY0004"
+      )
+    );
+    throw USER_EXCEPTION( lQName, msg.str() );
   }
-
-  String uri( aPath );
-
+  String const uri( aPath );
   return uri;
 }
 
-#ifdef WIN32
-bool
-FileFunction::isValidDriveSegment(
-    String& aString)
-{
-  aString = fn::upper_case( aString );
-  // the drive segment has one of the forms: "C:", "C%3A"
-  if ((aString.length() != 2 && aString.length() != 4) ||
-      (aString.length() == 2 && !fn::ends_with(aString,":")) ||
-      (aString.length() == 4 && !fn::ends_with(aString,"%3A"))) {
-    return false;
-  }
-
-  char const lDrive = aString[0];
-  // the string is already upper case
-  return lDrive >= 'A' && lDrive <= 'Z';
-}
-#endif
-
-//*****************************************************************************
-
-StreamableFileFunction::StreamableFileFunction(const FileModule* aModule)
-  : FileFunction(aModule)
-{
-}
-
-StreamableFileFunction::~StreamableFileFunction()
-{
-}
-
-bool
-StreamableFileFunction::StreamableItemSequence::InternalIterator::next(Item& aResult)
-{
-  assert(theIsOpen);
-
-  if (theHasNext) {
-    aResult = theItemSequence->theItem;
-    theHasNext = false;
-    return !aResult.isNull();
-  }
-  return false;
-}
-
-//*****************************************************************************
-
-WriterFileFunction::WriterFileFunction(const FileModule* aModule)
-  : FileFunction(aModule)
-{
-}
-
-WriterFileFunction::~WriterFileFunction()
-{
-}
-
-ItemSequence_t
-WriterFileFunction::evaluate(
-  const ExternalFunction::Arguments_t& aArgs,
-  const StaticContext*,
-  const DynamicContext* ) const
-{
-  String const lFileStr( getPathArg(aArgs, 0) );
-
-  fs::type const fs_type = fs::get_type( lFileStr );
-  if ( fs_type && fs_type != fs::file )
-    raiseFileError( "FOFL0004", "not a plain file", lFileStr );
-
-  bool const lBinary = isBinary();
-
-  std::ios_base::openmode mode = std::ios_base::out
-    | (isAppend() ? std::ios_base::app : std::ios_base::trunc);
-  if ( lBinary )
-    mode |= std::ios_base::binary;
-
-  std::ofstream lOutStream( lFileStr.c_str(), mode );
-  if ( !lOutStream ) {
-    std::ostringstream oss;
-    oss << '"' << lFileStr << "\": can not open file for writing";
-    raiseFileError( "FOFL9999", oss.str().c_str(), lFileStr );
-  }
-
-  // if this is a binary write
-  if (lBinary)
-  {
-    Item lBinaryItem;
-    Iterator_t lContentSeq = aArgs[1]->getIterator();
-    lContentSeq->open();
-    while (lContentSeq->next(lBinaryItem))
-    {
-      if (lBinaryItem.isStreamable() && !lBinaryItem.isEncoded())
-      {
-        lOutStream << lBinaryItem.getStream().rdbuf();
-      }
-      else
-      {
-        Zorba_SerializerOptions lOptions;
-        lOptions.ser_method = ZORBA_SERIALIZATION_METHOD_BINARY;
-        Serializer_t lSerializer = Serializer::createSerializer(lOptions);
-        SingletonItemSequence lSeq(lBinaryItem);
-        lSerializer->serialize(&lSeq, lOutStream);
-      }
-
-    }
-  }
-  // if we only write text
-  else
-  {
-    Item lStringItem;
-    Iterator_t lContentSeq = aArgs[1]->getIterator();
-    lContentSeq->open();
-    // for each item (string or base64Binary) in the content sequence
-    while (lContentSeq->next(lStringItem)) {
-      // if the item is streamable make use of the stream
-      if (lStringItem.isStreamable()) {
-        std::istream& lInStream = lStringItem.getStream();
-        char lBuf[1024];
-        while (!lInStream.eof()) {
-          lInStream.read(lBuf, 1024);
-          lOutStream.write(lBuf, lInStream.gcount());
-        }
-      }
-      // else write the string value
-      else {
-        zorba::String lString = lStringItem.getStringValue();
-        lOutStream.write(lString.data(), lString.size());
-      }
-    }
-    lContentSeq->close();
-  }
-
-  // close the file stream
-  lOutStream.close();
-
-  return ItemSequence_t(new EmptySequence());
-}
+///////////////////////////////////////////////////////////////////////////////
+
+WriteBinaryFunctionImpl::WriteBinaryFunctionImpl( FileModule const *m,
+                                                  char const *local_name,
+                                                  bool append ) :
+  FileFunction( m, local_name ),
+  append_( append )
+{
+}
+
+ItemSequence_t WriteBinaryFunctionImpl::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+
+  fs::type const fs_type = fs::get_type( path );
+  if ( fs_type && fs_type != fs::file )
+    raiseFileError( "FOFL0004", "not a plain file", path );
+
+  ios_base::openmode const mode = ios_base::out | ios_base::binary
+    | (append_ ? ios_base::app : ios_base::trunc);
+
+  ofstream ofs( path.c_str(), mode );
+  if ( !ofs ) {
+    ostringstream oss;
+    oss << '"' << path << "\": can not open file for writing";
+    raiseFileError( "FOFL9999", oss.str().c_str(), path );
+  }
+
+  Iterator_t it( args[1]->getIterator() );
+  it->open();
+  Item item;
+  while ( it->next( item ) ) {
+    if ( item.isStreamable() ) {
+      if ( item.isEncoded() )
+        base64::decode( item.getStream(), ofs );
+      else
+        ofs << item.getStream().rdbuf();
+    } else {
+      size_t b64_size;
+      char const *const b64_value = item.getBase64BinaryValue( b64_size );
+      if ( item.isEncoded() )
+        base64::decode( b64_value, b64_size, ofs );
+      else
+        ofs.write( b64_value, b64_size );
+    }
+  }
+  it->close();
+
+  return ItemSequence_t( new EmptySequence() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+WriteTextFunctionImpl::WriteTextFunctionImpl( FileModule const *m,
+                                              char const *local_name,
+                                              bool append, bool newlines ) :
+  FileFunction( m, local_name ),
+  append_( append ),
+  newlines_( newlines )
+{
+}
+
+ItemSequence_t WriteTextFunctionImpl::evaluate(
+  ExternalFunction::Arguments_t const &args,
+  StaticContext const*,
+  DynamicContext const* ) const
+{
+  String const path( getPathArg( args, 0 ) );
+  String const encoding( getStringArg( args, 2 ) );
+
+  fs::type const fs_type = fs::get_type( path );
+  if ( fs_type && fs_type != fs::file )
+    raiseFileError( "FOFL0004", "not a plain file", path );
+
+  if ( !transcode::is_supported( encoding.c_str() ) )
+    raiseFileError( "FOFL9999", "encoding not supported", encoding );
+
+  ios_base::openmode const mode = ios_base::out
+    | (append_ ? ios_base::app : ios_base::trunc);
+
+  ofstream ofs( path.c_str(), mode );
+  if ( !ofs ) {
+    ostringstream oss;
+    oss << '"' << path << "\": can not open file for writing";
+    raiseFileError( "FOFL9999", oss.str().c_str(), path );
+  }
+
+  transcode::auto_attach<ofstream> transcoder;
+  if ( transcode::is_necessary( encoding.c_str() ) )
+    transcoder.attach( ofs, encoding.c_str() );
+
+  Iterator_t it( args[1]->getIterator() );
+  it->open();
+  Item item;
+  while ( it->next( item ) ) {
+    if ( item.isStreamable() ) {
+      ofs << item.getStream().rdbuf();
+    } else {
+      zorba::String const s( item.getStringValue() );
+      ofs.write( s.data(), s.size() );
+    }
+    if ( newlines_ )
+      ofs << fs::newline;
+  }
+  it->close();
+
+  return ItemSequence_t( new EmptySequence() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 } // namespace filemodule
 } // namespace zorba

=== modified file 'modules/org/expath/ns/file.xq.src/file_function.h'
--- modules/org/expath/ns/file.xq.src/file_function.h	2013-06-12 23:54:27 +0000
+++ modules/org/expath/ns/file.xq.src/file_function.h	2013-08-05 22:16:26 +0000
@@ -17,162 +17,87 @@
 #ifndef ZORBA_FILEMODULE_FILEFUNCTION_H
 #define ZORBA_FILEMODULE_FILEFUNCTION_H
 
+// standard
+#include <fstream>
+
+// Zorba
 #include <zorba/error.h>
 #include <zorba/function.h>
 #include <zorba/item.h>
 #include <zorba/iterator.h>
 #include <zorba/options.h>
 
-#include <fstream>
-
 namespace zorba {
-
-  namespace filemodule {
-
-  class FileModule;
-
-  class FileFunction : public ContextualExternalFunction
-  {
-    private:
-
-#ifdef WIN32
-      static bool
-      isValidDriveSegment(
-          String& value);
-#endif
-
-    protected:
-      const FileModule* theModule;
-
-      int
-      raiseFileError(
-          char const *qName,
-          char const *message,
-          const String& path) const;
-
-      /*
-       * Gets the argument on position pos as a normalised file system path.
-       * pos must point to a file function argument. No checks are made.
-       */
-      String
-      getPathArg(
-        const ExternalFunction::Arguments_t& args,
-        unsigned int pos) const;
-
-      String
-      getEncodingArg(
-        const ExternalFunction::Arguments_t& args,
-        unsigned int pos) const;
-
-      String
-      getStringArg(
-        const ExternalFunction::Arguments_t& args,
-        unsigned int pos) const;
-
-      String
-      pathToFullOSPath(const String& path) const;
-
-      String
-      pathToOSPath(const String& path) const;
-
-      String
-      pathToUriString(const String& path) const;
-
-    public:
-      FileFunction(const FileModule* module);
-      ~FileFunction();
-
-      virtual String
-      getURI() const;
-
-  };
-
-  class StreamableFileFunction : public FileFunction
-  {
-    public:
-
-      StreamableFileFunction(const FileModule* module);
-
-      ~StreamableFileFunction();
-
-    protected:
-
-      class StreamableItemSequence : public ItemSequence {
-
-      public:
-        class InternalIterator : public Iterator
-        {
-          private:
-            StreamableItemSequence *theItemSequence;
-            bool theIsOpen;
-            bool theHasNext;
-
-          public:
-            InternalIterator(StreamableItemSequence* aItemSequence)
-              : theItemSequence(aItemSequence),
-                theIsOpen(false),
-                theHasNext(true)
-            { }
-
-            virtual void
-            open()
-            {
-              theIsOpen = true;
-              theHasNext = true;
-            }
-
-            virtual void
-            close()
-            {
-              theIsOpen = false;
-            }
-
-            virtual bool
-            isOpen() const
-            {
-              return theIsOpen;
-            }
-
-            bool
-            next(Item& aResult);
-        };
-
-        Item                 theItem;
-        std::ifstream*       theStream;
-
-        StreamableItemSequence() 
-          : theStream(new std::ifstream()) {}
-
-        Iterator_t  getIterator()
-        {
-          return new InternalIterator(this);
-        }
-      };
-  };
-
-  class WriterFileFunction : public FileFunction
-  {
-    public:
-
-      WriterFileFunction(const FileModule* module);
-
-      ~WriterFileFunction();
-
-      virtual ItemSequence_t 
-      evaluate(const ExternalFunction::Arguments_t& args,
-               const StaticContext* aSctxCtx,
-               const DynamicContext* aDynCtx) const;
-
-    protected:
-
-      virtual bool
-      isAppend() const = 0;
-
-      virtual bool
-      isBinary() const = 0;
-  };
-
-} /* namespace filemodule */
-} /* namespace zorba */
+namespace filemodule {
+
+class FileModule;
+
+///////////////////////////////////////////////////////////////////////////////
+
+class FileFunction : public ContextualExternalFunction {
+public:
+  virtual String getLocalName() const;
+  virtual String getURI() const;
+
+protected:
+  FileFunction( FileModule const *module, char const *local_name );
+
+  /**
+   * Gets the argument on position pos as a normalised file system path.
+   * pos must point to a file function argument. No checks are made.
+   */
+  String getPathArg( ExternalFunction::Arguments_t const&, unsigned pos ) const;
+
+  String getEncodingArg( ExternalFunction::Arguments_t const&,
+                         unsigned pos ) const;
+
+  String getStringArg( ExternalFunction::Arguments_t const&,
+                       unsigned pos ) const;
+
+  String pathToUriString(const String& path) const;
+
+  int raiseFileError( char const *qName, char const *message,
+                      String const &path ) const;
+
+  FileModule const *module_;
+  char const *const local_name_;        // points to string literal
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class WriteBinaryFunctionImpl : public FileFunction {
+public:
+  ItemSequence_t evaluate( ExternalFunction::Arguments_t const&,
+                           StaticContext const*,
+                           DynamicContext const* ) const;
+
+protected:
+  WriteBinaryFunctionImpl( FileModule const*, char const *local_name,
+                           bool append );
+
+  bool const append_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class WriteTextFunctionImpl : public FileFunction {
+public:
+  ItemSequence_t evaluate( ExternalFunction::Arguments_t const&,
+                           StaticContext const*,
+                           DynamicContext const* ) const;
+
+protected:
+  WriteTextFunctionImpl( FileModule const*, char const *local_name,
+                         bool append, bool newlines );
+
+  bool const append_;
+  bool const newlines_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace filemodule
+} // namespace zorba
 
 #endif /* ZORBA_FILEMODULE_FILEFUNCTION_H */
+/* vim:set et sw=2 ts=2: */

=== modified file 'modules/org/expath/ns/file.xq.src/file_module.cpp'
--- modules/org/expath/ns/file.xq.src/file_module.cpp	2013-06-12 15:35:27 +0000
+++ modules/org/expath/ns/file.xq.src/file_module.cpp	2013-08-05 22:16:26 +0000
@@ -1,12 +1,12 @@
 /*
  * Copyright 2006-2008 The FLWOR Foundation.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,87 +17,87 @@
 #include "file.h"
 #include "file_module.h"
 #include "file_function.h"
-#include <cassert>
-
-namespace zorba { namespace filemodule {
-
-  const char* FileModule::theNamespace = "http://expath.org/ns/file";;
-
-
-FileModule::~FileModule()
-{
-  for (FuncMap_t::const_iterator lIter = theFunctions.begin();
-       lIter != theFunctions.end(); ++lIter) {
-    delete lIter->second;
+
+namespace zorba {
+namespace filemodule {
+
+///////////////////////////////////////////////////////////////////////////////
+
+FileModule::~FileModule() {
+  for ( FuncMap_t::const_iterator i = theFunctions.begin();
+        i != theFunctions.end(); ++i ) {
+    delete i->second;
   }
-  theFunctions.clear();
 }
   
-ExternalFunction*
-FileModule::getExternalFunction(const String& aLocalname)
-{
-  ExternalFunction*& lFunc = theFunctions[aLocalname];
-  if (!lFunc) {
-    if (aLocalname == "base-name") {
-      lFunc = new BaseNameFunction(this);
-    } else if (aLocalname == "copy-file-impl") {
-      lFunc = new CopyFileImplFunction(this);
-    } else if (aLocalname == "create-directory") {
-      lFunc = new CreateDirectoryFunction(this);
-    } else if (aLocalname == "delete-file-impl") {
-      lFunc = new DeleteFileImplFunction(this);
-    } else if (aLocalname == "dir-name") {
-      lFunc = new DirNameFunction(this);
-    } else if (aLocalname == "exists") {
-      lFunc = new ExistsFunction(this);
-    } else if (aLocalname == "is-directory") {
-      lFunc = new IsDirectoryFunction(this);
-    } else if (aLocalname == "is-file") {
-      lFunc = new IsFileFunction(this);
-    } else if (aLocalname == "read-binary") {
-      lFunc = new ReadBinaryFunction(this);
-    } else if (aLocalname == "read-text") {
-      lFunc = new ReadTextFunction(this);
-    } else if (aLocalname == "read-text-lines") {
-      lFunc = new ReadTextLinesFunction(this);
-    } else if (aLocalname == "is-symlink") {
-      lFunc = new IsSymlinkFunction(this);
-    } else if (aLocalname == "write-text") {
-      lFunc = new WriteTextFunction(this);
-    } else if (aLocalname == "write-binary") {
-      lFunc = new WriteBinaryFunction(this);
-    } else if (aLocalname == "append-text") {
-      lFunc = new AppendTextFunction(this);
-    } else if (aLocalname == "append-binary") {
-      lFunc = new AppendBinaryFunction(this);
-    } else if (aLocalname == "list") {
-      lFunc = new ListFunction(this);
-    } else if (aLocalname == "last-modified") {
-      lFunc = new LastModifiedFunction(this);
-    } else if (aLocalname == "size") {
-      lFunc = new SizeFunction(this);
-    } else if (aLocalname == "directory-separator") {
-      lFunc = new DirectorySeparator(this);
-    } else if (aLocalname == "path-separator") {
-      lFunc = new PathSeparator(this);
-    } else if (aLocalname == "resolve-path") {
-      lFunc = new ResolvePathFunction(this);
-    } else if (aLocalname == "path-to-uri") {
-      lFunc = new PathToUriFunction(this);
-    } else if (aLocalname == "path-to-native") {
-      lFunc = new PathToNativeFunction(this);
-    }
+ExternalFunction* FileModule::getExternalFunction( String const &aLocalname ) {
+  ExternalFunction *&lFunc = theFunctions[ aLocalname ];
+  if ( !lFunc ) {
+    if ( aLocalname == "append-text" )
+      lFunc = new AppendTextFunction( this );
+    else if ( aLocalname == "append-text-lines" )
+      lFunc = new AppendTextLinesFunction( this );
+    else if ( aLocalname == "append-binary" )
+      lFunc = new AppendBinaryFunction( this );
+    else if ( aLocalname == "base-name" )
+      lFunc = new BaseNameFunction( this );
+    else if ( aLocalname == "copy-file-impl" )
+      lFunc = new CopyFileImplFunction( this );
+    else if ( aLocalname == "create-directory" )
+      lFunc = new CreateDirectoryFunction( this );
+    else if ( aLocalname == "delete-file-impl" )
+      lFunc = new DeleteFileImplFunction( this );
+    else if ( aLocalname == "dir-name" )
+      lFunc = new DirNameFunction( this );
+    else if ( aLocalname == "directory-separator" )
+      lFunc = new DirectorySeparator( this );
+    else if ( aLocalname == "exists" )
+      lFunc = new ExistsFunction( this );
+    else if ( aLocalname == "is-directory" )
+      lFunc = new IsDirectoryFunction( this );
+    else if ( aLocalname == "is-file" )
+      lFunc = new IsFileFunction( this );
+    else if ( aLocalname == "is-symlink" )
+      lFunc = new IsSymlinkFunction( this );
+    else if ( aLocalname == "last-modified" )
+      lFunc = new LastModifiedFunction( this );
+    else if ( aLocalname == "list" )
+      lFunc = new ListFunction( this );
+    else if ( aLocalname == "path-separator" )
+      lFunc = new PathSeparator( this );
+    else if ( aLocalname == "path-to-native" )
+      lFunc = new PathToNativeFunction( this );
+    else if ( aLocalname == "path-to-uri" )
+      lFunc = new PathToUriFunction( this );
+    else if ( aLocalname == "read-binary" )
+      lFunc = new ReadBinaryFunction( this );
+    else if ( aLocalname == "read-text" )
+      lFunc = new ReadTextFunction( this );
+    else if ( aLocalname == "read-text-lines" )
+      lFunc = new ReadTextLinesFunction( this );
+    else if ( aLocalname == "resolve-path" )
+      lFunc = new ResolvePathFunction( this );
+    else if ( aLocalname == "write-text" )
+      lFunc = new WriteTextFunction( this );
+    else if ( aLocalname == "write-text-lines" )
+      lFunc = new WriteTextLinesFunction( this );
+    else if ( aLocalname == "write-binary" )
+      lFunc = new WriteBinaryFunction( this );
+    else if ( aLocalname == "size" )
+      lFunc = new SizeFunction( this );
   }
   return lFunc;
 }
 
-void
-FileModule::destroy()
-{
-  if (dynamic_cast<FileModule*>(this)) {
-    delete this;
-  }
-}
+void FileModule::destroy() {
+  delete this;
+}
+
+String FileModule::getURI() const {
+  return "http://expath.org/ns/file";;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 } // namespace filemodule
 } // namespace zorba

=== modified file 'modules/org/expath/ns/file.xq.src/file_module.h'
--- modules/org/expath/ns/file.xq.src/file_module.h	2013-02-07 17:24:36 +0000
+++ modules/org/expath/ns/file.xq.src/file_module.h	2013-08-05 22:16:26 +0000
@@ -1,12 +1,12 @@
 /*
  * Copyright 2006-2008 The FLWOR Foundation.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,67 +22,44 @@
 #include <zorba/zorba.h>
 #include <zorba/external_module.h>
 
-namespace zorba { namespace filemodule {
-
-class FileModule : public ExternalModule
-{
-private:
-  mutable ItemFactory* theFactory;
-
-public:
-  static const char* theNamespace;
-
-protected:
-  class ltstr
-  {
-  public:
-    bool operator()(const String& s1, const String& s2) const
-    {
-      return s1.compare(s2) < 0;
-    }
-  };
-  
-  typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;
-  FuncMap_t theFunctions;
-
-public:
-  static void
-  streamReleaser(std::istream* stream)
-  {
+namespace zorba {
+namespace filemodule {
+
+///////////////////////////////////////////////////////////////////////////////
+
+class FileModule : public ExternalModule {
+public:
+  static void streamReleaser( std::istream *stream ) {
     delete stream;
   }
 
-  FileModule() : theFactory(0) {}
-
+  FileModule() : theFactory(0) { }
   virtual ~FileModule();
-  
-  virtual String
-  getURI() const { return theNamespace; }
-  
-  virtual ExternalFunction*
-  getExternalFunction(const String& aLocalname);
-
-  virtual void
-  destroy();
-
-  ItemFactory*
-  getItemFactory() const
-  {
-    if (!theFactory)
-    {
+
+  virtual void destroy();
+  virtual ExternalFunction* getExternalFunction( String const &aLocalname );
+  virtual String getURI() const;
+
+  ItemFactory* getItemFactory() const {
+    if ( !theFactory )
       theFactory = Zorba::getInstance(0)->getItemFactory();
-    }
-    
     return theFactory;
   }
+
+protected:
+  typedef std::map<String,ExternalFunction*> FuncMap_t;
+  FuncMap_t theFunctions;
+
+private:
+  mutable ItemFactory *theFactory;
 };
 
+///////////////////////////////////////////////////////////////////////////////
 
-} /* namespace filemodule */ 
-} /* namespace zorba */
+} // namespace filemodule
+} // namespace zorba
 
 #endif /* ZORBA_FILEMODULE_FILEMODULE_H */
-
 /*
  * Local variables:
  * mode: c++

=== modified file 'scripts/notice-generator.xq.in'
--- scripts/notice-generator.xq.in	2013-02-07 17:24:36 +0000
+++ scripts/notice-generator.xq.in	2013-08-05 22:16:26 +0000
@@ -171,12 +171,8 @@
     ()
   else
     let $contents := local:contents($notice)
-    return file:write (
-      fn:concat($relpath-from-this, "/NOTICE.txt"), $contents,
-      <output:serialization-parameters
-             xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization";>
-        <output:method value="text"/>
-      </output:serialization-parameters>
+    return file:write-text(
+      fn:concat($relpath-from-this, "/NOTICE.txt"), $contents
     )
 };
 

=== modified file 'src/util/fs_util.cpp'
--- src/util/fs_util.cpp	2013-06-17 22:19:13 +0000
+++ src/util/fs_util.cpp	2013-08-05 22:16:26 +0000
@@ -44,14 +44,21 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-char const *const type_string[] = {
-  "non_existant",
-  "directory",
-  "file",
-  "link",
-  "volume",
-  "other"
-};
+ostream& operator<<( ostream &o, type t ) {
+  static char const *const string_of[] = {
+    "non_existant",
+    "directory",
+    "file",
+    "link",
+    "volume",
+    "other"
+  };
+  if ( t >= 0 && t <= other )
+    o << string_of[ t ];
+  else
+    o << "<invalid fs::type " << (int)t << '>';
+  return o;
+}
 
 ////////// helper functions ///////////////////////////////////////////////////
 

=== modified file 'test/rbkt/Queries/zorba/file/common.xqlib'
--- test/rbkt/Queries/zorba/file/common.xqlib	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/file/common.xqlib	2013-08-05 22:16:26 +0000
@@ -37,8 +37,8 @@
   }
 };
 
-declare %ann:sequential function commons:testWriteXml($path as xs:string, $xml as item()) as xs:string* {
-  file:write($path, $xml, ());
+declare %ann:sequential function commons:testWriteXml($path as xs:string, $xml as node()) as xs:string* {
+  file:write-text($path, serialize($xml));
   "SUCCESS"
 };
 
@@ -66,13 +66,15 @@
 };
 
 declare %ann:sequential function commons:testWriteSerializeXml($path as xs:string, $xml as item()) as xs:string* {
-  file:write(
+  file:write-text(
     $path,
-    $xml,
-    <output:serialization-parameters>
-      <output:method value="xml"/>
-    </output:serialization-parameters>);
-
+    fn:serialize(
+      $xml,
+      <output:serialization-parameters>
+        <output:method value="xml"/>
+      </output:serialization-parameters>
+    )
+  );
   "SUCCESS";
 };
 
@@ -138,3 +140,4 @@
   else
     fn:false()    
 };
+(: vim:set syntax=xquery et sw=2 ts=2: :)

=== modified file 'test/rbkt/Queries/zorba/file/file_read_serialize.xq'
--- test/rbkt/Queries/zorba/file/file_read_serialize.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/file/file_read_serialize.xq	2013-08-05 22:16:26 +0000
@@ -11,8 +11,7 @@
 return replace value of node $price with xs:double($price) * 2;
 
 (: write the updated data to a new file :)
-file:write("new-prices.xml", $local:my-doc, ());
+file:write-text("new-prices.xml", $local:my-doc);
 
 (: return the new data as result of the program :)
 $local:my-doc
-


Follow ups