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

Proposed by Paul J. Lucas
Status: Merged
Approved by: Paul J. Lucas
Approved revision: 11571
Merged at revision: 11585
Proposed branch: lp:~zorba-coders/zorba/bug-942171
Merge into: lp:zorba
Diff against target: 4912 lines (+2013/-2107)
21 files modified
ChangeLog (+1/-0)
doc/zorba/xqdoc/src/xqdoc-html.xq (+2/-2)
include/zorba/util/base64_stream.h (+71/-9)
include/zorba/util/fs_util.h (+4/-4)
include/zorba/util/hexbinary_stream.h (+66/-5)
include/zorba/util/transcode_stream.h (+69/-7)
modules/com/zorba-xquery/www/modules/xqdoc/batch.xq (+11/-5)
modules/org/expath/ns/file.xq (+581/-562)
modules/org/expath/ns/file.xq.src/file.cpp (+448/-481)
modules/org/expath/ns/file.xq.src/file.h (+359/-486)
modules/org/expath/ns/file.xq.src/file_function.cpp (+182/-234)
modules/org/expath/ns/file.xq.src/file_function.h (+75/-150)
modules/org/expath/ns/file.xq.src/file_module.cpp (+77/-77)
modules/org/expath/ns/file.xq.src/file_module.h (+29/-52)
scripts/notice-generator.xq.in (+2/-6)
src/util/fs_util.cpp (+15/-8)
test/fots_driver/reporting.xq (+5/-5)
test/fots_driver/util.xq (+3/-3)
test/rbkt/Queries/zorba/file/common.xqlib (+11/-8)
test/rbkt/Queries/zorba/file/file_read_serialize.xq (+1/-2)
test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_02.xq (+1/-1)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug-942171
Reviewer Review Type Date Requested Status
Matthias Brantner Approve
Paul J. Lucas Approve
Review via email: mp+178637@code.launchpad.net

Commit message

Added arbitrary encoding support.
Added missing functions from spec.

To post a comment you must log in.
lp:~zorba-coders/zorba/bug-942171 updated
11569. By Paul J. Lucas

s/0/nullptr/

Revision history for this message
Paul J. Lucas (paul-lucas) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue starting for the following merge proposals:
https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Progress dashboard at http://jenkins.lambda.nu/view/ValidationQueue

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Stage "AddTestSuitesUbuntu" failed.

Check console output at http://jenkins.lambda.nu/job/AddTestSuitesUbuntu/165/console to view the results.

lp:~zorba-coders/zorba/bug-942171 updated
11570. By Paul J. Lucas

s/write/write-text/

11571. By Paul J. Lucas

s/write/write-text/

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue starting for the following merge proposals:
https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Progress dashboard at http://jenkins.lambda.nu/view/ValidationQueue

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Stage "TestZorbaUbuntu" failed.
6 tests failed (8404 total tests run).

Check test results at http://jenkins.lambda.nu/job/TestZorbaUbuntu/165/testReport/ to view the results.

lp:~zorba-coders/zorba/bug-942171 updated
11572. By Paul J. Lucas

Intermediate check-in.

11573. By Paul J. Lucas

Merge from trunk.

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Stage "TestZorbaUbuntu" failed.
13 tests failed (8404 total tests run).

Check test results at http://jenkins.lambda.nu/job/TestZorbaUbuntu/169/testReport/ to view the results.

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/bug-942171/+merge/178637

Stage "CommitZorba" failed.

Check console output at http://jenkins.lambda.nu/job/CommitZorba/95/console to view the results.

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Matthias Brantner (matthias-brantner) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue succeeded - proposal merged!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2013-08-02 14:56:12 +0000
3+++ ChangeLog 2013-08-06 14:19:26 +0000
4@@ -28,6 +28,7 @@
5 * Fixed bug #1189636 (transcoding hexBinary streambuf)
6 * Fixed bug in hoisting through try-catch expr
7 * Fixed bug #1162631 (format-integer 'w' format of negative numbers)
8+ * Fixed bug #942171 (file module to allow for arbitrary encodings)
9 * Fixed bug #1192285 (Have JSON token know number subtype)
10 * Fixed bug #1190261 (relative paths bug in file module)
11 * Fixed bug #1189798 (Update core module "errors")
12
13=== modified file 'doc/zorba/xqdoc/src/xqdoc-html.xq'
14--- doc/zorba/xqdoc/src/xqdoc-html.xq 2013-06-21 20:12:28 +0000
15+++ doc/zorba/xqdoc/src/xqdoc-html.xq 2013-08-06 14:19:26 +0000
16@@ -41,7 +41,7 @@
17 let $schema-doc := doc($base || $slash || trace($schema, "schema"))
18 let $target-uri := $schema-doc/xs:schema/@targetNamespace/string()
19 return {
20- file:write($xqdocBuildPath || $slash || "schemas" || $slash || replace(replace($target-uri, "http://", ""), "/", "_") || ".xsd" , $schema-doc, ())
21+ file:write-text($xqdocBuildPath || $slash || "schemas" || $slash || replace(replace($target-uri, "http://", ""), "/", "_") || ".xsd", $schema-doc)
22 };
23
24 file:create-directory($xqdocBuildPath || $slash || "examples");
25@@ -70,4 +70,4 @@
26 let $output-folder := $xqdocBuildPath
27 let $modules := xqdoc-html:modules($manifest)
28 return batch:build-xqdoc($output-folder, $static-folders, $template, $modules);
29-trace("","XQDoc generated successfully!");
30\ No newline at end of file
31+trace("","XQDoc generated successfully!");
32
33=== modified file 'include/zorba/util/base64_stream.h'
34--- include/zorba/util/base64_stream.h 2013-06-19 23:15:33 +0000
35+++ include/zorba/util/base64_stream.h 2013-08-06 14:19:26 +0000
36@@ -29,8 +29,8 @@
37 ///////////////////////////////////////////////////////////////////////////////
38
39 /**
40- * A %base64::streambuf is-a std::streambuf for encoding to and decoding from
41- * Base64 on-the-fly.
42+ * A %base64::streambuf is-a std::streambuf for decoding from and encoding to
43+ * Base64 on-the-fly while reading or writing, respectively.
44 *
45 * To use it, replace a stream's streambuf:
46 * \code
47@@ -149,9 +149,10 @@
48 * @param ios The stream to attach the base64::streambuf to. If the stream
49 * already has a base64::streambuf attached to it, this function does
50 * nothing.
51+ * @return \c true only if a base64::streambuf was attached.
52 */
53 template<typename charT,class Traits> inline
54-void attach( std::basic_ios<charT,Traits> &ios ) {
55+bool attach( std::basic_ios<charT,Traits> &ios ) {
56 int const index = internal::base64::get_streambuf_index();
57 void *&pword = ios.pword( index );
58 if ( !pword ) {
59@@ -160,7 +161,9 @@
60 ios.rdbuf( buf );
61 pword = buf;
62 ios.register_callback( internal::stream_callback, index );
63+ return true;
64 }
65+ return false;
66 }
67
68 /**
69@@ -170,15 +173,18 @@
70 * @param ios The stream to detach the base64::streambuf from. If the
71 * stream doesn't have a base64::streambuf attached to it, this function
72 * does nothing.
73+ * @return \c true only if a base64::streambuf was detached.
74 */
75 template<typename charT,class Traits> inline
76-void detach( std::basic_ios<charT,Traits> &ios ) {
77+bool detach( std::basic_ios<charT,Traits> &ios ) {
78 int const index = internal::base64::get_streambuf_index();
79 if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
80 ios.pword( index ) = nullptr;
81 ios.rdbuf( buf->orig_streambuf() );
82 internal::dealloc_streambuf( buf );
83+ return true;
84 }
85+ return false;
86 }
87
88 /**
89@@ -210,26 +216,82 @@
90 class auto_attach {
91 public:
92 /**
93+ * Default constructor; does nothing.
94+ */
95+ auto_attach() : stream_( nullptr ) {
96+ }
97+
98+ /**
99 * Constructs an %auto_attach object calling attach() on the given stream.
100 *
101 * @param stream The stream to attach the base64::streambuf to. If the
102 * stream already has a base64::streambuf attached to it, this contructor
103 * does nothing.
104 */
105- auto_attach( StreamType &stream ) : stream_( stream ) {
106- attach( stream );
107+ auto_attach( StreamType &stream ) : stream_( &stream ) {
108+ base64::attach( stream );
109+ }
110+
111+ /**
112+ * Copy constructor that takes ownership of the stream.
113+ *
114+ * @param from The %auto_attach to take ownership from.
115+ */
116+ auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
117+ from.stream_ = nullptr;
118 }
119
120 /**
121 * Destroys this %auto_attach object calling detach() on the previously
122- * attached stream.
123+ * attached stream, if any.
124 */
125 ~auto_attach() {
126- detach( stream_ );
127+ detach();
128+ }
129+
130+ /**
131+ * Assignment operator that takes ownership of the stream.
132+ *
133+ * @param from The %auto_attach to take ownership from.
134+ * @return \c *this.
135+ */
136+ auto_attach& operator=( auto_attach &from ) {
137+ if ( &from != this ) {
138+ stream_ = from.stream_;
139+ from.stream_ = nullptr;
140+ }
141+ return *this;
142+ }
143+
144+ /**
145+ * Calls base64::attach() on the given stream.
146+ *
147+ * @param stream The stream to attach the base64::streambuf to. If the
148+ * stream already has a base64::streambuf attached to it, this contructor
149+ * does nothing.
150+ * @param charset The name of the character encoding to convert from/to.
151+ * @return \c true only if a base64::streambuf was attached.
152+ */
153+ bool attach( StreamType &stream, char const *charset ) {
154+ if ( base64::attach( stream, charset ) ) {
155+ stream_ = &stream;
156+ return true;
157+ }
158+ return false;
159+ }
160+
161+ /**
162+ * Calls base64::detach().
163+ */
164+ void detach() {
165+ if ( stream_ ) {
166+ base64::detach( *stream_ );
167+ stream_ = nullptr;
168+ }
169 }
170
171 private:
172- StreamType &stream_;
173+ StreamType *stream_;
174 };
175
176 ///////////////////////////////////////////////////////////////////////////////
177
178=== modified file 'include/zorba/util/fs_util.h'
179--- include/zorba/util/fs_util.h 2013-08-02 14:55:29 +0000
180+++ include/zorba/util/fs_util.h 2013-08-06 14:19:26 +0000
181@@ -47,9 +47,11 @@
182 #ifdef WIN32
183 char const dir_separator = '\\';
184 char const path_separator = ';';
185+char const newline[] = "\r\n";
186 #else
187 char const dir_separator = '/';
188 char const path_separator = ':';
189+char const newline[] = "\n";
190 #endif /* WIN32 */
191
192 ////////// types //////////////////////////////////////////////////////////////
193@@ -74,7 +76,6 @@
194 volume,
195 other // named pipe, character/block special, socket, etc.
196 };
197-extern char const *const type_string[];
198
199 /**
200 * Emits the string representation of a file type to the given ostream.
201@@ -83,9 +84,8 @@
202 * @param t The file type to emit.
203 * @return Returns \a o.
204 */
205-inline std::ostream& operator<<( std::ostream &o, type t ) {
206- return o << type_string[ t ];
207-}
208+ZORBA_DLL_PUBLIC
209+std::ostream& operator<<( std::ostream &o, type t );
210
211 ////////// Directory //////////////////////////////////////////////////////////
212
213
214=== modified file 'include/zorba/util/hexbinary_stream.h'
215--- include/zorba/util/hexbinary_stream.h 2013-06-20 00:53:29 +0000
216+++ include/zorba/util/hexbinary_stream.h 2013-08-06 14:19:26 +0000
217@@ -133,9 +133,10 @@
218 * @param ios The stream to attach the hexbinary::streambuf to. If the stream
219 * already has a hexbinary::streambuf attached to it, this function does
220 * nothing.
221+ * @return \c true only if a hexbinary::streambuf was attached.
222 */
223 template<typename charT,class Traits> inline
224-void attach( std::basic_ios<charT,Traits> &ios ) {
225+bool attach( std::basic_ios<charT,Traits> &ios ) {
226 int const index = internal::hexbinary::get_streambuf_index();
227 void *&pword = ios.pword( index );
228 if ( !pword ) {
229@@ -144,7 +145,9 @@
230 ios.rdbuf( buf );
231 pword = buf;
232 ios.register_callback( internal::stream_callback, index );
233+ return true;
234 }
235+ return false;
236 }
237
238 /**
239@@ -154,15 +157,18 @@
240 * @param ios The stream to detach the hexbinary::streambuf from. If the
241 * stream doesn't have a hexbinary::streambuf attached to it, this function
242 * does nothing.
243+ * @return \c true only if a hexbinary::streambuf was detached.
244 */
245 template<typename charT,class Traits> inline
246-void detach( std::basic_ios<charT,Traits> &ios ) {
247+bool detach( std::basic_ios<charT,Traits> &ios ) {
248 int const index = internal::hexbinary::get_streambuf_index();
249 if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
250 ios.pword( index ) = nullptr;
251 ios.rdbuf( buf->orig_streambuf() );
252 internal::dealloc_streambuf( buf );
253+ return true;
254 }
255+ return false;
256 }
257
258 /**
259@@ -194,26 +200,81 @@
260 class auto_attach {
261 public:
262 /**
263+ * Default constructor; does nothing.
264+ */
265+ auto_attach() : stream_( nullptr ) {
266+ }
267+
268+ /**
269 * Constructs an %auto_attach object calling attach() on the given stream.
270 *
271 * @param stream The stream to attach the hexbinary::streambuf to. If the
272 * stream already has a hexbinary::streambuf attached to it, this contructor
273 * does nothing.
274 */
275- auto_attach( StreamType &stream ) : stream_( stream ) {
276+ auto_attach( StreamType &stream ) : stream_( &stream ) {
277 attach( stream );
278 }
279
280 /**
281+ * Copy constructor that takes ownership of the stream.
282+ *
283+ * @param from The %auto_attach to take ownership from.
284+ */
285+ auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
286+ from.stream_ = nullptr;
287+ }
288+
289+ /**
290 * Destroys this %auto_attach object calling detach() on the previously
291 * attached stream.
292 */
293 ~auto_attach() {
294- detach( stream_ );
295+ detach();
296+ }
297+
298+ /**
299+ * Assignment operator that takes ownership of the stream.
300+ *
301+ * @param from The %auto_attach to take ownership from.
302+ * @return \c *this.
303+ */
304+ auto_attach& operator=( auto_attach &from ) {
305+ if ( &from != this ) {
306+ stream_ = from.stream_;
307+ from.stream_ = nullptr;
308+ }
309+ return *this;
310+ }
311+
312+ /**
313+ * Calls hexbinary::attach() on the given stream.
314+ *
315+ * @param stream The stream to attach the hexbinary::streambuf to. If the
316+ * stream already has a hexbinary::streambuf attached to it, this contructor
317+ * does nothing.
318+ * @return \c true only if a hexbinary::streambuf was attached.
319+ */
320+ bool attach( StreamType &stream ) {
321+ if ( hexbinary::attach( stream ) ) {
322+ stream_ = &stream;
323+ return true;
324+ }
325+ return false;
326+ }
327+
328+ /**
329+ * Calls hexbinary::detach().
330+ */
331+ void detach() {
332+ if ( stream_ ) {
333+ hexbinary::detach( *stream_ );
334+ stream_ = nullptr;
335+ }
336 }
337
338 private:
339- StreamType &stream_;
340+ StreamType *stream_;
341 };
342
343 ///////////////////////////////////////////////////////////////////////////////
344
345=== modified file 'include/zorba/util/transcode_stream.h'
346--- include/zorba/util/transcode_stream.h 2013-06-12 00:21:05 +0000
347+++ include/zorba/util/transcode_stream.h 2013-08-06 14:19:26 +0000
348@@ -139,9 +139,10 @@
349 * already has a transcode::streambuf attached to it, this function does
350 * nothing.
351 * @param charset The name of the character encoding to convert from/to.
352+ * @return \c true only if a transcode::streambuf was attached.
353 */
354 template<typename charT,class Traits> inline
355-void attach( std::basic_ios<charT,Traits> &ios, char const *charset ) {
356+bool attach( std::basic_ios<charT,Traits> &ios, char const *charset ) {
357 int const index = internal::transcode::get_streambuf_index();
358 void *&pword = ios.pword( index );
359 if ( !pword ) {
360@@ -150,7 +151,9 @@
361 ios.rdbuf( buf );
362 pword = buf;
363 ios.register_callback( internal::stream_callback, index );
364+ return true;
365 }
366+ return false;
367 }
368
369 /**
370@@ -160,15 +163,18 @@
371 * @param ios The stream to detach the transcode::streambuf from. If the
372 * stream doesn't have a transcode::streambuf attached to it, this function
373 * does nothing.
374+ * @return \c true only if a transcode::streambuf was detached.
375 */
376 template<typename charT,class Traits> inline
377-void detach( std::basic_ios<charT,Traits> &ios ) {
378+bool detach( std::basic_ios<charT,Traits> &ios ) {
379 int const index = internal::transcode::get_streambuf_index();
380 if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) {
381 ios.pword( index ) = nullptr;
382 ios.rdbuf( buf->orig_streambuf() );
383 internal::dealloc_streambuf( buf );
384+ return true;
385 }
386+ return false;
387 }
388
389 /**
390@@ -214,6 +220,12 @@
391 class auto_attach {
392 public:
393 /**
394+ * Default constructor; does nothing.
395+ */
396+ auto_attach() : stream_( nullptr ) {
397+ }
398+
399+ /**
400 * Constructs an %auto_attach object calling attach() on the given stream.
401 *
402 * @param stream The stream to attach the transcode::streambuf to. If the
403@@ -221,20 +233,70 @@
404 * does nothing.
405 * @param charset The name of the character encoding to convert from/to.
406 */
407- auto_attach( StreamType &stream, char const *charset ) : stream_( stream ) {
408- attach( stream, charset );
409+ auto_attach( StreamType &stream, char const *charset ) : stream_( &stream ) {
410+ transcode::attach( stream, charset );
411+ }
412+
413+ /**
414+ * Copy constructor that takes ownership of the stream.
415+ *
416+ * @param from The %auto_attach to take ownership from.
417+ */
418+ auto_attach( auto_attach &from ) : stream_( from.stream_ ) {
419+ from.stream_ = nullptr;
420 }
421
422 /**
423 * Destroys this %auto_attach object calling detach() on the previously
424- * attached stream.
425+ * attached stream, if any.
426 */
427 ~auto_attach() {
428- detach( stream_ );
429+ detach();
430+ }
431+
432+ /**
433+ * Assignment operator that takes ownership of the stream.
434+ *
435+ * @param from The %auto_attach to take ownership from.
436+ * @return \c *this.
437+ */
438+ auto_attach& operator=( auto_attach &from ) {
439+ if ( &from != this ) {
440+ stream_ = from.stream_;
441+ from.stream_ = nullptr;
442+ }
443+ return *this;
444+ }
445+
446+ /**
447+ * Calls transcode::attach() on the given stream.
448+ *
449+ * @param stream The stream to attach the transcode::streambuf to. If the
450+ * stream already has a transcode::streambuf attached to it, this contructor
451+ * does nothing.
452+ * @param charset The name of the character encoding to convert from/to.
453+ * @return \c true only if a transcode::streambuf was attached.
454+ */
455+ bool attach( StreamType &stream, char const *charset ) {
456+ if ( transcode::attach( stream, charset ) ) {
457+ stream_ = &stream;
458+ return true;
459+ }
460+ return false;
461+ }
462+
463+ /**
464+ * Calls transcode::detach().
465+ */
466+ void detach() {
467+ if ( stream_ ) {
468+ transcode::detach( *stream_ );
469+ stream_ = nullptr;
470+ }
471 }
472
473 private:
474- StreamType &stream_;
475+ StreamType *stream_;
476 };
477
478 ///////////////////////////////////////////////////////////////////////////////
479
480=== modified file 'modules/com/zorba-xquery/www/modules/xqdoc/batch.xq'
481--- modules/com/zorba-xquery/www/modules/xqdoc/batch.xq 2013-06-15 16:20:18 +0000
482+++ modules/com/zorba-xquery/www/modules/xqdoc/batch.xq 2013-08-06 14:19:26 +0000
483@@ -97,7 +97,7 @@
484 declare %an:sequential function batch:save-xml($output-file, $page)
485 {
486 if($page instance of element(module)) then
487- file:write($output-file, batch:xqdoc($page), ());
488+ file:write-text($output-file, serialize(batch:xqdoc($page)));
489 else
490 ();
491 (:
492@@ -141,10 +141,16 @@
493 let $output-folder := batch:add-trailing-slash($output-folder)
494 let $output := concat($output-folder, $page-name)
495 return
496- file:write($output, $page, <out:serialization-parameters>
497- <out:method value="xhtml" />
498- <out:doctype-system value="about:legacy-compat" />
499- </out:serialization-parameters>)
500+ file:write-text(
501+ $output,
502+ serialize(
503+ $page,
504+ <out:serialization-parameters>
505+ <out:method value="xhtml" />
506+ <out:doctype-system value="about:legacy-compat" />
507+ </out:serialization-parameters>
508+ )
509+ )
510 };
511
512 declare %an:sequential function batch:copy-static-folders($output-folder as xs:string, $static-folders as xs:string*)
513
514=== modified file 'modules/org/expath/ns/file.xq'
515--- modules/org/expath/ns/file.xq 2013-06-15 20:57:44 +0000
516+++ modules/org/expath/ns/file.xq 2013-08-06 14:19:26 +0000
517@@ -1,7 +1,7 @@
518 xquery version "3.0";
519
520 (:
521- : Copyright 2006-2009 The FLWOR Foundation.
522+ : Copyright 2006-2013 The FLWOR Foundation.
523 :
524 : Licensed under the Apache License, Version 2.0 (the "License");
525 : you may not use this file except in compliance with the License.
526@@ -24,68 +24,128 @@
527 :)
528 module namespace file = "http://expath.org/ns/file";
529
530-import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
531 declare namespace an = "http://www.zorba-xquery.com/annotations";
532 declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
533 declare option ver:module-version "2.0";
534
535 (:~
536- : Appends a sequence of items to a file. If the file pointed by <pre>$file</pre>
537- : does not exist, a new file will be created. Before writing to the file, the items
538- : are serialized according to the <pre>$serializer-params</pre>.
539- :
540- : The semantics of <pre>$serializer-params</pre> is the same as for the
541- : <pre>$params</pre> parameter of the <a target="_blank"
542- : href="http://www.w3.org/TR/xpath-functions-11/#func-serialize">fn:serialize</a>
543- : function.
544- :
545- : @param $file The path/URI of the file to write the content to.
546- : @param $content The content to be serialized to the file.
547- : @param $serializer-params Parameter to control the serialization of the
548- : content.
549- : @return The empty sequence.
550- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
551- : @error file:FOFL9999 If any other error occurs.
552- :)
553-declare %an:sequential function file:append(
554- $file as xs:string,
555- $content as item()*,
556- $serializer-params as element(output:serialization-parameters)?
557-) as empty-sequence()
558-{
559- file:append-text(
560- $file,
561- fn:serialize($content, $serializer-params))
562-};
563-
564-(:~
565 : Appends a sequence of Base64 items as binary to a file. If the file pointed
566 : by <pre>$file</pre> does not exist, a new file will be created.
567 :
568 : @param $file The path/URI of the file to write the content to.
569- : @param $content The content to be serialized to the file.
570- : @return The empty sequence.
571- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
572- : @error file:FOFL9999 If any other error occurs.
573- :)
574-declare %an:sequential function file:append-binary(
575- $file as xs:string,
576- $content as xs:base64Binary*
577-) as empty-sequence() external;
578-
579-(:~
580- : Appends a sequence of string items to a file.
581- :
582- : @param $file The path/URI of the file to write the content to.
583- : @param $content The content to be serialized to the file.
584- : @return The empty sequence.
585- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
586- : @error file:FOFL9999 If any other error occurs.
587- :)
588-declare %private %an:sequential function file:append-text(
589- $file as xs:string,
590- $content as xs:string*
591-) as empty-sequence() external;
592+ : @param $content The content to be written to the file.
593+ : @return The empty sequence.
594+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
595+ : @error file:FOFL9999 If any other error occurs.
596+ :)
597+declare %an:sequential
598+function file:append-binary( $file as xs:string, $content as xs:base64Binary )
599+ as empty-sequence() external;
600+
601+(:~
602+ : Appends a sequence of string items to a file.
603+ :
604+ : @param $file The path/URI of the file to write the content to.
605+ : @param $content The content to be written to the file.
606+ : @param $encoding The character encoding to append <code>$content</code> as.
607+ : @return The empty sequence.
608+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
609+ : @error file:FOFL9999 If any other error occurs.
610+ :)
611+declare %an:sequential
612+function file:append-text( $file as xs:string, $content as xs:string*,
613+ $encoding as xs:string )
614+ as empty-sequence() external;
615+
616+(:~
617+ : Appends a sequence of string items to a file.
618+ :
619+ : @param $file The path/URI of the file to write the content to.
620+ : @param $content The content to be written to the file.
621+ : @return The empty sequence.
622+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
623+ : @error file:FOFL9999 If any other error occurs.
624+ :)
625+declare %an:sequential
626+function file:append-text( $file as xs:string, $content as xs:string* )
627+ as empty-sequence()
628+{
629+ file:append-text( $file, $content, "UTF-8" )
630+};
631+
632+(:~
633+ : Appends a sequence of string items to a file, each followed by a
634+ : platform-dependent newline character(s).
635+ :
636+ : @param $file The path/URI of the file to write the content to.
637+ : @param $content The content to be written to the file.
638+ : @param $encoding The character encoding to append <code>$content</code> as.
639+ : @return The empty sequence.
640+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
641+ : @error file:FOFL9999 If any other error occurs.
642+ :)
643+declare %an:sequential
644+function file:append-text-lines( $file as xs:string, $content as xs:string*,
645+ $encoding as xs:string )
646+ as empty-sequence() external;
647+
648+(:~
649+ : Appends a sequence of string to a file, each followed by a
650+ : platform-dependent newline character(s), using the UTF-8 character encoding.
651+ :
652+ : @param $file The path/URI of the file to write the content to.
653+ : @param $content The content to be written to the file.
654+ : @return The empty sequence.
655+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
656+ : @error file:FOFL9999 If any other error occurs.
657+ :)
658+declare %an:sequential
659+function file:append-text-lines( $file as xs:string, $content as xs:string* )
660+ as empty-sequence()
661+{
662+ file:append-text-lines( $file, $content, "UTF-8" )
663+};
664+
665+(:~
666+ : Returns the last component from the <pre>$path</pre>, deleting any
667+ : trailing directory-separator characters. If <pre>$path</pre> consists
668+ : entirely directory-separator characters, the empty string is returned. If
669+ : <pre>$path</pre> is the empty string, the string <pre>"."</pre> is returned,
670+ : signifying the current directory.
671+ :
672+ : No path existence check is made.
673+ :
674+ : @param $path A file path/URI.
675+ : @return The base name of this file.
676+ :)
677+declare function file:base-name( $path as xs:string )
678+ as xs:string external;
679+
680+(:~
681+ : Returns the last component from the <pre>$path</pre>, deleting any
682+ : trailing directory-separator characters and the <pre>$suffix</pre>. If path
683+ : consists entirely directory-separator characters, the empty string is
684+ : returned. If path is the empty string, the string <pre>"."</pre> is
685+ : returned, signifying the current directory.
686+ :
687+ : No path existence check is made.
688+ :
689+ : The <pre>$suffix</pre> can be used for example to eliminate file extensions.
690+ :
691+ : @param $path A file path/URI.
692+ : @param $suffix A suffix which should get deleted from the result.
693+ : @return The base-name of $path with a deleted $suffix.
694+ :)
695+declare function file:base-name( $path as xs:string, $suffix as xs:string )
696+ as xs:string
697+{
698+ let $res := file:base-name($path)
699+ return
700+ if (fn:ends-with($res, $suffix) and $res ne ".") then
701+ fn:substring($res, 1, fn:string-length($res) - fn:string-length($suffix))
702+ else
703+ $res
704+};
705
706 (:~
707 : Copies a file or a directory given a source and a destination path/URI.
708@@ -100,10 +160,9 @@
709 : parent directory does not exist either.
710 : @error file:FOFL9999 If any other error occurs.
711 :)
712-declare %an:nondeterministic %an:sequential function file:copy(
713- $source as xs:string,
714- $destination as xs:string
715-) as empty-sequence()
716+declare %an:nondeterministic %an:sequential
717+function file:copy( $source as xs:string, $destination as xs:string )
718+ as empty-sequence()
719 {
720 if (file:exists($source)) then
721 if (file:is-directory($source)) then
722@@ -115,89 +174,6 @@
723 };
724
725 (:~
726- : Copies a file given a source and a destination path/URI.
727- :
728- : @param $sourceFile The path/URI of the file to copy.
729- : @param $destination The destination path/URI.
730- : @return The empty sequence.
731- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
732- : @error file:FOFL0002 If the computed destination points to directory.
733- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
734- : parent directory does not exist either.
735- : @error file:FOFL0004 If <pre>$sourceFile</pre> points to a directory.
736- : @error file:FOFL9999 If any other error occurs.
737- :)
738-declare %private %an:sequential function file:copy-file-impl(
739- $sourceFile as xs:string,
740- $destination as xs:string
741-) as empty-sequence() external;
742-
743-(:~
744- : Copies a source directory recursively to a destination path/URI.
745- :
746- : @param $sourceDir The path/URI of the directory to copy.
747- : @param $destination The destination path/URI.
748- : @return The empty sequence.
749- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
750- : @error file:FOFL0002 If <pre>$destination</pre> points to an existing file.
751- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
752- : parent directory does not exist either.
753- : @error file:FOFL9999 If any other error occurs.
754- :)
755-declare %private %an:nondeterministic %an:sequential function file:copy-directory-impl(
756- $sourceDir as xs:string,
757- $destination as xs:string
758-) as empty-sequence()
759-{
760- if (file:is-file($destination)) then
761- fn:error(xs:QName("file:FOFL0002"), fn:concat("The specified destination path already exists: ", $destination))
762- else if (fn:not(file:exists($destination))) then
763- let $dirname := file:dir-name($destination)
764- return
765- if (fn:not(file:exists($dirname))) then
766- fn:error(xs:QName("file:FOFL0003"), fn:concat("The destination directory does not exist: ", $dirname))
767- else
768- {
769- file:create-directory($destination);
770- file:copy-directory-content($sourceDir, $destination)
771- }
772-
773- else
774- let $basename := file:base-name($sourceDir)
775- let $newdir := fn:concat($destination, file:directory-separator(), $basename)
776- return
777- {
778- file:create-directory($newdir);
779- file:copy-directory-content($sourceDir, $newdir)
780- }
781-};
782-
783-(:~
784- : Copies the content of a given directory to an existing destination
785- : directory.
786- :
787- : @param $sourceDir The path/URI of the directory to copy the content from.
788- : @param $destination The destination directory path/URI.
789- : @return The empty sequence.
790- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
791- : @error file:FOFL0003 If <pre>$destination</pre> directory does not exist.
792- : @error file:FOFL9999 If any other error occurs.
793- :)
794-declare %private %an:nondeterministic %an:sequential function file:copy-directory-content(
795- $sourceDir as xs:string,
796- $destination as xs:string
797-) as empty-sequence()
798-{
799- if (file:is-directory($destination)) then
800- for $item in file:list($sourceDir)
801- let $fullPath := fn:concat($sourceDir, file:directory-separator(), $item)
802- return
803- file:copy($fullPath, $destination)
804- else
805- fn:error(xs:QName("file:FOFL0003"), fn:concat("The specified destination directory does not exist: ", $destination))
806-};
807-
808-(:~
809 : Creates a directory.
810 :
811 : The operation is will create all the missing parent directories from the
812@@ -209,9 +185,9 @@
813 : existing file.
814 : @error file:FOFL9999 If any other error occurs.
815 :)
816-declare %an:sequential function file:create-directory(
817- $dir as xs:string
818-) as empty-sequence() external;
819+declare %an:sequential function
820+file:create-directory( $dir as xs:string )
821+ as empty-sequence() external;
822
823 (:~
824 : Deletes a file or a directory from the file system.
825@@ -224,9 +200,9 @@
826 : @error file:FOFL0001 If the <pre>$path</pre> path does not exist.
827 : @error file:FOFL9999 If any other error occurs.
828 :)
829-declare %an:nondeterministic %an:sequential function file:delete(
830- $path as xs:string
831-) as empty-sequence()
832+declare %an:nondeterministic %an:sequential
833+function file:delete( $path as xs:string )
834+ as empty-sequence()
835 {
836 if (file:exists($path,false())) then
837 if (not(file:is-symlink($path)) and file:is-directory($path)) then
838@@ -238,40 +214,29 @@
839 };
840
841 (:~
842- : Deletes a file from the file system.
843+ : This function returns the value of the operating system specific directory
844+ : separator. For example, <pre>/</pre> on Unix-based systems and <pre>\</pre>
845+ : on Windows systems.
846 :
847- : @param $file The path/URI of the file to delete.
848- : @return The empty sequence.
849- : @error file:FOFL0001 If the <pre>$file</pre> path does not exist.
850- : @error file:FOFL9999 If any other error occurs.
851+ : @return The operating system specific directory separator.
852 :)
853-declare %private %an:sequential function file:delete-file-impl(
854- $file as xs:string
855-) as empty-sequence() external;
856+declare function file:directory-separator()
857+ as xs:string external;
858
859 (:~
860- : Deletes a directory from the file system.
861- :
862- : @param $dir The path/URI of the directory to delete.
863- : @return The empty sequence.
864- : @error file:FOFL0001 If the <pre>$dir</pre> path does not exist.
865- : @error file:FOFL0003 If <pre>$dir</pre> does not point to a directory.
866- : @error file:FOFL9999 If any other error occurs.
867+ : This function is the converse of <pre>file:base-name</pre>. It returns a
868+ : string denoting the parent directory of the <pre>$path</pre>. Any trailing
869+ : directory-separator characters are not counted as part of the directory
870+ : name. If path is the empty string or contains no directory-separator string,
871+ : <pre>"."</pre> is returned, signifying the current directory.
872+ :
873+ : No path existence check is made.
874+ :
875+ : @param $path The filename, of which the dirname should be get.
876+ : @return The name of the directory the file is in.
877 :)
878-declare %private %an:nondeterministic %an:sequential function file:delete-directory-impl(
879- $dir as xs:string
880-) as empty-sequence()
881-{
882- for $item in file:list($dir)
883- let $fullPath := fn:concat($dir, file:directory-separator(), $item)
884- return
885- if (file:is-directory($fullPath)) then
886- file:delete-directory-impl($fullPath);
887- else
888- file:delete-file-impl($fullPath);
889-
890- file:delete-file-impl($dir)
891-};
892+declare function file:dir-name( $path as xs:string )
893+ as xs:string external;
894
895 (:~
896 : Tests if a path/URI is already used in the file system.
897@@ -280,9 +245,9 @@
898 : @param $follow-symlinks if <code>true</code>, follows symbolic links.
899 : @return true if <code>$path</code> points to an existing file system item.
900 :)
901-declare %an:nondeterministic function file:exists(
902- $path as xs:string, $follow-symlinks as xs:boolean
903-) as xs:boolean external;
904+declare %an:nondeterministic
905+function file:exists( $path as xs:string, $follow-symlinks as xs:boolean )
906+ as xs:boolean external;
907
908 (:~
909 : Tests if a path/URI is already used in the file system.
910@@ -291,11 +256,27 @@
911 : @return true if <code>$path</code> points to an existing file system item;
912 : for symbolic links, retuns true if the linked-to item exists.
913 :)
914-declare %an:nondeterministic function file:exists(
915- $path as xs:string
916-) as xs:boolean
917-{
918- file:exists($path,true())
919+declare %an:nondeterministic
920+function file:exists( $path as xs:string )
921+ as xs:boolean
922+{
923+ file:exists( $path, true() )
924+};
925+
926+(:~
927+ : A helper function that performs a trivial (not complete) glob to regex
928+ : pattern translation.
929+ :
930+ : @param $pattern The glob pattern.
931+ : @return A regex pattern corresponding to the glob pattern provided.
932+ :)
933+declare function file:glob-to-regex( $pattern as xs:string )
934+ as xs:string
935+{
936+ let $pattern := fn:replace($pattern, '(\.|\[|\]|\\|/|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
937+ let $pattern := fn:replace($pattern, '\\\?', '.')
938+ let $pattern := fn:replace($pattern, '\\\*', '.*')
939+ return fn:concat( "^", $pattern, "$" )
940 };
941
942 (:~
943@@ -306,9 +287,9 @@
944 : @return true if <code>$path</code> points to a directory; for symbolic
945 : links, returns true if the linked-to item is a directory.
946 :)
947-declare %an:nondeterministic function file:is-directory(
948- $path as xs:string
949-) as xs:boolean external;
950+declare %an:nondeterministic
951+function file:is-directory( $path as xs:string )
952+ as xs:boolean external;
953
954 (:~
955 : Tests if a path/URI points to a file.
956@@ -317,9 +298,9 @@
957 : @return true if <code>$path</code> points to a file; for symbolic links,
958 : returns true if the linked-to item is a file.
959 :)
960-declare %an:nondeterministic function file:is-file(
961- $path as xs:string
962-) as xs:boolean external;
963+declare %an:nondeterministic
964+function file:is-file( $path as xs:string )
965+ as xs:boolean external;
966
967 (:~
968 : Tests if a path/URI points to symbolic link. This works on all Unix-based
969@@ -328,235 +309,22 @@
970 : @param $path The path/URI to test.
971 : @return true if <code>$path</code> points to a symbolic link.
972 :)
973-declare %an:nondeterministic function file:is-symlink(
974- $path as xs:string
975-) as xs:boolean external;
976-
977-(:~
978- : Moves a file or directory given a source and a destination paths/URIs.
979- :
980- : @param $source The path/URI of the file to move.
981- : @param $destination The destination path/URI.
982- : @return The empty sequence.
983- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
984- : @error file:FOFL0002 If <pre>$source</pre> points to a directory and
985- : <pre>$destination</pre> points to an existing file.
986- : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's parent
987- : directory does not exist either.
988- : @error file:FOFL9999 If any other error occurs.
989- :)
990-declare %an:sequential function file:move(
991- $source as xs:string,
992- $destination as xs:string
993-) as empty-sequence()
994-{
995- file:copy($source, $destination);
996- file:delete($source);
997-};
998-
999-(:~
1000- : Reads the content of a file and returns a Base64 representation of the
1001- : content.
1002- :
1003- : @param $file The file to read.
1004- : @return The content of the file as Base64.
1005- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1006- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1007- : @error file:FOFL9999 If any other error occurs.
1008- :)
1009-declare %an:nondeterministic function file:read-binary(
1010- $file as xs:string
1011-) as xs:base64Binary external;
1012-
1013-(:~
1014- : Reads the content of a file and returns a string representation of the
1015- : content.
1016- :
1017- : The operation is equivalent to calling:
1018- : <pre>file:read-text($file, "UTF-8")</pre>.
1019- :
1020- : @param $file The file to read.
1021- : @return The content of the file as string.
1022- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1023- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1024- : @error file:FOFL9999 If any other error occurs.
1025- :)
1026-declare %an:nondeterministic function file:read-text(
1027- $file as xs:string
1028-) as xs:string
1029-{
1030- file:read-text($file, "UTF-8")
1031-};
1032-
1033-(:~
1034- : Reads the content of a file using the specified encoding and returns a
1035- : string representation of the content.
1036- :
1037- : @param $file The file to read.
1038- : @param $encoding The encoding used when reading the file.
1039- : If compiled with ICU, then Zorba supports any encoding that ICU supports;
1040- : otherwise Zorba only supports ASCII and UTF-8.
1041- : The encoding parameter is case insensitive.
1042- : @return The content of the file as string.
1043- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1044- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1045- : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
1046- : @error file:FOFL9999 If any other error occurs.
1047- :)
1048-declare %an:nondeterministic function file:read-text(
1049- $file as xs:string,
1050- $encoding as xs:string
1051-) as xs:string external;
1052-
1053-(:~
1054- : Reads the content of a file and returns a sequence of strings representing
1055- : the lines in the content of the file.
1056- :
1057- : The operation is equivalent to calling:
1058- : <pre>file:read-text-lines($file, "UTF-8")</pre>.
1059- :
1060- : @param $file The file to read.
1061- : @return The content of the file as a sequence of strings.
1062- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1063- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1064- : @error file:FOFL9999 If any other error occurs.
1065- :)
1066-declare %an:nondeterministic function file:read-text-lines(
1067- $file as xs:string
1068-) as xs:string*
1069-{
1070- file:read-text-lines($file, "UTF-8")
1071-};
1072-
1073-(:~
1074- : Reads the content of a file using the specified encoding and returns a
1075- : sequence of strings representing the lines in the content of the file.
1076- :
1077- : This implementation considers the LF (&#xA;) character as the line
1078- : separator. If a resulting line ends with the CR (&#xD;) character, this is
1079- : trimmed as well. This implementation will uniformly treat LF and CRLF as
1080- : line separators.
1081- :
1082- : @param $file The file to read.
1083- : @param $encoding The encoding used when reading the file.
1084- : If compiled with ICU, then Zorba supports any encoding that ICU supports;
1085- : otherwise Zorba only supports ASCII and UTF-8.
1086- : The encoding parameter is case insensitive.
1087- : @return The content of the file as a sequence of strings.
1088- : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1089- : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1090- : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
1091- : @error file:FOFL9999 If any other error occurs.
1092- :)
1093-declare %an:nondeterministic function file:read-text-lines(
1094- $file as xs:string,
1095- $encoding as xs:string
1096-) as xs:string* external;
1097-
1098-(:~
1099- : This is an internal function that copies an entire source directory to an
1100- : destination directory. The caller to this function must make sure that both
1101- : the source and destination point to existing directories.
1102- :
1103- : @param $sourceDir The existing source directory.
1104- : @param $destinationDir The existing destination directory.
1105- : @return The empty sequence.
1106- :)
1107-declare %private %an:nondeterministic %an:sequential function file:copy-directory(
1108- $sourceDir as xs:string,
1109- $destinationDir as xs:string
1110-) as empty-sequence()
1111-{
1112- let $name := file:base-name($sourceDir)
1113- let $destDir := fn:concat($destinationDir, file:directory-separator(), $name)
1114- return
1115- {
1116- file:create-directory($destDir);
1117-
1118- for $item in file:list($sourceDir)
1119- let $fullSrcPath := fn:concat($sourceDir, file:directory-separator(), $item)
1120- let $fullDestPath := fn:concat($destDir, file:directory-separator(), $item)
1121- return
1122- if (file:is-directory($fullSrcPath)) then
1123- file:copy-directory($fullSrcPath, $fullDestPath)
1124- else
1125- file:copy($fullSrcPath, $fullDestPath)
1126- }
1127-};
1128-
1129-(:~
1130- : Writes a sequence of items to a file. Before writing to the file, the items
1131- : are serialized according to the <pre>$serializer-params</pre>.
1132- :
1133- : The semantics of <pre>$serializer-params</pre> is the same as for the
1134- : <pre>$params</pre> parameter of the <a target="_blank"
1135- : href="http://www.w3.org/TR/xpath-functions-11/#func-serialize">fn:serialize</a>
1136- : function.
1137- :
1138- : @param $file The path/URI of the file to write the content to.
1139- : @param $content The content to be serialized to the file.
1140- : @param $serializer-params Parameter to control the serialization of the
1141- : content.
1142- : @return The empty sequence.
1143- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1144- : @error file:FOFL9999 If any other error occurs.
1145- :)
1146-declare %an:sequential function file:write(
1147- $file as xs:string,
1148- $content as item()*,
1149- $serializer-params as element(output:serialization-parameters)?
1150-) as empty-sequence()
1151-{
1152- file:write-text($file, fn:serialize($content, $serializer-params))
1153-};
1154-
1155-(:~
1156- : Writes a sequence of Base64 items as binary to a file.
1157- :
1158- : The operation is equivalent to calling:
1159- : <pre>file:write-binary($file, $content, fn:true())</pre>.
1160- :
1161- : @param $file The path/URI of the file to write the content to.
1162- : @param $content The content to be serialized to the file.
1163- : @return The empty sequence.
1164- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1165- : @error file:FOFL9999 If any other error occurs.
1166- :)
1167-declare %an:sequential function file:write-binary(
1168- $file as xs:string,
1169- $content as xs:base64Binary*
1170-) as empty-sequence() external;
1171-
1172-(:~
1173- : Writes a sequence of Base64 items as binary to a file.
1174- :
1175- : @param $file The path/URI of the file to write the content to.
1176- : @param $content The content to be serialized to the file.
1177- : @return The empty sequence.
1178- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1179- : @error file:FOFL9999 If any other error occurs.
1180- :)
1181-declare %an:sequential function file:write-binary(
1182- $file as xs:string,
1183- $content as xs:base64Binary*
1184-) as empty-sequence() external;
1185-
1186-(:~
1187- : Writes a sequence of string items to a file.
1188- :
1189- : The operation is equivalent to calling:
1190- : <pre>file:write-text($file, $content, fn:true())</pre>.
1191- :
1192- : @param $file The path/URI of the file to write the content to.
1193- : @param $content The content to be serialized to the file.
1194- : @return The empty sequence.
1195- : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1196- : @error file:FOFL9999 If any other error occurs.
1197- :)
1198-declare %private %an:sequential function file:write-text(
1199- $file as xs:string,
1200- $content as xs:string*
1201-) as empty-sequence() external;
1202+declare %an:nondeterministic
1203+function file:is-symlink( $path as xs:string )
1204+ as xs:boolean external;
1205+
1206+(:~
1207+ : Retrieves the timestamp of the last modification of the file system item
1208+ : pointed by the path/URI.
1209+ :
1210+ : @param $path The file system item to read the last modification
1211+ : timestamp from.
1212+ : @return The date and time of the last modification of the item.
1213+ : @error file:FOFL0001 If the <pre>$path</pre> does not exist.
1214+ : @error file:FOFL9999 If any other error occurs.
1215+ :)
1216+declare %an:nondeterministic function file:last-modified( $path as xs:string )
1217+ as xs:dateTime external;
1218
1219 (:~
1220 : Lists the file system items in a certain directory.
1221@@ -569,9 +337,9 @@
1222 : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
1223 : @error file:FOFL9999 If any other error occurs.
1224 :)
1225-declare %an:nondeterministic function file:list(
1226- $dir as xs:string
1227-) as xs:string* external;
1228+declare %an:nondeterministic
1229+function file:list( $dir as xs:string )
1230+ as xs:string* external;
1231
1232 (:~
1233 : Lists the file system items in a certain directory. The order of the items
1234@@ -588,10 +356,9 @@
1235 : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
1236 : @error file:FOFL9999 If any other error occurs.
1237 :)
1238-declare %an:nondeterministic function file:list(
1239- $path as xs:string,
1240- $recursive as xs:boolean
1241-) as xs:string*
1242+declare %an:nondeterministic
1243+function file:list( $path as xs:string, $recursive as xs:boolean )
1244+ as xs:string*
1245 {
1246 for $f in file:list($path)
1247 let $full := fn:concat($path, file:directory-separator(), $f)
1248@@ -625,81 +392,174 @@
1249 : @error file:FOFL0003 If <pre>$dir</pre> does not point to an existing directory.
1250 : @error file:FOFL9999 If any other error occurs.
1251 :)
1252-declare %an:nondeterministic function file:list(
1253- $path as xs:string,
1254- $recursive as xs:boolean,
1255- $pattern as xs:string
1256-) as xs:string* {
1257- for $file in file:list($path, $recursive)
1258- let $name := file:base-name($file)
1259+declare %an:nondeterministic
1260+function file:list( $path as xs:string, $recursive as xs:boolean,
1261+ $pattern as xs:string )
1262+ as xs:string*
1263+{
1264+ for $file in file:list( $path, $recursive )
1265+ let $name := file:base-name( $file )
1266 return
1267- if (fn:matches($name, file:glob-to-regex($pattern))) then
1268+ if ( fn:matches( $name, file:glob-to-regex( $pattern ) ) ) then
1269 $file
1270 else
1271 ()
1272 };
1273
1274 (:~
1275- : A helper function that performs a trivial (not complete) glob to regex
1276- : pattern translation.
1277- :
1278- : @param $pattern The glob pattern.
1279- : @return A regex pattern corresponding to the glob pattern provided.
1280+ : Moves a file or directory given a source and a destination paths/URIs.
1281+ :
1282+ : @param $source The path/URI of the file to move.
1283+ : @param $destination The destination path/URI.
1284+ : @return The empty sequence.
1285+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1286+ : @error file:FOFL0002 If <pre>$source</pre> points to a directory and
1287+ : <pre>$destination</pre> points to an existing file.
1288+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and its
1289+ : parent directory does not exist either.
1290+ : @error file:FOFL9999 If any other error occurs.
1291 :)
1292-declare function file:glob-to-regex(
1293- $pattern as xs:string
1294-) as xs:string {
1295- let $pattern := fn:replace($pattern, '(\.|\[|\]|\\|/|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
1296- let $pattern := fn:replace($pattern, '\\\?', '.')
1297- let $pattern := fn:replace($pattern, '\\\*', '.*')
1298- return
1299- fn:concat("^", $pattern, "$")
1300+declare %an:sequential
1301+function file:move( $source as xs:string, $destination as xs:string )
1302+ as empty-sequence()
1303+{
1304+ file:copy( $source, $destination );
1305+ file:delete( $source );
1306 };
1307
1308 (:~
1309- : Retrieves the timestamp of the last modification of the file system item
1310- : pointed by the path/URI.
1311- :
1312- : @param $path The file system item to read the last modification
1313- : timestamp from.
1314- : @return The date and time of the last modification of the item.
1315- : @error file:FOFL0001 If the <pre>$path</pre> does not exist.
1316- : @error file:FOFL9999 If any other error occurs.
1317- :)
1318-declare %an:nondeterministic function file:last-modified(
1319- $path as xs:string
1320-) as xs:dateTime external;
1321-
1322-(:~
1323- : Retrieves the size of a file.
1324- :
1325- : @param $file The file get the size.
1326- : @return An integer representing the size in bytes of the file.
1327- : @error file:FOFL0001 If the <pre>$file</pre> does not exist.
1328- : @error file:FOFL0004 If the <pre>$file</pre> points to a directory.
1329- : @error file:FOFL9999 If any other error occurs.
1330- :)
1331-declare %an:nondeterministic function file:size(
1332- $file as xs:string
1333-) as xs:integer external;
1334-
1335-(:~
1336- : This function returns the value of the operating system specific directory
1337- : separator. For example, <pre>/</pre> on Unix-based systems and <pre>\</pre>
1338- : on Windows systems.
1339- :
1340- : @return The operating system specific directory separator.
1341- :)
1342-declare function file:directory-separator() as xs:string external;
1343-
1344-(:~
1345 : This function returns the value of the operating system specific path
1346 : separator. For example, <pre>:</pre> on Unix-based systems and <pre>;</pre>
1347 : on Windows systems.
1348 :
1349 : @return The operating system specific path separator.
1350 :)
1351-declare function file:path-separator() as xs:string external;
1352+declare function file:path-separator()
1353+ as xs:string external;
1354+
1355+(:~
1356+ : Transforms a URI, an absolute path, or relative path to a native path on the
1357+ : running platform.
1358+ :
1359+ : No path existence check is made.
1360+ :
1361+ : @param $path The uri or path to normalize.
1362+ : @return The native path corresponding to <pre>$path</pre>.
1363+ : @error file:FOFL9999 If an error occurs while trying to obtain the native
1364+ : path.
1365+ :)
1366+declare function file:path-to-native( $path as xs:string )
1367+ as xs:string external;
1368+
1369+(:~
1370+ : Transforms a file system path into a URI with the file:// scheme. If the
1371+ : path is relative, it is first resolved against the current working
1372+ : directory.
1373+ :
1374+ : No path existence check is made.
1375+ :
1376+ : @param $path The path to transform.
1377+ : @return The file URI corresponding to <pre>path</pre>.
1378+ :)
1379+declare function file:path-to-uri( $path as xs:string )
1380+ as xs:anyURI external;
1381+
1382+(:~
1383+ : Reads the content of a file and returns a Base64 representation of the
1384+ : content.
1385+ :
1386+ : @param $file The file to read.
1387+ : @return The content of the file as Base64.
1388+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1389+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1390+ : @error file:FOFL9999 If any other error occurs.
1391+ :)
1392+declare %an:nondeterministic
1393+function file:read-binary( $file as xs:string )
1394+ as xs:base64Binary external;
1395+
1396+(:~
1397+ : Reads the content of a file using the specified encoding and returns a
1398+ : string representation of the content.
1399+ :
1400+ : @param $file The file to read.
1401+ : @param $encoding The encoding used when reading the file.
1402+ : If compiled with ICU, then Zorba supports any encoding that ICU supports;
1403+ : otherwise Zorba only supports ASCII and UTF-8.
1404+ : The encoding parameter is case insensitive.
1405+ : @return The content of the file as string.
1406+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1407+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1408+ : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
1409+ : @error file:FOFL9999 If any other error occurs.
1410+ :)
1411+declare %an:nondeterministic
1412+function file:read-text( $file as xs:string, $encoding as xs:string )
1413+ as xs:string external;
1414+
1415+(:~
1416+ : Reads the content of a file and returns a string representation of the
1417+ : content.
1418+ :
1419+ : The operation is equivalent to calling:
1420+ : <pre>file:read-text($file, "UTF-8")</pre>.
1421+ :
1422+ : @param $file The file to read.
1423+ : @return The content of the file as string.
1424+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1425+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1426+ : @error file:FOFL9999 If any other error occurs.
1427+ :)
1428+declare %an:nondeterministic
1429+function file:read-text( $file as xs:string )
1430+ as xs:string
1431+{
1432+ file:read-text( $file, "UTF-8" )
1433+};
1434+
1435+(:~
1436+ : Reads the content of a file and returns a sequence of strings representing
1437+ : the lines in the content of the file.
1438+ :
1439+ : The operation is equivalent to calling:
1440+ : <pre>file:read-text-lines($file, "UTF-8")</pre>.
1441+ :
1442+ : @param $file The file to read.
1443+ : @return The content of the file as a sequence of strings.
1444+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1445+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1446+ : @error file:FOFL9999 If any other error occurs.
1447+ :)
1448+declare %an:nondeterministic
1449+function file:read-text-lines( $file as xs:string )
1450+ as xs:string*
1451+{
1452+ file:read-text-lines( $file, "UTF-8" )
1453+};
1454+
1455+(:~
1456+ : Reads the content of a file using the specified encoding and returns a
1457+ : sequence of strings representing the lines in the content of the file.
1458+ :
1459+ : This implementation considers the LF (&#xA;) character as the line
1460+ : separator. If a resulting line ends with the CR (&#xD;) character, this is
1461+ : trimmed as well. This implementation will uniformly treat LF and CRLF as
1462+ : line separators.
1463+ :
1464+ : @param $file The file to read.
1465+ : @param $encoding The encoding used when reading the file.
1466+ : If compiled with ICU, then Zorba supports any encoding that ICU supports;
1467+ : otherwise Zorba only supports ASCII and UTF-8.
1468+ : The encoding parameter is case insensitive.
1469+ : @return The content of the file as a sequence of strings.
1470+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1471+ : @error file:FOFL0004 If <pre>$source</pre> points to a directory.
1472+ : @error file:FOFL0006 If <pre>$encoding</pre> is not supported.
1473+ : @error file:FOFL9999 If any other error occurs.
1474+ :)
1475+declare %an:nondeterministic
1476+function file:read-text-lines( $file as xs:string, $encoding as xs:string )
1477+ as xs:string* external;
1478
1479 (:~
1480 : Transforms a relative path/URI into an absolute operating system path by
1481@@ -710,88 +570,247 @@
1482 : @param $path The path/URI to transform.
1483 : @return The operating system file path.
1484 :)
1485-declare function file:resolve-path(
1486- $path as xs:string
1487-) as xs:string external;
1488-
1489-(:~
1490- : Transforms a file system path into a URI with the file:// scheme. If the
1491- : path is relative, it is first resolved against the current working
1492+declare function file:resolve-path( $path as xs:string )
1493+ as xs:string external;
1494+
1495+(:~
1496+ : Retrieves the size of a file.
1497+ :
1498+ : @param $file The file get the size.
1499+ : @return An integer representing the size in bytes of the file.
1500+ : @error file:FOFL0001 If the <pre>$file</pre> does not exist.
1501+ : @error file:FOFL0004 If the <pre>$file</pre> points to a directory.
1502+ : @error file:FOFL9999 If any other error occurs.
1503+ :)
1504+declare %an:nondeterministic function file:size( $file as xs:string )
1505+ as xs:integer external;
1506+
1507+(:~
1508+ : Writes a sequence of Base64 items as binary to a file.
1509+ :
1510+ : @param $file The path/URI of the file to write the content to.
1511+ : @param $content The content to be written to the file.
1512+ : @return The empty sequence.
1513+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1514+ : @error file:FOFL9999 If any other error occurs.
1515+ :)
1516+declare %an:sequential
1517+function file:write-binary( $file as xs:string, $content as xs:base64Binary )
1518+ as empty-sequence() external;
1519+
1520+(:~
1521+ : Writes a sequence of strings to a file.
1522+ :
1523+ : @param $file The path/URI of the file to write the content to.
1524+ : @param $content The content to be written to the file.
1525+ : @param $encoding The character encoding to write <code>$content</code> as.
1526+ : @return The empty sequence.
1527+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1528+ : @error file:FOFL9999 If any other error occurs.
1529+ :)
1530+declare %an:sequential
1531+function file:write-text( $file as xs:string, $content as xs:string*,
1532+ $encoding as xs:string )
1533+ as empty-sequence() external;
1534+
1535+(:~
1536+ : Writes a sequence of strings to a file using the UTF-8 character encoding.
1537+ :
1538+ : @param $file The path/URI of the file to write the content to.
1539+ : @param $content The content to be written to the file.
1540+ : @return The empty sequence.
1541+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1542+ : @error file:FOFL9999 If any other error occurs.
1543+ :)
1544+declare %an:sequential
1545+function file:write-text( $file as xs:string, $content as xs:string* )
1546+ as empty-sequence()
1547+{
1548+ file:write-text( $file, $content, "UTF-8" )
1549+};
1550+
1551+(:~
1552+ : Writes a sequence of strings to a file, each followed by a
1553+ : platform-dependent newline character(s).
1554+ :
1555+ : @param $file The path/URI of the file to write the content to.
1556+ : @param $content The content to be written to the file.
1557+ : @param $encoding The character encoding to write <code>$content</code> as.
1558+ : @return The empty sequence.
1559+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1560+ : @error file:FOFL9999 If any other error occurs.
1561+ :)
1562+declare %an:sequential
1563+function file:write-text-lines( $file as xs:string, $content as xs:string*,
1564+ $encoding as xs:string )
1565+ as empty-sequence() external;
1566+
1567+(:~
1568+ : Writes a sequence of strings to a file, each followed by a
1569+ : platform-dependent newline character(s), using the UTF-8 character encoding.
1570+ :
1571+ : @param $file The path/URI of the file to write the content to.
1572+ : @param $content The content to be written to the file.
1573+ : @return The empty sequence.
1574+ : @error file:FOFL0004 If <pre>$file</pre> points to a directory.
1575+ : @error file:FOFL9999 If any other error occurs.
1576+ :)
1577+declare %an:sequential
1578+function file:write-text-lines( $file as xs:string, $content as xs:string* )
1579+ as empty-sequence()
1580+{
1581+ file:write-text-lines( $file, $content, "UTF-8" )
1582+};
1583+
1584+(:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)
1585+
1586+(:~
1587+ : Copies a file given a source and a destination path/URI.
1588+ :
1589+ : @param $sourceFile The path/URI of the file to copy.
1590+ : @param $destination The destination path/URI.
1591+ : @return The empty sequence.
1592+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1593+ : @error file:FOFL0002 If the computed destination points to directory.
1594+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
1595+ : parent directory does not exist either.
1596+ : @error file:FOFL0004 If <pre>$sourceFile</pre> points to a directory.
1597+ : @error file:FOFL9999 If any other error occurs.
1598+ :)
1599+declare %private %an:sequential
1600+function file:copy-file-impl( $sourceFile as xs:string,
1601+ $destination as xs:string )
1602+ as empty-sequence() external;
1603+
1604+(:~
1605+ : Copies a source directory recursively to a destination path/URI.
1606+ :
1607+ : @param $sourceDir The path/URI of the directory to copy.
1608+ : @param $destination The destination path/URI.
1609+ : @return The empty sequence.
1610+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1611+ : @error file:FOFL0002 If <pre>$destination</pre> points to an existing file.
1612+ : @error file:FOFL0003 If <pre>$destination</pre> does not exist and it's
1613+ : parent directory does not exist either.
1614+ : @error file:FOFL9999 If any other error occurs.
1615+ :)
1616+declare %private %an:nondeterministic %an:sequential
1617+function file:copy-directory-impl( $sourceDir as xs:string,
1618+ $destination as xs:string )
1619+ as empty-sequence()
1620+{
1621+ if (file:is-file($destination)) then
1622+ fn:error(xs:QName("file:FOFL0002"), fn:concat("The specified destination path already exists: ", $destination))
1623+ else if (fn:not(file:exists($destination))) then
1624+ let $dirname := file:dir-name($destination)
1625+ return
1626+ if (fn:not(file:exists($dirname))) then
1627+ fn:error(xs:QName("file:FOFL0003"), fn:concat("The destination directory does not exist: ", $dirname))
1628+ else
1629+ {
1630+ file:create-directory($destination);
1631+ file:copy-directory-content($sourceDir, $destination)
1632+ }
1633+ else
1634+ let $basename := file:base-name($sourceDir)
1635+ let $newdir := fn:concat($destination, file:directory-separator(), $basename)
1636+ return
1637+ {
1638+ file:create-directory($newdir);
1639+ file:copy-directory-content($sourceDir, $newdir)
1640+ }
1641+};
1642+
1643+(:~
1644+ : This is an internal function that copies an entire source directory to an
1645+ : destination directory. The caller to this function must make sure that both
1646+ : the source and destination point to existing directories.
1647+ :
1648+ : @param $sourceDir The existing source directory.
1649+ : @param $destinationDir The existing destination directory.
1650+ : @return The empty sequence.
1651+ :)
1652+declare %private %an:nondeterministic %an:sequential
1653+function file:copy-directory( $sourceDir as xs:string,
1654+ $destinationDir as xs:string )
1655+ as empty-sequence()
1656+{
1657+ let $name := file:base-name($sourceDir)
1658+ let $destDir := fn:concat($destinationDir, file:directory-separator(), $name)
1659+ return
1660+ {
1661+ file:create-directory($destDir);
1662+
1663+ for $item in file:list($sourceDir)
1664+ let $fullSrcPath := fn:concat($sourceDir, file:directory-separator(), $item)
1665+ let $fullDestPath := fn:concat($destDir, file:directory-separator(), $item)
1666+ return
1667+ if (file:is-directory($fullSrcPath)) then
1668+ file:copy-directory($fullSrcPath, $fullDestPath)
1669+ else
1670+ file:copy($fullSrcPath, $fullDestPath)
1671+ }
1672+};
1673+
1674+(:~
1675+ : Copies the content of a given directory to an existing destination
1676 : directory.
1677 :
1678- : No path existence check is made.
1679- :
1680- : @param $path The path to transform.
1681- : @return The file URI corresponding to <pre>path</pre>.
1682- :)
1683-declare function file:path-to-uri(
1684- $path as xs:string
1685-) as xs:anyURI external;
1686-
1687-(:~
1688- : Transforms a URI, an absolute path, or relative path to a native path on the
1689- : running platform.
1690- :
1691- : No path existence check is made.
1692- :
1693- : @param $path The uri or path to normalize.
1694- : @return The native path corresponding to <pre>$path</pre>.
1695- : @error file:FOFL9999 If an error occurs while trying to obtain the native path.
1696- :)
1697-declare function file:path-to-native($path as xs:string) as xs:string external;
1698-
1699-(:~
1700- : Returns the last component from the <pre>$path</pre>, deleting any
1701- : trailing directory-separator characters. If <pre>$path</pre> consists
1702- : entirely directory-separator characters, the empty string is returned. If
1703- : <pre>$path</pre> is the empty string, the string <pre>"."</pre> is returned,
1704- : signifying the current directory.
1705- :
1706- : No path existence check is made.
1707- :
1708- : @param $path A file path/URI.
1709- : @return The base name of this file.
1710- :)
1711-declare function file:base-name($path as xs:string) as xs:string external;
1712-
1713-(:~
1714- : Returns the last component from the <pre>$path</pre>, deleting any
1715- : trailing directory-separator characters and the <pre>$suffix</pre>. If path
1716- : consists entirely directory-separator characters, the empty string is
1717- : returned. If path is the empty string, the string <pre>"."</pre> is
1718- : returned, signifying the current directory.
1719- :
1720- : No path existence check is made.
1721- :
1722- : The <pre>$suffix</pre> can be used for example to eliminate file extensions.
1723- :
1724- : @param $path A file path/URI.
1725- : @param $suffix A suffix which should get deleted from the result.
1726- : @return The base-name of $path with a deleted $suffix.
1727- :)
1728-declare function file:base-name($path as xs:string, $suffix as xs:string)
1729- as xs:string
1730-{
1731- let $res := file:base-name($path)
1732+ : @param $sourceDir The path/URI of the directory to copy the content from.
1733+ : @param $destination The destination directory path/URI.
1734+ : @return The empty sequence.
1735+ : @error file:FOFL0001 If the <pre>$source</pre> path does not exist.
1736+ : @error file:FOFL0003 If <pre>$destination</pre> directory does not exist.
1737+ : @error file:FOFL9999 If any other error occurs.
1738+ :)
1739+declare %private %an:nondeterministic %an:sequential
1740+function file:copy-directory-content( $sourceDir as xs:string,
1741+ $destination as xs:string )
1742+ as empty-sequence()
1743+{
1744+ if (file:is-directory($destination)) then
1745+ for $item in file:list($sourceDir)
1746+ let $fullPath := fn:concat($sourceDir, file:directory-separator(), $item)
1747+ return
1748+ file:copy($fullPath, $destination)
1749+ else
1750+ fn:error(xs:QName("file:FOFL0003"), fn:concat("The specified destination directory does not exist: ", $destination))
1751+};
1752+
1753+(:~
1754+ : Deletes a file from the file system.
1755+ :
1756+ : @param $file The path/URI of the file to delete.
1757+ : @return The empty sequence.
1758+ : @error file:FOFL0001 If the <pre>$file</pre> path does not exist.
1759+ : @error file:FOFL9999 If any other error occurs.
1760+ :)
1761+declare %private %an:sequential
1762+function file:delete-file-impl( $file as xs:string )
1763+ as empty-sequence() external;
1764+
1765+(:~
1766+ : Deletes a directory from the file system.
1767+ :
1768+ : @param $dir The path/URI of the directory to delete.
1769+ : @return The empty sequence.
1770+ : @error file:FOFL0001 If the <pre>$dir</pre> path does not exist.
1771+ : @error file:FOFL0003 If <pre>$dir</pre> does not point to a directory.
1772+ : @error file:FOFL9999 If any other error occurs.
1773+ :)
1774+declare %private %an:nondeterministic %an:sequential
1775+function file:delete-directory-impl( $dir as xs:string )
1776+ as empty-sequence()
1777+{
1778+ for $item in file:list($dir)
1779+ let $fullPath := fn:concat($dir, file:directory-separator(), $item)
1780 return
1781- if (fn:ends-with($res, $suffix) and $res ne ".") then
1782- fn:substring($res, 1, fn:string-length($res) - fn:string-length($suffix))
1783+ if (file:is-directory($fullPath)) then
1784+ file:delete-directory-impl($fullPath);
1785 else
1786- $res
1787+ file:delete-file-impl($fullPath);
1788+
1789+ file:delete-file-impl($dir)
1790 };
1791
1792-(:~
1793- : This function is the converse of <pre>file:base-name</pre>. It returns a
1794- : string denoting the parent directory of the <pre>$path</pre>. Any trailing
1795- : directory-separator characters are not counted as part of the directory
1796- : name. If path is the empty string or contains no directory-separator string,
1797- : <pre>"."</pre> is returned, signifying the current directory.
1798- :
1799- : No path existence check is made.
1800- :
1801- : @param $path The filename, of which the dirname should be get.
1802- : @return The name of the directory the file is in.
1803- :)
1804-declare function file:dir-name($path as xs:string) as xs:string external;
1805-
1806 (: vim:set et sw=2 ts=2: :)
1807
1808=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
1809--- modules/org/expath/ns/file.xq.src/file.cpp 2013-08-05 11:54:06 +0000
1810+++ modules/org/expath/ns/file.xq.src/file.cpp 2013-08-06 14:19:26 +0000
1811@@ -38,10 +38,31 @@
1812 namespace zorba {
1813 namespace filemodule {
1814
1815-//*****************************************************************************
1816-
1817-BaseNameFunction::BaseNameFunction(const FileModule* aModule)
1818- : FileFunction(aModule)
1819+///////////////////////////////////////////////////////////////////////////////
1820+
1821+AppendTextFunction::AppendTextFunction( FileModule const *m ) :
1822+ WriteTextFunctionImpl( m, "append-text", true, false )
1823+{
1824+}
1825+
1826+///////////////////////////////////////////////////////////////////////////////
1827+
1828+AppendTextLinesFunction::AppendTextLinesFunction( FileModule const *m ) :
1829+ WriteTextFunctionImpl( m, "append-text-lines", true, true )
1830+{
1831+}
1832+
1833+///////////////////////////////////////////////////////////////////////////////
1834+
1835+AppendBinaryFunction::AppendBinaryFunction( FileModule const *m ) :
1836+ WriteBinaryFunctionImpl( m, "append-binary", true )
1837+{
1838+}
1839+
1840+///////////////////////////////////////////////////////////////////////////////
1841+
1842+BaseNameFunction::BaseNameFunction( FileModule const *m ) :
1843+ FileFunction( m, "base-name" )
1844 {
1845 }
1846
1847@@ -55,14 +76,63 @@
1848 while ( path.size() > 1 && path[ path.size() - 1 ] == fs::dir_separator )
1849 path.erase( path.size() - 1 );
1850 String const base_name( fs::base_name( path ) );
1851- Item item( theModule->getItemFactory()->createString( base_name ) );
1852+ Item item( module_->getItemFactory()->createString( base_name ) );
1853 return ItemSequence_t( new SingletonItemSequence( item ) );
1854 }
1855
1856-//*****************************************************************************
1857-
1858-CreateDirectoryFunction::CreateDirectoryFunction(const FileModule* aModule)
1859- : FileFunction(aModule)
1860+///////////////////////////////////////////////////////////////////////////////
1861+
1862+CopyFileImplFunction::CopyFileImplFunction( FileModule const *m ) :
1863+ FileFunction( m, "copy-file-impl" )
1864+{
1865+}
1866+
1867+ItemSequence_t
1868+CopyFileImplFunction::evaluate(
1869+ ExternalFunction::Arguments_t const &args,
1870+ StaticContext const*,
1871+ DynamicContext const* ) const
1872+{
1873+ String const src_path( getPathArg( args, 0 ) );
1874+ String dst_path( getPathArg( args, 1 ) );
1875+
1876+ fs::type const src_type = fs::get_type( src_path );
1877+ if ( !src_type )
1878+ raiseFileError( "FOFL0001", "file not found", src_path );
1879+ if ( src_type != fs::file )
1880+ raiseFileError( "FOFL0004", "not a plain file", src_path );
1881+
1882+ fs::type dst_type = fs::get_type( dst_path );
1883+ if ( dst_type == fs::directory ) { // we are copying into a directory
1884+ fs::append( dst_path, fs::base_name( src_path ) );
1885+ dst_type = fs::get_type( dst_path );
1886+ if ( dst_type == fs::directory )
1887+ raiseFileError( "FOFL0002", "path already exists", dst_path );
1888+ }
1889+
1890+ if ( src_path == dst_path )
1891+ raiseFileError( "FOFL9999", "source and destination paths must not be equal", src_path );
1892+
1893+ try {
1894+ std::ifstream fin( src_path.c_str(), std::ios_base::binary );
1895+ std::ofstream fout( dst_path.c_str(), std::ios_base::binary | std::ios_base::trunc );
1896+ char buf[ 8192 ];
1897+ while ( !fin.eof() ) {
1898+ fin.read( buf, sizeof buf );
1899+ fout.write( buf, fin.gcount() );
1900+ }
1901+ }
1902+ catch ( std::exception const &e ) {
1903+ throw raiseFileError( "FOFL9999", e.what(), src_path );
1904+ }
1905+
1906+ return ItemSequence_t( new EmptySequence() );
1907+}
1908+
1909+///////////////////////////////////////////////////////////////////////////////
1910+
1911+CreateDirectoryFunction::CreateDirectoryFunction( FileModule const *m ) :
1912+ FileFunction( m, "create-directory" )
1913 {
1914 }
1915
1916@@ -75,31 +145,25 @@
1917 String const path( getPathArg( args, 0 ) );
1918
1919 fs::type const fs_type = fs::get_type( path );
1920- if ( !fs_type )
1921- {
1922+ if ( !fs_type ) {
1923 try {
1924 fs::mkdir( path, true );
1925 }
1926 catch ( std::exception const &e ) {
1927 throw raiseFileError( "FOFL9999", e.what(), path );
1928 }
1929- }
1930- else if ( fs_type != fs::directory )
1931- {
1932+ } else if ( fs_type != fs::directory )
1933 raiseFileError( "FOFL0002", "file already exists", path );
1934- }
1935 else
1936- {
1937 /* directory already exists: do nothing */;
1938- }
1939
1940 return ItemSequence_t( new EmptySequence() );
1941 }
1942
1943-//*****************************************************************************
1944+///////////////////////////////////////////////////////////////////////////////
1945
1946-DeleteFileImplFunction::DeleteFileImplFunction(const FileModule* aModule) :
1947- FileFunction(aModule)
1948+DeleteFileImplFunction::DeleteFileImplFunction( FileModule const *m ) :
1949+ FileFunction( m, "delete-file-impl" )
1950 {
1951 }
1952
1953@@ -124,10 +188,31 @@
1954 return ItemSequence_t( new EmptySequence() );
1955 }
1956
1957-//*****************************************************************************
1958-
1959-DirNameFunction::DirNameFunction(const FileModule* aModule)
1960- : FileFunction(aModule)
1961+///////////////////////////////////////////////////////////////////////////////
1962+
1963+DirectorySeparator::DirectorySeparator( FileModule const *m ) :
1964+ FileFunction( m, "directory-separator" )
1965+{
1966+}
1967+
1968+ItemSequence_t
1969+DirectorySeparator::evaluate(
1970+ ExternalFunction::Arguments_t const &args,
1971+ StaticContext const*,
1972+ DynamicContext const* ) const
1973+{
1974+ String const dir_separator( 1, fs::dir_separator );
1975+ return ItemSequence_t(
1976+ new SingletonItemSequence(
1977+ module_->getItemFactory()->createString( dir_separator )
1978+ )
1979+ );
1980+}
1981+
1982+///////////////////////////////////////////////////////////////////////////////
1983+
1984+DirNameFunction::DirNameFunction( FileModule const *m ) :
1985+ FileFunction( m, "dir-name" )
1986 {
1987 }
1988
1989@@ -141,14 +226,235 @@
1990 while ( path.size() > 1 && path[ path.size() - 1 ] == fs::dir_separator )
1991 path.erase( path.size() - 1 );
1992 String const dir_name( fs::dir_name( path ) );
1993- Item item( theModule->getItemFactory()->createString( dir_name ) );
1994+ Item item( module_->getItemFactory()->createString( dir_name ) );
1995 return ItemSequence_t( new SingletonItemSequence( item ) );
1996 }
1997
1998-//*****************************************************************************
1999-
2000-ReadBinaryFunction::ReadBinaryFunction( FileModule const *aModule ) :
2001- FileFunction( aModule )
2002+///////////////////////////////////////////////////////////////////////////////
2003+
2004+ExistsFunction::ExistsFunction( FileModule const *m ) :
2005+ FileFunction( m, "exists" )
2006+{
2007+}
2008+
2009+ItemSequence_t
2010+ExistsFunction::evaluate(
2011+ ExternalFunction::Arguments_t const &args,
2012+ StaticContext const*,
2013+ DynamicContext const* ) const
2014+{
2015+ String const path = getPathArg( args, 0 );
2016+ bool const follow_symlink = getItem( args, 1 ).getBooleanValue();
2017+ bool const exists = !!fs::get_type( path, follow_symlink );
2018+ return ItemSequence_t(
2019+ new SingletonItemSequence(
2020+ module_->getItemFactory()->createBoolean( exists )
2021+ )
2022+ );
2023+}
2024+
2025+///////////////////////////////////////////////////////////////////////////////
2026+
2027+IsDirectoryFunction::IsDirectoryFunction( FileModule const *m ) :
2028+ FileFunction( m, "is-directory" )
2029+{
2030+}
2031+
2032+ItemSequence_t
2033+IsDirectoryFunction::evaluate(
2034+ ExternalFunction::Arguments_t const &args,
2035+ StaticContext const*,
2036+ DynamicContext const* ) const
2037+{
2038+ String const path( getPathArg( args, 0 ) );
2039+ bool const is_directory = fs::get_type( path ) == fs::directory;
2040+ return ItemSequence_t(
2041+ new SingletonItemSequence(
2042+ module_->getItemFactory()->createBoolean( is_directory )
2043+ )
2044+ );
2045+}
2046+
2047+///////////////////////////////////////////////////////////////////////////////
2048+
2049+IsFileFunction::IsFileFunction( FileModule const *m ) :
2050+ FileFunction( m, "is-file" )
2051+{
2052+}
2053+
2054+ItemSequence_t
2055+IsFileFunction::evaluate(
2056+ ExternalFunction::Arguments_t const &args,
2057+ StaticContext const*,
2058+ DynamicContext const* ) const
2059+{
2060+ String const path( getPathArg( args, 0 ) );
2061+ bool const is_file = fs::get_type( path ) == fs::file;
2062+ return ItemSequence_t(
2063+ new SingletonItemSequence(
2064+ module_->getItemFactory()->createBoolean( is_file )
2065+ )
2066+ );
2067+}
2068+
2069+///////////////////////////////////////////////////////////////////////////////
2070+
2071+IsSymlinkFunction::IsSymlinkFunction( FileModule const *m ) :
2072+ FileFunction( m, "is-symlink" )
2073+{
2074+}
2075+
2076+ItemSequence_t
2077+IsSymlinkFunction::evaluate(
2078+ ExternalFunction::Arguments_t const &args,
2079+ StaticContext const*,
2080+ DynamicContext const* ) const
2081+{
2082+ String const path( getPathArg( args, 0 ) );
2083+ bool const is_symlink = fs::get_type( path, false ) == fs::link;
2084+ return ItemSequence_t(
2085+ new SingletonItemSequence(
2086+ module_->getItemFactory()->createBoolean( is_symlink )
2087+ )
2088+ );
2089+}
2090+
2091+///////////////////////////////////////////////////////////////////////////////
2092+
2093+LastModifiedFunction::LastModifiedFunction( FileModule const *m ) :
2094+ FileFunction( m, "last-modified" )
2095+{
2096+}
2097+
2098+ItemSequence_t
2099+LastModifiedFunction::evaluate(
2100+ ExternalFunction::Arguments_t const &args,
2101+ StaticContext const*,
2102+ DynamicContext const* ) const
2103+{
2104+ String const path( getPathArg( args, 0 ) );
2105+
2106+ fs::info info;
2107+ if ( !fs::get_type( path, &info ) )
2108+ raiseFileError( "FOFL0001", "file not found", path );
2109+
2110+ try {
2111+ time_t lTime = info.mtime;
2112+ // result of localtime needs to be copied.
2113+ // Otherwise, nasty side effecs do happen
2114+ struct tm lT( *localtime( &lTime ) );
2115+ int gmtOffset = LastModifiedFunction::getGmtOffset();
2116+
2117+ return ItemSequence_t(
2118+ new SingletonItemSequence(
2119+ module_->getItemFactory()->createDateTime(
2120+ 1900 + lT.tm_year,
2121+ lT.tm_mon,
2122+ lT.tm_mday,
2123+ lT.tm_hour,
2124+ lT.tm_min,
2125+ lT.tm_sec,
2126+ gmtOffset
2127+ )
2128+ )
2129+ );
2130+ }
2131+ catch ( std::exception const &e ) {
2132+ throw raiseFileError( "FOFL9999", e.what(), path );
2133+ }
2134+}
2135+
2136+int
2137+LastModifiedFunction::getGmtOffset()
2138+{
2139+ time_t t = ::time(0);
2140+ struct tm* data;
2141+ data = localtime(&t);
2142+ data->tm_isdst = 0;
2143+ time_t a = mktime(data);
2144+ data = gmtime(&t);
2145+ data->tm_isdst = 0;
2146+ time_t b = mktime(data);
2147+ return (int)(a - b)/3600;
2148+}
2149+
2150+///////////////////////////////////////////////////////////////////////////////
2151+
2152+ListFunction::ListFunction( FileModule const *m ) :
2153+ FileFunction( m, "list" )
2154+{
2155+}
2156+
2157+ItemSequence_t
2158+ListFunction::evaluate(
2159+ ExternalFunction::Arguments_t const &args,
2160+ StaticContext const*,
2161+ DynamicContext const* ) const
2162+{
2163+ String const path( getPathArg( args, 0 ) );
2164+
2165+ if ( fs::get_type( path ) != fs::directory )
2166+ raiseFileError( "FOFL0003", "path is not a directory", path );
2167+
2168+ try {
2169+ return ItemSequence_t(
2170+ new IteratorBackedItemSequence( path, module_->getItemFactory() )
2171+ );
2172+ }
2173+ catch ( std::exception const &e ) {
2174+ throw raiseFileError( "FOFL9999", e.what(), path );
2175+ }
2176+}
2177+
2178+ListFunction::IteratorBackedItemSequence::IteratorBackedItemSequence(
2179+ String const& path,
2180+ ItemFactory* aFactory
2181+) :
2182+ theIterator( path ),
2183+ theItemFactory( aFactory )
2184+{
2185+ is_open = false;
2186+ open_count = 0;
2187+}
2188+
2189+Iterator_t ListFunction::IteratorBackedItemSequence::getIterator()
2190+{
2191+ return this;
2192+}
2193+
2194+void ListFunction::IteratorBackedItemSequence::open()
2195+{
2196+ if (open_count) {
2197+ theIterator.reset();
2198+ }
2199+ open_count++;
2200+ is_open = true;
2201+}
2202+
2203+void ListFunction::IteratorBackedItemSequence::close()
2204+{
2205+ is_open = false;
2206+}
2207+
2208+bool ListFunction::IteratorBackedItemSequence::isOpen() const
2209+{
2210+ return is_open;
2211+}
2212+
2213+bool
2214+ListFunction::IteratorBackedItemSequence::next(Item& lItem)
2215+{
2216+ if ( !theIterator.next() )
2217+ return false;
2218+ String const lUriStr( theIterator->name );
2219+ lItem = theItemFactory->createString( lUriStr );
2220+ return true;
2221+}
2222+
2223+///////////////////////////////////////////////////////////////////////////////
2224+
2225+ReadBinaryFunction::ReadBinaryFunction( FileModule const *m ) :
2226+ FileFunction( m, "read-binary" )
2227 {
2228 }
2229
2230@@ -170,7 +476,7 @@
2231 std::unique_ptr<std::ifstream> pin(
2232 new std::ifstream( path.c_str(), std::ios_base::binary )
2233 );
2234- Item item = theModule->getItemFactory()->createStreamableBase64Binary(
2235+ Item item = module_->getItemFactory()->createStreamableBase64Binary(
2236 *pin, &FileModule::streamReleaser, true
2237 );
2238 pin.release();
2239@@ -181,10 +487,10 @@
2240 }
2241 }
2242
2243-//*****************************************************************************
2244+///////////////////////////////////////////////////////////////////////////////
2245
2246-ReadTextFunction::ReadTextFunction(const FileModule* aModule)
2247- : StreamableFileFunction(aModule)
2248+ReadTextFunction::ReadTextFunction( FileModule const *m ) :
2249+ FileFunction( m, "read-text" )
2250 {
2251 }
2252
2253@@ -221,7 +527,7 @@
2254
2255 pin->open( path.c_str() );
2256 skip_utf8_bom( *pin );
2257- lResult = theModule->getItemFactory()->createStreamableString(
2258+ lResult = module_->getItemFactory()->createStreamableString(
2259 *pin, &FileModule::streamReleaser, path.c_str(), true
2260 );
2261 pin.release();
2262@@ -229,10 +535,10 @@
2263 return ItemSequence_t( new SingletonItemSequence( lResult ) );
2264 }
2265
2266-//*****************************************************************************
2267+///////////////////////////////////////////////////////////////////////////////
2268
2269-ReadTextLinesFunction::ReadTextLinesFunction(const FileModule* aModule)
2270- : FileFunction(aModule)
2271+ReadTextLinesFunction::ReadTextLinesFunction( FileModule const *m ) :
2272+ FileFunction( m, "read-text-lines" )
2273 {
2274 }
2275
2276@@ -285,14 +591,11 @@
2277 {
2278 }
2279
2280-ReadTextLinesFunction::LinesItemSequence::LinesIterator::~LinesIterator()
2281-{
2282+ReadTextLinesFunction::LinesItemSequence::LinesIterator::~LinesIterator() {
2283 delete theStream;
2284 }
2285
2286-void
2287-ReadTextLinesFunction::LinesItemSequence::LinesIterator::open()
2288-{
2289+void ReadTextLinesFunction::LinesItemSequence::LinesIterator::open() {
2290 if ( transcode::is_necessary( theEncoding.c_str() ) ) {
2291 try {
2292 theStream = new transcode::stream<std::ifstream>( theEncoding.c_str() );
2293@@ -307,8 +610,7 @@
2294 }
2295
2296 bool
2297-ReadTextLinesFunction::LinesItemSequence::LinesIterator::next(Item& aRes)
2298-{
2299+ReadTextLinesFunction::LinesItemSequence::LinesIterator::next(Item& aRes) {
2300 if ( !theStream || !theStream->good() )
2301 return false;
2302
2303@@ -317,7 +619,7 @@
2304 if ( theStream->bad() )
2305 return false;
2306
2307- aRes = theFunc->theModule->getItemFactory()->createString( s );
2308+ aRes = theFunc->module_->getItemFactory()->createString( s );
2309 return true;
2310 }
2311
2312@@ -331,312 +633,13 @@
2313 bool
2314 ReadTextLinesFunction::LinesItemSequence::LinesIterator::isOpen() const
2315 {
2316- return theStream != 0;
2317-}
2318-
2319-//*****************************************************************************
2320-
2321-ExistsFunction::ExistsFunction(const FileModule* aModule) :
2322- FileFunction( aModule )
2323-{
2324-}
2325-
2326-ItemSequence_t
2327-ExistsFunction::evaluate(
2328- ExternalFunction::Arguments_t const &args,
2329- StaticContext const*,
2330- DynamicContext const* ) const
2331-{
2332- String const path = getPathArg( args, 0 );
2333- bool const follow_symlink = getItem( args, 1 ).getBooleanValue();
2334- bool const exists = !!fs::get_type( path, follow_symlink );
2335- return ItemSequence_t(
2336- new SingletonItemSequence(
2337- theModule->getItemFactory()->createBoolean( exists )
2338- )
2339- );
2340-}
2341-
2342-//*****************************************************************************
2343-
2344-IsDirectoryFunction::IsDirectoryFunction( FileModule const *aModule ) :
2345- FileFunction( aModule )
2346-{
2347-}
2348-
2349-ItemSequence_t
2350-IsDirectoryFunction::evaluate(
2351- ExternalFunction::Arguments_t const &args,
2352- StaticContext const*,
2353- DynamicContext const* ) const
2354-{
2355- String const path( getPathArg( args, 0 ) );
2356- bool const is_directory = fs::get_type( path ) == fs::directory;
2357- return ItemSequence_t(
2358- new SingletonItemSequence(
2359- theModule->getItemFactory()->createBoolean( is_directory )
2360- )
2361- );
2362-}
2363-
2364-//*****************************************************************************
2365-
2366-IsFileFunction::IsFileFunction( FileModule const *aModule ) :
2367- FileFunction( aModule )
2368-{
2369-}
2370-
2371-ItemSequence_t
2372-IsFileFunction::evaluate(
2373- ExternalFunction::Arguments_t const &args,
2374- StaticContext const*,
2375- DynamicContext const* ) const
2376-{
2377- String const path( getPathArg( args, 0 ) );
2378- bool const is_file = fs::get_type( path ) == fs::file;
2379- return ItemSequence_t(
2380- new SingletonItemSequence(
2381- theModule->getItemFactory()->createBoolean( is_file )
2382- )
2383- );
2384-}
2385-
2386-//*****************************************************************************
2387-
2388-IsSymlinkFunction::IsSymlinkFunction( FileModule const *aModule ) :
2389- FileFunction( aModule )
2390-{
2391-}
2392-
2393-ItemSequence_t
2394-IsSymlinkFunction::evaluate(
2395- ExternalFunction::Arguments_t const &args,
2396- StaticContext const*,
2397- DynamicContext const* ) const
2398-{
2399- String const path( getPathArg( args, 0 ) );
2400- bool const is_symlink = fs::get_type( path, false ) == fs::link;
2401- return ItemSequence_t(
2402- new SingletonItemSequence(
2403- theModule->getItemFactory()->createBoolean( is_symlink )
2404- )
2405- );
2406-}
2407-
2408-//*****************************************************************************
2409-
2410-CopyFileImplFunction::CopyFileImplFunction( FileModule const *aModule ) :
2411- FileFunction( aModule )
2412-{
2413-}
2414-
2415-ItemSequence_t
2416-CopyFileImplFunction::evaluate(
2417- ExternalFunction::Arguments_t const &args,
2418- StaticContext const*,
2419- DynamicContext const* ) const
2420-{
2421- String const src_path( getPathArg( args, 0 ) );
2422- String dst_path( getPathArg( args, 1 ) );
2423-
2424- fs::type const src_type = fs::get_type( src_path );
2425- if ( !src_type )
2426- raiseFileError( "FOFL0001", "file not found", src_path );
2427- if ( src_type != fs::file )
2428- raiseFileError( "FOFL0004", "not a plain file", src_path );
2429-
2430- fs::type dst_type = fs::get_type( dst_path );
2431- if ( dst_type == fs::directory ) { // we are copying into a directory
2432- fs::append( dst_path, fs::base_name( src_path ) );
2433- dst_type = fs::get_type( dst_path );
2434- if ( dst_type == fs::directory )
2435- raiseFileError( "FOFL0002", "path already exists", dst_path );
2436- }
2437-
2438- if ( src_path == dst_path )
2439- raiseFileError( "FOFL9999", "source and destination paths must not be equal", src_path );
2440-
2441- try {
2442- std::ifstream fin( src_path.c_str(), std::ios_base::binary );
2443- std::ofstream fout( dst_path.c_str(), std::ios_base::binary | std::ios_base::trunc );
2444- char buf[ 8192 ];
2445- while ( !fin.eof() ) {
2446- fin.read( buf, sizeof buf );
2447- fout.write( buf, fin.gcount() );
2448- }
2449- }
2450- catch ( std::exception const &e ) {
2451- throw raiseFileError( "FOFL9999", e.what(), src_path );
2452- }
2453-
2454- return ItemSequence_t( new EmptySequence() );
2455-}
2456-
2457-//*****************************************************************************
2458-
2459-ListFunction::ListFunction( FileModule const *aModule ) :
2460- FileFunction( aModule )
2461-{
2462-}
2463-
2464-ItemSequence_t
2465-ListFunction::evaluate(
2466- ExternalFunction::Arguments_t const &args,
2467- StaticContext const*,
2468- DynamicContext const* ) const
2469-{
2470- String const path( getPathArg( args, 0 ) );
2471-
2472- if ( fs::get_type( path ) != fs::directory )
2473- raiseFileError( "FOFL0003", "path is not a directory", path );
2474-
2475- try {
2476- return ItemSequence_t(
2477- new IteratorBackedItemSequence( path, theModule->getItemFactory() )
2478- );
2479- }
2480- catch ( std::exception const &e ) {
2481- throw raiseFileError( "FOFL9999", e.what(), path );
2482- }
2483-}
2484-
2485-ListFunction::IteratorBackedItemSequence::IteratorBackedItemSequence(
2486- String const& path,
2487- ItemFactory* aFactory
2488-) :
2489- theIterator( path ),
2490- theItemFactory( aFactory )
2491-{
2492- is_open = false;
2493- open_count = 0;
2494-}
2495-
2496-ListFunction::IteratorBackedItemSequence::~IteratorBackedItemSequence()
2497-{
2498-}
2499-
2500-Iterator_t ListFunction::IteratorBackedItemSequence::getIterator()
2501-{
2502- return this;
2503-}
2504-
2505-void ListFunction::IteratorBackedItemSequence::open()
2506-{
2507- if (open_count) {
2508- theIterator.reset();
2509- }
2510- open_count++;
2511- is_open = true;
2512-}
2513-
2514-void ListFunction::IteratorBackedItemSequence::close()
2515-{
2516- is_open = false;
2517-}
2518-
2519-bool ListFunction::IteratorBackedItemSequence::isOpen() const
2520-{
2521- return is_open;
2522-}
2523-
2524-bool
2525-ListFunction::IteratorBackedItemSequence::next(Item& lItem)
2526-{
2527- if ( !theIterator.next() )
2528- return false;
2529- String const lUriStr( theIterator->name );
2530- lItem = theItemFactory->createString( lUriStr );
2531- return true;
2532-}
2533-
2534-//*****************************************************************************
2535-
2536-LastModifiedFunction::LastModifiedFunction(const FileModule* aModule) :
2537- FileFunction(aModule)
2538-{
2539-}
2540-
2541-ItemSequence_t
2542-LastModifiedFunction::evaluate(
2543- ExternalFunction::Arguments_t const &args,
2544- StaticContext const*,
2545- DynamicContext const* ) const
2546-{
2547- String const path( getPathArg( args, 0 ) );
2548-
2549- fs::info info;
2550- if ( !fs::get_type( path, &info ) )
2551- raiseFileError( "FOFL0001", "file not found", path );
2552-
2553- try {
2554- time_t lTime = info.mtime;
2555- // result of localtime needs to be copied.
2556- // Otherwise, nasty side effecs do happen
2557- struct tm lT(*localtime(&lTime));
2558- int gmtOffset = LastModifiedFunction::getGmtOffset();
2559-
2560- return ItemSequence_t(
2561- new SingletonItemSequence(
2562- theModule->getItemFactory()->createDateTime(
2563- 1900 + lT.tm_year,
2564- lT.tm_mon,
2565- lT.tm_mday,
2566- lT.tm_hour,
2567- lT.tm_min,
2568- lT.tm_sec,
2569- gmtOffset
2570- )
2571- )
2572- );
2573- }
2574- catch ( std::exception const &e ) {
2575- throw raiseFileError( "FOFL9999", e.what(), path );
2576- }
2577-}
2578-
2579-int
2580-LastModifiedFunction::getGmtOffset()
2581-{
2582- time_t t = ::time(0);
2583- struct tm* data;
2584- data = localtime(&t);
2585- data->tm_isdst = 0;
2586- time_t a = mktime(data);
2587- data = gmtime(&t);
2588- data->tm_isdst = 0;
2589- time_t b = mktime(data);
2590- return (int)(a - b)/3600;
2591-}
2592-
2593-//*****************************************************************************
2594-
2595-SizeFunction::SizeFunction(const FileModule* aModule)
2596- : FileFunction(aModule)
2597-{
2598-}
2599-
2600-ItemSequence_t
2601-SizeFunction::evaluate(
2602- ExternalFunction::Arguments_t const &args,
2603- StaticContext const*,
2604- DynamicContext const* ) const
2605-{
2606- String const path( getPathArg( args, 0 ) );
2607-
2608- fs::info info;
2609- if ( !fs::get_type( path, &info ) )
2610- raiseFileError( "FOFL0001", "file not found", path );
2611- if ( info.type != fs::file )
2612- raiseFileError( "FOFL0004", "not plain file", path );
2613-
2614- return ItemSequence_t(new SingletonItemSequence(
2615- theModule->getItemFactory()->createInteger(info.size)));
2616-}
2617-
2618-//*****************************************************************************
2619-
2620-PathSeparator::PathSeparator(const FileModule* aModule)
2621- : FileFunction(aModule)
2622+ return !!theStream;
2623+}
2624+
2625+///////////////////////////////////////////////////////////////////////////////
2626+
2627+PathSeparator::PathSeparator( FileModule const *m ) :
2628+ FileFunction( m, "path-separator" )
2629 {
2630 }
2631
2632@@ -649,58 +652,15 @@
2633 String const path_separator( 1, fs::path_separator );
2634 return ItemSequence_t(
2635 new SingletonItemSequence(
2636- theModule->getItemFactory()->createString( path_separator )
2637- )
2638- );
2639-}
2640-
2641-//*****************************************************************************
2642-
2643-DirectorySeparator::DirectorySeparator(const FileModule* aModule)
2644- : FileFunction(aModule)
2645-{
2646-}
2647-
2648-ItemSequence_t
2649-DirectorySeparator::evaluate(
2650- ExternalFunction::Arguments_t const &args,
2651- StaticContext const*,
2652- DynamicContext const* ) const
2653-{
2654- String const dir_separator( 1, fs::dir_separator );
2655- return ItemSequence_t(
2656- new SingletonItemSequence(
2657- theModule->getItemFactory()->createString( dir_separator )
2658- )
2659- );
2660-}
2661-
2662-//*****************************************************************************
2663-
2664-ResolvePathFunction::ResolvePathFunction(const FileModule* aModule)
2665- : FileFunction(aModule)
2666-{
2667-}
2668-
2669-ItemSequence_t
2670-ResolvePathFunction::evaluate(
2671- ExternalFunction::Arguments_t const &args,
2672- StaticContext const*,
2673- DynamicContext const* ) const
2674-{
2675- String const path( getPathArg( args, 0 ) );
2676- String const result( pathToOSPath( path ) );
2677- return ItemSequence_t(
2678- new SingletonItemSequence(
2679- theModule->getItemFactory()->createString( result )
2680- )
2681- );
2682-}
2683-
2684-//*****************************************************************************
2685-
2686-PathToNativeFunction::PathToNativeFunction(const FileModule* aModule)
2687- : FileFunction(aModule)
2688+ module_->getItemFactory()->createString( path_separator )
2689+ )
2690+ );
2691+}
2692+
2693+///////////////////////////////////////////////////////////////////////////////
2694+
2695+PathToNativeFunction::PathToNativeFunction( FileModule const *m ) :
2696+ FileFunction( m, "path-to-native" )
2697 {
2698 }
2699
2700@@ -715,7 +675,7 @@
2701 String const native_path( fs::normalize_path( path ) );
2702 return ItemSequence_t(
2703 new SingletonItemSequence(
2704- theModule->getItemFactory()->createString( native_path )
2705+ module_->getItemFactory()->createString( native_path )
2706 )
2707 );
2708 }
2709@@ -724,10 +684,10 @@
2710 }
2711 }
2712
2713-//*****************************************************************************
2714+///////////////////////////////////////////////////////////////////////////////
2715
2716-PathToUriFunction::PathToUriFunction(const FileModule* aModule)
2717- : FileFunction(aModule)
2718+PathToUriFunction::PathToUriFunction( FileModule const *m ) :
2719+ FileFunction( m, "path-to-uri" )
2720 {
2721 }
2722
2723@@ -741,80 +701,87 @@
2724 String const result = pathToUriString( path );
2725 return ItemSequence_t(
2726 new SingletonItemSequence(
2727- theModule->getItemFactory()->createAnyURI( result ) )
2728- );
2729-}
2730-
2731-//*****************************************************************************
2732-
2733-WriteTextFunction::WriteTextFunction(const FileModule* aModule)
2734- : WriterFileFunction(aModule)
2735-{
2736-}
2737-
2738-bool
2739-WriteTextFunction::isAppend() const {
2740- return false;
2741-}
2742-
2743-bool
2744-WriteTextFunction::isBinary() const {
2745- return false;
2746-}
2747-
2748-//*****************************************************************************
2749-
2750-WriteBinaryFunction::WriteBinaryFunction(const FileModule* aModule)
2751- : WriterFileFunction(aModule)
2752-{
2753-}
2754-
2755-bool
2756-WriteBinaryFunction::isAppend() const {
2757- return false;
2758-}
2759-
2760-bool
2761-WriteBinaryFunction::isBinary() const {
2762- return true;
2763-}
2764-
2765-//*****************************************************************************
2766-
2767-AppendTextFunction::AppendTextFunction(const FileModule* aModule)
2768- : WriterFileFunction(aModule)
2769-{
2770-}
2771-
2772-bool
2773-AppendTextFunction::isAppend() const {
2774- return true;
2775-}
2776-
2777-bool
2778-AppendTextFunction::isBinary() const {
2779- return false;
2780-}
2781-
2782-//*****************************************************************************
2783-
2784-AppendBinaryFunction::AppendBinaryFunction(const FileModule* aModule)
2785- : WriterFileFunction(aModule)
2786-{
2787-}
2788-
2789-bool
2790-AppendBinaryFunction::isAppend() const {
2791- return true;
2792-}
2793-
2794-bool
2795-AppendBinaryFunction::isBinary() const {
2796- return true;
2797-}
2798-
2799-//*****************************************************************************
2800-
2801+ module_->getItemFactory()->createAnyURI( result )
2802+ )
2803+ );
2804+}
2805+
2806+///////////////////////////////////////////////////////////////////////////////
2807+
2808+ResolvePathFunction::ResolvePathFunction( FileModule const *m ) :
2809+ FileFunction( m, "resolve-path" )
2810+{
2811+}
2812+
2813+ItemSequence_t
2814+ResolvePathFunction::evaluate(
2815+ ExternalFunction::Arguments_t const &args,
2816+ StaticContext const*,
2817+ DynamicContext const* ) const
2818+{
2819+ String const path( getPathArg( args, 0 ) );
2820+ try {
2821+ return ItemSequence_t(
2822+ new SingletonItemSequence(
2823+ module_->getItemFactory()->createString( fs::normalize_path( path ) )
2824+ )
2825+ );
2826+ }
2827+ catch ( std::invalid_argument const &e ) {
2828+ throw raiseFileError( "FOFL9999", e.what(), path );
2829+ }
2830+}
2831+
2832+///////////////////////////////////////////////////////////////////////////////
2833+
2834+SizeFunction::SizeFunction( FileModule const *m ) :
2835+ FileFunction( m, "size" )
2836+{
2837+}
2838+
2839+ItemSequence_t
2840+SizeFunction::evaluate(
2841+ ExternalFunction::Arguments_t const &args,
2842+ StaticContext const*,
2843+ DynamicContext const* ) const
2844+{
2845+ String const path( getPathArg( args, 0 ) );
2846+
2847+ fs::info info;
2848+ if ( !fs::get_type( path, &info ) )
2849+ raiseFileError( "FOFL0001", "file not found", path );
2850+ if ( info.type != fs::file )
2851+ raiseFileError( "FOFL0004", "not plain file", path );
2852+
2853+ return ItemSequence_t(
2854+ new SingletonItemSequence(
2855+ module_->getItemFactory()->createInteger( info.size )
2856+ )
2857+ );
2858+}
2859+
2860+///////////////////////////////////////////////////////////////////////////////
2861+
2862+WriteBinaryFunction::WriteBinaryFunction( FileModule const *m ) :
2863+ WriteBinaryFunctionImpl( m, "write-binary", false )
2864+{
2865+}
2866+
2867+///////////////////////////////////////////////////////////////////////////////
2868+
2869+WriteTextFunction::WriteTextFunction( FileModule const *m ) :
2870+ WriteTextFunctionImpl( m, "write-text", false, false )
2871+{
2872+}
2873+
2874+///////////////////////////////////////////////////////////////////////////////
2875+
2876+WriteTextLinesFunction::WriteTextLinesFunction( FileModule const *m ) :
2877+ WriteTextFunctionImpl( m, "write-text-lines", false, true )
2878+{
2879+}
2880+
2881+///////////////////////////////////////////////////////////////////////////////
2882
2883 } // namespace filemodule
2884 } // namespace zorba
2885
2886=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
2887--- modules/org/expath/ns/file.xq.src/file.h 2013-06-12 15:35:27 +0000
2888+++ modules/org/expath/ns/file.xq.src/file.h 2013-08-06 14:19:26 +0000
2889@@ -1,12 +1,12 @@
2890 /*
2891 * Copyright 2006-2008 The FLWOR Foundation.
2892- *
2893+ *
2894 * Licensed under the Apache License, Version 2.0 (the "License");
2895 * you may not use this file except in compliance with the License.
2896 * You may obtain a copy of the License at
2897- *
2898+ *
2899 * http://www.apache.org/licenses/LICENSE-2.0
2900- *
2901+ *
2902 * Unless required by applicable law or agreed to in writing, software
2903 * distributed under the License is distributed on an "AS IS" BASIS,
2904 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2905@@ -20,488 +20,361 @@
2906
2907 #include "file_function.h"
2908
2909-namespace zorba {
2910-
2911- class ItemFactory;
2912-
2913- namespace filemodule {
2914-
2915-//*****************************************************************************
2916-
2917- class BaseNameFunction : public FileFunction
2918- {
2919- public:
2920- BaseNameFunction(const FileModule* aModule);
2921-
2922- virtual String
2923- getLocalName() const { return "base-name"; }
2924-
2925- virtual ItemSequence_t
2926- evaluate(const ExternalFunction::Arguments_t& args,
2927- const StaticContext* aSctxCtx,
2928- const DynamicContext* aDynCtx) const;
2929- };
2930-
2931-//*****************************************************************************
2932-
2933- class CreateDirectoryFunction : public FileFunction
2934- {
2935- public:
2936- CreateDirectoryFunction(const FileModule* aModule);
2937-
2938- virtual String
2939- getLocalName() const { return "create-directory"; }
2940-
2941- virtual ItemSequence_t
2942- evaluate(const ExternalFunction::Arguments_t& args,
2943- const StaticContext* aSctxCtx,
2944- const DynamicContext* aDynCtx) const;
2945- };
2946-
2947-//*****************************************************************************
2948-
2949- class DeleteFileImplFunction : public FileFunction
2950- {
2951- public:
2952- DeleteFileImplFunction(const FileModule* aModule);
2953-
2954- virtual String
2955- getLocalName() const { return "delete-file-impl"; }
2956-
2957- virtual ItemSequence_t
2958- evaluate(const ExternalFunction::Arguments_t& args,
2959- const StaticContext* aSctxCtx,
2960- const DynamicContext* aDynCtx) const;
2961- };
2962-
2963-//*****************************************************************************
2964-
2965- class DirNameFunction : public FileFunction
2966- {
2967- public:
2968- DirNameFunction(const FileModule* aModule);
2969-
2970- virtual String
2971- getLocalName() const { return "dir-name"; }
2972-
2973- virtual ItemSequence_t
2974- evaluate(const ExternalFunction::Arguments_t& args,
2975- const StaticContext* aSctxCtx,
2976- const DynamicContext* aDynCtx) const;
2977- };
2978-
2979-//*****************************************************************************
2980-
2981- class CopyFileImplFunction : public FileFunction
2982- {
2983- public:
2984- CopyFileImplFunction(const FileModule* aModule);
2985-
2986- virtual String
2987- getLocalName() const { return "copy-file-impl"; }
2988-
2989- virtual ItemSequence_t
2990- evaluate(const ExternalFunction::Arguments_t& args,
2991- const StaticContext* aSctxCtx,
2992- const DynamicContext* aDynCtx) const;
2993- };
2994-
2995-//*****************************************************************************
2996-
2997- class ExistsFunction : public FileFunction
2998- {
2999- public:
3000- ExistsFunction(const FileModule* aModule);
3001-
3002- virtual String
3003- getLocalName() const { return "exists"; }
3004-
3005- virtual ItemSequence_t
3006- evaluate(const ExternalFunction::Arguments_t& args,
3007- const StaticContext* aSctxCtx,
3008- const DynamicContext* aDynCtx) const;
3009- };
3010-
3011-//*****************************************************************************
3012-
3013- class ListFunction : public FileFunction
3014- {
3015- public:
3016- ListFunction(const FileModule* aModule);
3017-
3018- virtual String
3019- getLocalName() const { return "list"; }
3020-
3021- virtual ItemSequence_t
3022- evaluate(const ExternalFunction::Arguments_t& args,
3023- const StaticContext* aSctxCtx,
3024- const DynamicContext* aDynCtx) const;
3025- private:
3026- class IteratorBackedItemSequence : public ItemSequence , public Iterator{
3027-
3028- public:
3029- IteratorBackedItemSequence(
3030- String const& path,
3031- zorba::ItemFactory* aFactory);
3032-
3033- virtual ~IteratorBackedItemSequence();
3034-
3035- //ItemSequence interface
3036- Iterator_t getIterator();
3037-
3038- //Iterator interface
3039- virtual void open();
3040- virtual bool next(Item& aItem);
3041- virtual void close();
3042- virtual bool isOpen() const;
3043- private:
3044- bool is_open;
3045- int open_count;
3046- fs::iterator theIterator;
3047- ItemFactory* theItemFactory;
3048+namespace zorba {
3049+
3050+class ItemFactory;
3051+
3052+namespace filemodule {
3053+
3054+//*****************************************************************************
3055+
3056+class AppendTextFunction : public WriteTextFunctionImpl {
3057+public:
3058+ AppendTextFunction( FileModule const* );
3059+};
3060+
3061+//*****************************************************************************
3062+
3063+class AppendTextLinesFunction : public WriteTextFunctionImpl {
3064+public:
3065+ AppendTextLinesFunction( FileModule const* );
3066+};
3067+
3068+//*****************************************************************************
3069+
3070+class AppendBinaryFunction : public WriteBinaryFunctionImpl {
3071+public:
3072+ AppendBinaryFunction( FileModule const* );
3073+};
3074+
3075+//*****************************************************************************
3076+
3077+class BaseNameFunction : public FileFunction {
3078+public:
3079+ BaseNameFunction( FileModule const* );
3080+
3081+ virtual ItemSequence_t
3082+ evaluate( ExternalFunction::Arguments_t const&,
3083+ StaticContext const*,
3084+ DynamicContext const* ) const;
3085+};
3086+
3087+//*****************************************************************************
3088+
3089+class CopyFileImplFunction : public FileFunction {
3090+public:
3091+ CopyFileImplFunction( FileModule const* );
3092+
3093+ virtual ItemSequence_t
3094+ evaluate( ExternalFunction::Arguments_t const&,
3095+ StaticContext const*,
3096+ DynamicContext const* ) const;
3097+};
3098+
3099+//*****************************************************************************
3100+
3101+class CreateDirectoryFunction : public FileFunction {
3102+public:
3103+ CreateDirectoryFunction( FileModule const* );
3104+
3105+ virtual ItemSequence_t
3106+ evaluate( ExternalFunction::Arguments_t const&,
3107+ StaticContext const*,
3108+ DynamicContext const* ) const;
3109+};
3110+
3111+//*****************************************************************************
3112+
3113+class DeleteFileImplFunction : public FileFunction {
3114+public:
3115+ DeleteFileImplFunction( FileModule const* );
3116+
3117+ virtual ItemSequence_t
3118+ evaluate( ExternalFunction::Arguments_t const&,
3119+ StaticContext const*,
3120+ DynamicContext const* ) const;
3121+};
3122+
3123+//*****************************************************************************
3124+
3125+class DirectorySeparator : public FileFunction {
3126+public:
3127+ DirectorySeparator( FileModule const* );
3128+
3129+ virtual ItemSequence_t
3130+ evaluate( ExternalFunction::Arguments_t const&,
3131+ StaticContext const*,
3132+ DynamicContext const* ) const;
3133+};
3134+
3135+//*****************************************************************************
3136+
3137+class DirNameFunction : public FileFunction {
3138+public:
3139+ DirNameFunction( FileModule const* );
3140+
3141+ virtual ItemSequence_t
3142+ evaluate( ExternalFunction::Arguments_t const&,
3143+ StaticContext const*,
3144+ DynamicContext const* ) const;
3145+};
3146+
3147+//*****************************************************************************
3148+
3149+class ExistsFunction : public FileFunction {
3150+public:
3151+ ExistsFunction( FileModule const* );
3152+
3153+ virtual ItemSequence_t
3154+ evaluate( ExternalFunction::Arguments_t const&,
3155+ StaticContext const*,
3156+ DynamicContext const* ) const;
3157+};
3158+
3159+//*****************************************************************************
3160+
3161+class ListFunction : public FileFunction {
3162+public:
3163+ ListFunction( FileModule const* );
3164+
3165+ virtual ItemSequence_t
3166+ evaluate( ExternalFunction::Arguments_t const&,
3167+ StaticContext const*,
3168+ DynamicContext const* ) const;
3169+private:
3170+ class IteratorBackedItemSequence : public ItemSequence, public Iterator {
3171+ public:
3172+ IteratorBackedItemSequence( String const &path, zorba::ItemFactory* );
3173+
3174+ //ItemSequence interface
3175+ Iterator_t getIterator();
3176+
3177+ //Iterator interface
3178+ virtual void open();
3179+ virtual bool next(Item& aItem);
3180+ virtual void close();
3181+ virtual bool isOpen() const;
3182+
3183+ private:
3184+ bool is_open;
3185+ int open_count;
3186+ fs::iterator theIterator;
3187+ ItemFactory *theItemFactory;
3188+ };
3189+};
3190+
3191+//*****************************************************************************
3192+
3193+class IsDirectoryFunction : public FileFunction {
3194+public:
3195+ IsDirectoryFunction( FileModule const* );
3196+
3197+ virtual ItemSequence_t
3198+ evaluate( ExternalFunction::Arguments_t const&,
3199+ StaticContext const*,
3200+ DynamicContext const* ) const;
3201+};
3202+
3203+//*****************************************************************************
3204+
3205+class IsFileFunction : public FileFunction {
3206+public:
3207+ IsFileFunction( FileModule const* );
3208+
3209+ virtual ItemSequence_t
3210+ evaluate( ExternalFunction::Arguments_t const&,
3211+ StaticContext const*,
3212+ DynamicContext const* ) const;
3213+};
3214+
3215+//*****************************************************************************
3216+
3217+class IsSymlinkFunction : public FileFunction {
3218+public:
3219+ IsSymlinkFunction( FileModule const* );
3220+
3221+ virtual ItemSequence_t
3222+ evaluate( ExternalFunction::Arguments_t const&,
3223+ StaticContext const*,
3224+ DynamicContext const* ) const;
3225+};
3226+
3227+//*****************************************************************************
3228+
3229+class LastModifiedFunction : public FileFunction {
3230+public:
3231+ LastModifiedFunction( FileModule const* );
3232+
3233+ virtual ItemSequence_t
3234+ evaluate( ExternalFunction::Arguments_t const&,
3235+ StaticContext const*,
3236+ DynamicContext const* ) const;
3237+
3238+private:
3239+ static int getGmtOffset();
3240+};
3241+
3242+//*****************************************************************************
3243+
3244+class ResolvePathFunction : public FileFunction {
3245+public:
3246+ ResolvePathFunction( FileModule const* );
3247+
3248+ virtual ItemSequence_t
3249+ evaluate( ExternalFunction::Arguments_t const&,
3250+ StaticContext const*,
3251+ DynamicContext const* ) const;
3252+};
3253+
3254+//*****************************************************************************
3255+
3256+class PathSeparator : public FileFunction {
3257+public:
3258+ PathSeparator( FileModule const* );
3259+
3260+ virtual ItemSequence_t
3261+ evaluate( ExternalFunction::Arguments_t const&,
3262+ StaticContext const*,
3263+ DynamicContext const* ) const;
3264+};
3265+
3266+//*****************************************************************************
3267+
3268+class PathToNativeFunction : public FileFunction {
3269+public:
3270+ PathToNativeFunction( FileModule const* );
3271+
3272+ virtual ItemSequence_t
3273+ evaluate( ExternalFunction::Arguments_t const&,
3274+ StaticContext const*,
3275+ DynamicContext const* ) const;
3276+};
3277+
3278+//*****************************************************************************
3279+
3280+class PathToUriFunction : public FileFunction {
3281+public:
3282+ PathToUriFunction( FileModule const* );
3283+
3284+ virtual ItemSequence_t
3285+ evaluate( ExternalFunction::Arguments_t const&,
3286+ StaticContext const*,
3287+ DynamicContext const* ) const;
3288+};
3289+
3290+//*****************************************************************************
3291+
3292+class ReadBinaryFunction : public FileFunction {
3293+public:
3294+ ReadBinaryFunction( FileModule const* );
3295+
3296+ virtual ItemSequence_t
3297+ evaluate( ExternalFunction::Arguments_t const&,
3298+ StaticContext const*,
3299+ DynamicContext const* ) const;
3300+};
3301+
3302+//*****************************************************************************
3303+
3304+class ReadTextFunction : public FileFunction {
3305+public:
3306+ ReadTextFunction( FileModule const* );
3307+
3308+ virtual ItemSequence_t
3309+ evaluate( ExternalFunction::Arguments_t const&,
3310+ StaticContext const*,
3311+ DynamicContext const* ) const;
3312+};
3313+
3314+//*****************************************************************************
3315+
3316+class ReadTextLinesFunction : public FileFunction {
3317+public:
3318+ ReadTextLinesFunction( FileModule const* );
3319+
3320+ virtual ItemSequence_t
3321+ evaluate( ExternalFunction::Arguments_t const&,
3322+ StaticContext const*,
3323+ DynamicContext const* ) const;
3324+
3325+protected:
3326+ class LinesItemSequence : public ItemSequence {
3327+ protected:
3328+ String theFile;
3329+ String theEncoding;
3330+ const ReadTextLinesFunction* theFunc;
3331+
3332+ class LinesIterator : public Iterator {
3333+ protected:
3334+ const String& theFile;
3335+ const String& theEncoding;
3336+ const ReadTextLinesFunction* theFunc;
3337+
3338+ std::ifstream* theStream;
3339+
3340+ public:
3341+ LinesIterator(
3342+ const String&,
3343+ const String&,
3344+ const ReadTextLinesFunction*);
3345+
3346+ virtual ~LinesIterator();
3347+
3348+ virtual void open();
3349+ virtual bool next(Item&);
3350+ virtual void close();
3351+ virtual bool isOpen() const;
3352 };
3353- };
3354-
3355-//*****************************************************************************
3356-
3357- class IsDirectoryFunction : public FileFunction
3358- {
3359- public:
3360- IsDirectoryFunction(const FileModule* aModule);
3361-
3362- virtual String
3363- getLocalName() const { return "is-directory"; }
3364-
3365- virtual ItemSequence_t
3366- evaluate(const ExternalFunction::Arguments_t& args,
3367- const StaticContext* aSctxCtx,
3368- const DynamicContext* aDynCtx) const;
3369- };
3370-
3371-//*****************************************************************************
3372-
3373- class IsFileFunction : public FileFunction
3374- {
3375- public:
3376- IsFileFunction(const FileModule* aModule);
3377-
3378- virtual String
3379- getLocalName() const { return "is-file"; }
3380-
3381- virtual ItemSequence_t
3382- evaluate(const ExternalFunction::Arguments_t& args,
3383- const StaticContext* aSctxCtx,
3384- const DynamicContext* aDynCtx) const;
3385- };
3386-
3387-//*****************************************************************************
3388-
3389- class IsSymlinkFunction : public FileFunction
3390- {
3391- public:
3392- IsSymlinkFunction(const FileModule* aModule);
3393-
3394- virtual String
3395- getLocalName() const { return "is-symlink"; }
3396-
3397- virtual ItemSequence_t
3398- evaluate(const ExternalFunction::Arguments_t& args,
3399- const StaticContext* aSctxCtx,
3400- const DynamicContext* aDynCtx) const;
3401- };
3402-
3403-//*****************************************************************************
3404-
3405- class LastModifiedFunction : public FileFunction
3406- {
3407- public:
3408- LastModifiedFunction(const FileModule* aModule);
3409-
3410- virtual String
3411- getLocalName() const { return "last-modified"; }
3412-
3413- virtual ItemSequence_t
3414- evaluate(const ExternalFunction::Arguments_t& args,
3415- const StaticContext* aSctxCtx,
3416- const DynamicContext* aDynCtx) const;
3417-
3418- private:
3419- static int
3420- getGmtOffset();
3421-
3422- };
3423-
3424-//*****************************************************************************
3425-
3426- class SizeFunction : public FileFunction
3427- {
3428- public:
3429- SizeFunction(const FileModule* aModule);
3430-
3431- virtual String
3432- getLocalName() const { return "size"; }
3433-
3434- virtual ItemSequence_t
3435- evaluate(const ExternalFunction::Arguments_t& args,
3436- const StaticContext* aSctxCtx,
3437- const DynamicContext* aDynCtx) const;
3438-
3439- private:
3440- static int
3441- getGmtOffset();
3442-
3443- };
3444-
3445-//*****************************************************************************
3446-
3447- class PathSeparator : public FileFunction
3448- {
3449- public:
3450- PathSeparator(const FileModule* aModule);
3451-
3452- virtual String
3453- getLocalName() const { return "path-separator"; }
3454-
3455- virtual ItemSequence_t
3456- evaluate(const ExternalFunction::Arguments_t& args,
3457- const StaticContext* aSctxCtx,
3458- const DynamicContext* aDynCtx) const;
3459- };
3460-
3461-//*****************************************************************************
3462-
3463- class DirectorySeparator : public FileFunction
3464- {
3465- public:
3466- DirectorySeparator(const FileModule* aModule);
3467-
3468- virtual String
3469- getLocalName() const { return "directory-separator"; }
3470-
3471- virtual ItemSequence_t
3472- evaluate(const ExternalFunction::Arguments_t& args,
3473- const StaticContext* aSctxCtx,
3474- const DynamicContext* aDynCtx) const;
3475- };
3476-
3477-//*****************************************************************************
3478-
3479- class ResolvePathFunction : public FileFunction
3480- {
3481- public:
3482- ResolvePathFunction(const FileModule* aModule);
3483-
3484- virtual String
3485- getLocalName() const { return "resolve-path"; }
3486-
3487- virtual ItemSequence_t
3488- evaluate(const ExternalFunction::Arguments_t& args,
3489- const StaticContext* aSctxCtx,
3490- const DynamicContext* aDynCtx) const;
3491- };
3492-
3493-//*****************************************************************************
3494-
3495- class PathToUriFunction : public FileFunction
3496- {
3497- public:
3498- PathToUriFunction(const FileModule* aModule);
3499-
3500- virtual String
3501- getLocalName() const { return "path-to-uri"; }
3502-
3503- virtual ItemSequence_t
3504- evaluate(const ExternalFunction::Arguments_t& args,
3505- const StaticContext* aSctxCtx,
3506- const DynamicContext* aDynCtx) const;
3507- };
3508-
3509-//*****************************************************************************
3510-
3511- class PathToNativeFunction : public FileFunction
3512- {
3513- public:
3514- PathToNativeFunction(const FileModule* aModule);
3515-
3516- virtual String
3517- getLocalName() const { return "path-to-native"; }
3518-
3519- virtual ItemSequence_t
3520- evaluate(const ExternalFunction::Arguments_t& args,
3521- const StaticContext* aStctxCtx,
3522- const DynamicContext* aDznCtx) const;
3523- };
3524-
3525-//*****************************************************************************
3526-
3527- class ReadBinaryFunction : public FileFunction
3528- {
3529- public:
3530- ReadBinaryFunction(const FileModule* aModule);
3531-
3532- virtual String
3533- getLocalName() const { return "read-binary"; }
3534-
3535- virtual ItemSequence_t
3536- evaluate(const ExternalFunction::Arguments_t& args,
3537- const StaticContext* aSctxCtx,
3538- const DynamicContext* aDynCtx) const;
3539- };
3540-
3541-//*****************************************************************************
3542-
3543- class ReadTextFunction : public StreamableFileFunction
3544- {
3545- public:
3546- ReadTextFunction(const FileModule* aModule);
3547-
3548- virtual String
3549- getLocalName() const { return "read-text"; }
3550-
3551- virtual ItemSequence_t
3552- evaluate(const ExternalFunction::Arguments_t& args,
3553- const StaticContext* aSctxCtx,
3554- const DynamicContext* aDynCtx) const;
3555- };
3556-
3557-//*****************************************************************************
3558-
3559- class ReadTextLinesFunction : public FileFunction
3560- {
3561- public:
3562- ReadTextLinesFunction(const FileModule* aModule);
3563-
3564- virtual String
3565- getLocalName() const { return "read-text-lines"; }
3566-
3567- virtual ItemSequence_t
3568- evaluate(const ExternalFunction::Arguments_t& args,
3569- const StaticContext* aSctxCtx,
3570- const DynamicContext* aDynCtx) const;
3571-
3572- protected:
3573- class LinesItemSequence : public ItemSequence
3574- {
3575- protected:
3576- String theFile;
3577- String theEncoding;
3578- const ReadTextLinesFunction* theFunc;
3579-
3580- class LinesIterator : public Iterator
3581- {
3582- protected:
3583- const String& theFile;
3584- const String& theEncoding;
3585- const ReadTextLinesFunction* theFunc;
3586-
3587- std::ifstream* theStream;
3588-
3589- public:
3590- LinesIterator(
3591- const String&,
3592- const String&,
3593- const ReadTextLinesFunction*);
3594-
3595- virtual ~LinesIterator();
3596-
3597- virtual void
3598- open();
3599-
3600- virtual bool
3601- next(Item&);
3602-
3603- virtual void
3604- close();
3605-
3606- virtual bool
3607- isOpen() const;
3608- };
3609-
3610- public:
3611- LinesItemSequence(
3612- const String& aFile,
3613- const String& aEncoding,
3614- const ReadTextLinesFunction*);
3615-
3616- Iterator_t
3617- getIterator();
3618- };
3619- };
3620-
3621-//*****************************************************************************
3622-
3623- class WriteTextFunction : public WriterFileFunction
3624- {
3625- public:
3626- WriteTextFunction(const FileModule* aModule);
3627-
3628- virtual String
3629- getLocalName() const { return "write-text"; }
3630-
3631- protected:
3632- virtual bool
3633- isAppend() const;
3634-
3635- virtual bool
3636- isBinary() const;
3637- };
3638-
3639-//*****************************************************************************
3640-
3641- class WriteBinaryFunction : public WriterFileFunction
3642- {
3643- public:
3644- WriteBinaryFunction(const FileModule* aModule);
3645-
3646- virtual String
3647- getLocalName() const { return "write-binary"; }
3648-
3649- protected:
3650- virtual bool
3651- isAppend() const;
3652-
3653- virtual bool
3654- isBinary() const;
3655- };
3656-
3657-//*****************************************************************************
3658-
3659- class AppendTextFunction : public WriterFileFunction
3660- {
3661- public:
3662- AppendTextFunction(const FileModule* aModule);
3663-
3664- virtual String
3665- getLocalName() const { return "append-text"; }
3666-
3667- protected:
3668- virtual bool
3669- isAppend() const;
3670-
3671- virtual bool
3672- isBinary() const;
3673- };
3674-
3675-//*****************************************************************************
3676-
3677- class AppendBinaryFunction : public WriterFileFunction
3678- {
3679- public:
3680- AppendBinaryFunction(const FileModule* aModule);
3681-
3682- virtual String
3683- getLocalName() const { return "append-binary"; }
3684-
3685- protected:
3686- virtual bool
3687- isAppend() const;
3688-
3689- virtual bool
3690- isBinary() const;
3691- };
3692-
3693-//*****************************************************************************
3694-
3695-} /* namespace filemodule */ } /* namespace zorba */
3696-
3697+
3698+ public:
3699+ LinesItemSequence(
3700+ const String& aFile,
3701+ const String& aEncoding,
3702+ const ReadTextLinesFunction*);
3703+
3704+ Iterator_t getIterator();
3705+ };
3706+};
3707+
3708+//*****************************************************************************
3709+
3710+class SizeFunction : public FileFunction {
3711+public:
3712+ SizeFunction( FileModule const* );
3713+
3714+ virtual ItemSequence_t
3715+ evaluate( ExternalFunction::Arguments_t const&,
3716+ StaticContext const*,
3717+ DynamicContext const* ) const;
3718+
3719+private:
3720+ static int getGmtOffset();
3721+};
3722+
3723+//*****************************************************************************
3724+
3725+class WriteTextFunction : public WriteTextFunctionImpl {
3726+public:
3727+ WriteTextFunction( FileModule const* );
3728+};
3729+
3730+//*****************************************************************************
3731+
3732+class WriteTextLinesFunction : public WriteTextFunctionImpl {
3733+public:
3734+ WriteTextLinesFunction( FileModule const* );
3735+};
3736+
3737+//*****************************************************************************
3738+
3739+class WriteBinaryFunction : public WriteBinaryFunctionImpl {
3740+public:
3741+ WriteBinaryFunction( FileModule const* );
3742+};
3743+
3744+//*****************************************************************************
3745+
3746+} // namespace filemodule
3747+} // namespace zorba
3748 #endif /* ZORBA_FILEMODULE_FILE_H */
3749+/* vim:set et sw=2 ts=2: */
3750
3751=== modified file 'modules/org/expath/ns/file.xq.src/file_function.cpp'
3752--- modules/org/expath/ns/file.xq.src/file_function.cpp 2013-06-12 23:54:27 +0000
3753+++ modules/org/expath/ns/file.xq.src/file_function.cpp 2013-08-06 14:19:26 +0000
3754@@ -14,280 +14,228 @@
3755 * limitations under the License.
3756 */
3757
3758-#include "file_function.h"
3759-
3760+// standard
3761+#include <cstdio>
3762+#include <cstdlib>
3763 #include <sstream>
3764+#ifdef WIN32
3765+#include <windows.h>
3766+#include <direct.h>
3767+#else
3768+#include <unistd.h>
3769+#endif /* WIN32 */
3770
3771+// Zorba
3772+#include <zorba/diagnostic_list.h>
3773 #include <zorba/empty_sequence.h>
3774-#include <zorba/diagnostic_list.h>
3775 #include <zorba/serializer.h>
3776+#include <zorba/singleton_item_sequence.h>
3777 #include <zorba/store_consts.h>
3778 #include <zorba/user_exception.h>
3779+#include <zorba/util/base64_util.h>
3780 #include <zorba/util/fs_util.h>
3781+#include <zorba/util/transcode_stream.h>
3782 #include <zorba/xquery_functions.h>
3783-#include <zorba/singleton_item_sequence.h>
3784 #include <zorba/zorba.h>
3785
3786+// local
3787+#include "file_function.h"
3788 #include "file_module.h"
3789
3790-#include <cassert>
3791-
3792-#include <stdlib.h>
3793-#include <stdio.h>
3794-#ifdef WIN32
3795-#include <Windows.h>
3796-#include <direct.h>
3797-#else
3798-#include <unistd.h>
3799-#endif
3800-
3801-namespace zorba { namespace filemodule {
3802-
3803-FileFunction::FileFunction(const FileModule* aModule)
3804- : theModule(aModule)
3805-{
3806-}
3807-
3808-FileFunction::~FileFunction()
3809-{
3810-}
3811-
3812-int
3813-FileFunction::raiseFileError(
3814- char const *aQName,
3815- char const *aMessage,
3816- String const &aPath ) const
3817-{
3818+using namespace std;
3819+
3820+namespace zorba {
3821+namespace filemodule {
3822+
3823+///////////////////////////////////////////////////////////////////////////////
3824+
3825+FileFunction::FileFunction( FileModule const *m, char const *local_name ) :
3826+ module_( m ),
3827+ local_name_( local_name )
3828+{
3829+}
3830+
3831+String FileFunction::getLocalName() const {
3832+ return local_name_;
3833+}
3834+
3835+int FileFunction::raiseFileError( char const *aQName, char const *aMessage,
3836+ String const &aPath ) const {
3837 Item const lQName(
3838- theModule->getItemFactory()->createQName( getURI(), "file", aQName )
3839+ module_->getItemFactory()->createQName( getURI(), "file", aQName )
3840 );
3841- std::ostringstream lErrorMessage;
3842+ ostringstream lErrorMessage;
3843 lErrorMessage << '"' << aPath << "\": " << aMessage;
3844 throw USER_EXCEPTION( lQName, lErrorMessage.str() );
3845 }
3846
3847-String
3848-FileFunction::getURI() const
3849-{
3850- return theModule->getURI();
3851+String FileFunction::getURI() const {
3852+ return module_->getURI();
3853 }
3854
3855-String
3856-FileFunction::getEncodingArg(
3857- const ExternalFunction::Arguments_t& aArgs,
3858- unsigned int aPos) const
3859-{
3860- String encoding( getStringArg( aArgs, aPos ) );
3861+String FileFunction::getEncodingArg( ExternalFunction::Arguments_t const &args,
3862+ unsigned pos ) const {
3863+ String encoding( getStringArg( args, pos ) );
3864 if ( encoding.empty() )
3865 encoding = "UTF-8"; // the default file encoding
3866 return encoding;
3867 }
3868
3869-String
3870-FileFunction::getPathArg(
3871- const ExternalFunction::Arguments_t& aArgs,
3872- unsigned int aPos) const
3873-{
3874- String const path( getStringArg( aArgs, aPos ) );
3875+String FileFunction::getPathArg( ExternalFunction::Arguments_t const &args,
3876+ unsigned pos ) const {
3877+ String const path( getStringArg( args, pos ) );
3878 if ( path.empty() )
3879 return path;
3880 try {
3881 return fs::normalize_path( path, fs::curdir() );
3882 }
3883- catch ( std::invalid_argument const &e ) {
3884+ catch ( invalid_argument const &e ) {
3885 throw raiseFileError( "FOFL9999", e.what(), path );
3886 }
3887 }
3888
3889-String
3890-FileFunction::getStringArg(
3891- const ExternalFunction::Arguments_t& aArgs,
3892- unsigned int aPos) const
3893-{
3894- String str;
3895- if ( aPos < aArgs.size() ) {
3896- Iterator_t i( aArgs[ aPos ]->getIterator() );
3897- i->open();
3898+String FileFunction::getStringArg( ExternalFunction::Arguments_t const &args,
3899+ unsigned pos ) const {
3900+ String s;
3901+ if ( pos < args.size() ) {
3902+ Iterator_t it( args[ pos ]->getIterator() );
3903+ it->open();
3904 Item item;
3905- if ( i->next( item ) )
3906- str = item.getStringValue();
3907- i->close();
3908- }
3909- return str;
3910-}
3911-
3912-String
3913-FileFunction::pathToFullOSPath(const String& aPath) const {
3914- try {
3915- return fs::normalize_path( aPath );
3916- }
3917- catch ( std::invalid_argument const &e ) {
3918- throw raiseFileError( "FOFL9999", e.what(), aPath );
3919- }
3920-}
3921-
3922-String
3923-FileFunction::pathToOSPath(const String& aPath) const {
3924- try {
3925- return fs::normalize_path( aPath );
3926- }
3927- catch ( std::invalid_argument const &e ) {
3928- throw raiseFileError( "FOFL9999", e.what(), aPath );
3929- }
3930-}
3931-
3932-String
3933-FileFunction::pathToUriString(const String& aPath) const {
3934-
3935+ if ( it->next( item ) )
3936+ s = item.getStringValue();
3937+ it->close();
3938+ }
3939+ return s;
3940+}
3941+
3942+String FileFunction::pathToUriString(const String& aPath) const {
3943 if ( fn::starts_with( aPath,"file://" ) ) {
3944- std::stringstream lErrorMessage;
3945- lErrorMessage << "Please provide a path, not a URI";
3946- Item lQName = theModule->getItemFactory()->createQName(
3947- "http://www.w3.org/2005/xqt-errors",
3948- "err",
3949- "XPTY0004");
3950- throw USER_EXCEPTION( lQName, lErrorMessage.str() );
3951+ stringstream msg;
3952+ msg << '"' << aPath << "\": path must not be a URI";
3953+ Item const lQName(
3954+ module_->getItemFactory()->createQName(
3955+ "http://www.w3.org/2005/xqt-errors", "err", "XPTY0004"
3956+ )
3957+ );
3958+ throw USER_EXCEPTION( lQName, msg.str() );
3959 }
3960-
3961- String uri( aPath );
3962-
3963+ String const uri( aPath );
3964 return uri;
3965 }
3966
3967-#ifdef WIN32
3968-bool
3969-FileFunction::isValidDriveSegment(
3970- String& aString)
3971-{
3972- aString = fn::upper_case( aString );
3973- // the drive segment has one of the forms: "C:", "C%3A"
3974- if ((aString.length() != 2 && aString.length() != 4) ||
3975- (aString.length() == 2 && !fn::ends_with(aString,":")) ||
3976- (aString.length() == 4 && !fn::ends_with(aString,"%3A"))) {
3977- return false;
3978- }
3979-
3980- char const lDrive = aString[0];
3981- // the string is already upper case
3982- return lDrive >= 'A' && lDrive <= 'Z';
3983-}
3984-#endif
3985-
3986-//*****************************************************************************
3987-
3988-StreamableFileFunction::StreamableFileFunction(const FileModule* aModule)
3989- : FileFunction(aModule)
3990-{
3991-}
3992-
3993-StreamableFileFunction::~StreamableFileFunction()
3994-{
3995-}
3996-
3997-bool
3998-StreamableFileFunction::StreamableItemSequence::InternalIterator::next(Item& aResult)
3999-{
4000- assert(theIsOpen);
4001-
4002- if (theHasNext) {
4003- aResult = theItemSequence->theItem;
4004- theHasNext = false;
4005- return !aResult.isNull();
4006- }
4007- return false;
4008-}
4009-
4010-//*****************************************************************************
4011-
4012-WriterFileFunction::WriterFileFunction(const FileModule* aModule)
4013- : FileFunction(aModule)
4014-{
4015-}
4016-
4017-WriterFileFunction::~WriterFileFunction()
4018-{
4019-}
4020-
4021-ItemSequence_t
4022-WriterFileFunction::evaluate(
4023- const ExternalFunction::Arguments_t& aArgs,
4024- const StaticContext*,
4025- const DynamicContext* ) const
4026-{
4027- String const lFileStr( getPathArg(aArgs, 0) );
4028-
4029- fs::type const fs_type = fs::get_type( lFileStr );
4030- if ( fs_type && fs_type != fs::file )
4031- raiseFileError( "FOFL0004", "not a plain file", lFileStr );
4032-
4033- bool const lBinary = isBinary();
4034-
4035- std::ios_base::openmode mode = std::ios_base::out
4036- | (isAppend() ? std::ios_base::app : std::ios_base::trunc);
4037- if ( lBinary )
4038- mode |= std::ios_base::binary;
4039-
4040- std::ofstream lOutStream( lFileStr.c_str(), mode );
4041- if ( !lOutStream ) {
4042- std::ostringstream oss;
4043- oss << '"' << lFileStr << "\": can not open file for writing";
4044- raiseFileError( "FOFL9999", oss.str().c_str(), lFileStr );
4045- }
4046-
4047- // if this is a binary write
4048- if (lBinary)
4049- {
4050- Item lBinaryItem;
4051- Iterator_t lContentSeq = aArgs[1]->getIterator();
4052- lContentSeq->open();
4053- while (lContentSeq->next(lBinaryItem))
4054- {
4055- if (lBinaryItem.isStreamable() && !lBinaryItem.isEncoded())
4056- {
4057- lOutStream << lBinaryItem.getStream().rdbuf();
4058- }
4059- else
4060- {
4061- Zorba_SerializerOptions lOptions;
4062- lOptions.ser_method = ZORBA_SERIALIZATION_METHOD_BINARY;
4063- Serializer_t lSerializer = Serializer::createSerializer(lOptions);
4064- SingletonItemSequence lSeq(lBinaryItem);
4065- lSerializer->serialize(&lSeq, lOutStream);
4066- }
4067-
4068- }
4069- }
4070- // if we only write text
4071- else
4072- {
4073- Item lStringItem;
4074- Iterator_t lContentSeq = aArgs[1]->getIterator();
4075- lContentSeq->open();
4076- // for each item (string or base64Binary) in the content sequence
4077- while (lContentSeq->next(lStringItem)) {
4078- // if the item is streamable make use of the stream
4079- if (lStringItem.isStreamable()) {
4080- std::istream& lInStream = lStringItem.getStream();
4081- char lBuf[1024];
4082- while (!lInStream.eof()) {
4083- lInStream.read(lBuf, 1024);
4084- lOutStream.write(lBuf, lInStream.gcount());
4085- }
4086- }
4087- // else write the string value
4088- else {
4089- zorba::String lString = lStringItem.getStringValue();
4090- lOutStream.write(lString.data(), lString.size());
4091- }
4092- }
4093- lContentSeq->close();
4094- }
4095-
4096- // close the file stream
4097- lOutStream.close();
4098-
4099- return ItemSequence_t(new EmptySequence());
4100-}
4101+///////////////////////////////////////////////////////////////////////////////
4102+
4103+WriteBinaryFunctionImpl::WriteBinaryFunctionImpl( FileModule const *m,
4104+ char const *local_name,
4105+ bool append ) :
4106+ FileFunction( m, local_name ),
4107+ append_( append )
4108+{
4109+}
4110+
4111+ItemSequence_t WriteBinaryFunctionImpl::evaluate(
4112+ ExternalFunction::Arguments_t const &args,
4113+ StaticContext const*,
4114+ DynamicContext const* ) const
4115+{
4116+ String const path( getPathArg( args, 0 ) );
4117+
4118+ fs::type const fs_type = fs::get_type( path );
4119+ if ( fs_type && fs_type != fs::file )
4120+ raiseFileError( "FOFL0004", "not a plain file", path );
4121+
4122+ ios_base::openmode const mode = ios_base::out | ios_base::binary
4123+ | (append_ ? ios_base::app : ios_base::trunc);
4124+
4125+ ofstream ofs( path.c_str(), mode );
4126+ if ( !ofs ) {
4127+ ostringstream oss;
4128+ oss << '"' << path << "\": can not open file for writing";
4129+ raiseFileError( "FOFL9999", oss.str().c_str(), path );
4130+ }
4131+
4132+ Iterator_t it( args[1]->getIterator() );
4133+ it->open();
4134+ Item item;
4135+ while ( it->next( item ) ) {
4136+ if ( item.isStreamable() ) {
4137+ if ( item.isEncoded() )
4138+ base64::decode( item.getStream(), ofs );
4139+ else
4140+ ofs << item.getStream().rdbuf();
4141+ } else {
4142+ size_t b64_size;
4143+ char const *const b64_value = item.getBase64BinaryValue( b64_size );
4144+ if ( item.isEncoded() )
4145+ base64::decode( b64_value, b64_size, ofs );
4146+ else
4147+ ofs.write( b64_value, b64_size );
4148+ }
4149+ }
4150+ it->close();
4151+
4152+ return ItemSequence_t( new EmptySequence() );
4153+}
4154+
4155+///////////////////////////////////////////////////////////////////////////////
4156+
4157+WriteTextFunctionImpl::WriteTextFunctionImpl( FileModule const *m,
4158+ char const *local_name,
4159+ bool append, bool newlines ) :
4160+ FileFunction( m, local_name ),
4161+ append_( append ),
4162+ newlines_( newlines )
4163+{
4164+}
4165+
4166+ItemSequence_t WriteTextFunctionImpl::evaluate(
4167+ ExternalFunction::Arguments_t const &args,
4168+ StaticContext const*,
4169+ DynamicContext const* ) const
4170+{
4171+ String const path( getPathArg( args, 0 ) );
4172+ String const encoding( getStringArg( args, 2 ) );
4173+
4174+ fs::type const fs_type = fs::get_type( path );
4175+ if ( fs_type && fs_type != fs::file )
4176+ raiseFileError( "FOFL0004", "not a plain file", path );
4177+
4178+ if ( !transcode::is_supported( encoding.c_str() ) )
4179+ raiseFileError( "FOFL9999", "encoding not supported", encoding );
4180+
4181+ ios_base::openmode const mode = ios_base::out
4182+ | (append_ ? ios_base::app : ios_base::trunc);
4183+
4184+ ofstream ofs( path.c_str(), mode );
4185+ if ( !ofs ) {
4186+ ostringstream oss;
4187+ oss << '"' << path << "\": can not open file for writing";
4188+ raiseFileError( "FOFL9999", oss.str().c_str(), path );
4189+ }
4190+
4191+ transcode::auto_attach<ofstream> transcoder;
4192+ if ( transcode::is_necessary( encoding.c_str() ) )
4193+ transcoder.attach( ofs, encoding.c_str() );
4194+
4195+ Iterator_t it( args[1]->getIterator() );
4196+ it->open();
4197+ Item item;
4198+ while ( it->next( item ) ) {
4199+ if ( item.isStreamable() ) {
4200+ ofs << item.getStream().rdbuf();
4201+ } else {
4202+ zorba::String const s( item.getStringValue() );
4203+ ofs.write( s.data(), s.size() );
4204+ }
4205+ if ( newlines_ )
4206+ ofs << fs::newline;
4207+ }
4208+ it->close();
4209+
4210+ return ItemSequence_t( new EmptySequence() );
4211+}
4212+
4213+///////////////////////////////////////////////////////////////////////////////
4214
4215 } // namespace filemodule
4216 } // namespace zorba
4217
4218=== modified file 'modules/org/expath/ns/file.xq.src/file_function.h'
4219--- modules/org/expath/ns/file.xq.src/file_function.h 2013-06-12 23:54:27 +0000
4220+++ modules/org/expath/ns/file.xq.src/file_function.h 2013-08-06 14:19:26 +0000
4221@@ -17,162 +17,87 @@
4222 #ifndef ZORBA_FILEMODULE_FILEFUNCTION_H
4223 #define ZORBA_FILEMODULE_FILEFUNCTION_H
4224
4225+// standard
4226+#include <fstream>
4227+
4228+// Zorba
4229 #include <zorba/error.h>
4230 #include <zorba/function.h>
4231 #include <zorba/item.h>
4232 #include <zorba/iterator.h>
4233 #include <zorba/options.h>
4234
4235-#include <fstream>
4236-
4237 namespace zorba {
4238-
4239- namespace filemodule {
4240-
4241- class FileModule;
4242-
4243- class FileFunction : public ContextualExternalFunction
4244- {
4245- private:
4246-
4247-#ifdef WIN32
4248- static bool
4249- isValidDriveSegment(
4250- String& value);
4251-#endif
4252-
4253- protected:
4254- const FileModule* theModule;
4255-
4256- int
4257- raiseFileError(
4258- char const *qName,
4259- char const *message,
4260- const String& path) const;
4261-
4262- /*
4263- * Gets the argument on position pos as a normalised file system path.
4264- * pos must point to a file function argument. No checks are made.
4265- */
4266- String
4267- getPathArg(
4268- const ExternalFunction::Arguments_t& args,
4269- unsigned int pos) const;
4270-
4271- String
4272- getEncodingArg(
4273- const ExternalFunction::Arguments_t& args,
4274- unsigned int pos) const;
4275-
4276- String
4277- getStringArg(
4278- const ExternalFunction::Arguments_t& args,
4279- unsigned int pos) const;
4280-
4281- String
4282- pathToFullOSPath(const String& path) const;
4283-
4284- String
4285- pathToOSPath(const String& path) const;
4286-
4287- String
4288- pathToUriString(const String& path) const;
4289-
4290- public:
4291- FileFunction(const FileModule* module);
4292- ~FileFunction();
4293-
4294- virtual String
4295- getURI() const;
4296-
4297- };
4298-
4299- class StreamableFileFunction : public FileFunction
4300- {
4301- public:
4302-
4303- StreamableFileFunction(const FileModule* module);
4304-
4305- ~StreamableFileFunction();
4306-
4307- protected:
4308-
4309- class StreamableItemSequence : public ItemSequence {
4310-
4311- public:
4312- class InternalIterator : public Iterator
4313- {
4314- private:
4315- StreamableItemSequence *theItemSequence;
4316- bool theIsOpen;
4317- bool theHasNext;
4318-
4319- public:
4320- InternalIterator(StreamableItemSequence* aItemSequence)
4321- : theItemSequence(aItemSequence),
4322- theIsOpen(false),
4323- theHasNext(true)
4324- { }
4325-
4326- virtual void
4327- open()
4328- {
4329- theIsOpen = true;
4330- theHasNext = true;
4331- }
4332-
4333- virtual void
4334- close()
4335- {
4336- theIsOpen = false;
4337- }
4338-
4339- virtual bool
4340- isOpen() const
4341- {
4342- return theIsOpen;
4343- }
4344-
4345- bool
4346- next(Item& aResult);
4347- };
4348-
4349- Item theItem;
4350- std::ifstream* theStream;
4351-
4352- StreamableItemSequence()
4353- : theStream(new std::ifstream()) {}
4354-
4355- Iterator_t getIterator()
4356- {
4357- return new InternalIterator(this);
4358- }
4359- };
4360- };
4361-
4362- class WriterFileFunction : public FileFunction
4363- {
4364- public:
4365-
4366- WriterFileFunction(const FileModule* module);
4367-
4368- ~WriterFileFunction();
4369-
4370- virtual ItemSequence_t
4371- evaluate(const ExternalFunction::Arguments_t& args,
4372- const StaticContext* aSctxCtx,
4373- const DynamicContext* aDynCtx) const;
4374-
4375- protected:
4376-
4377- virtual bool
4378- isAppend() const = 0;
4379-
4380- virtual bool
4381- isBinary() const = 0;
4382- };
4383-
4384-} /* namespace filemodule */
4385-} /* namespace zorba */
4386+namespace filemodule {
4387+
4388+class FileModule;
4389+
4390+///////////////////////////////////////////////////////////////////////////////
4391+
4392+class FileFunction : public ContextualExternalFunction {
4393+public:
4394+ virtual String getLocalName() const;
4395+ virtual String getURI() const;
4396+
4397+protected:
4398+ FileFunction( FileModule const *module, char const *local_name );
4399+
4400+ /**
4401+ * Gets the argument on position pos as a normalised file system path.
4402+ * pos must point to a file function argument. No checks are made.
4403+ */
4404+ String getPathArg( ExternalFunction::Arguments_t const&, unsigned pos ) const;
4405+
4406+ String getEncodingArg( ExternalFunction::Arguments_t const&,
4407+ unsigned pos ) const;
4408+
4409+ String getStringArg( ExternalFunction::Arguments_t const&,
4410+ unsigned pos ) const;
4411+
4412+ String pathToUriString(const String& path) const;
4413+
4414+ int raiseFileError( char const *qName, char const *message,
4415+ String const &path ) const;
4416+
4417+ FileModule const *module_;
4418+ char const *const local_name_; // points to string literal
4419+};
4420+
4421+///////////////////////////////////////////////////////////////////////////////
4422+
4423+class WriteBinaryFunctionImpl : public FileFunction {
4424+public:
4425+ ItemSequence_t evaluate( ExternalFunction::Arguments_t const&,
4426+ StaticContext const*,
4427+ DynamicContext const* ) const;
4428+
4429+protected:
4430+ WriteBinaryFunctionImpl( FileModule const*, char const *local_name,
4431+ bool append );
4432+
4433+ bool const append_;
4434+};
4435+
4436+///////////////////////////////////////////////////////////////////////////////
4437+
4438+class WriteTextFunctionImpl : public FileFunction {
4439+public:
4440+ ItemSequence_t evaluate( ExternalFunction::Arguments_t const&,
4441+ StaticContext const*,
4442+ DynamicContext const* ) const;
4443+
4444+protected:
4445+ WriteTextFunctionImpl( FileModule const*, char const *local_name,
4446+ bool append, bool newlines );
4447+
4448+ bool const append_;
4449+ bool const newlines_;
4450+};
4451+
4452+///////////////////////////////////////////////////////////////////////////////
4453+
4454+} // namespace filemodule
4455+} // namespace zorba
4456
4457 #endif /* ZORBA_FILEMODULE_FILEFUNCTION_H */
4458+/* vim:set et sw=2 ts=2: */
4459
4460=== modified file 'modules/org/expath/ns/file.xq.src/file_module.cpp'
4461--- modules/org/expath/ns/file.xq.src/file_module.cpp 2013-06-12 15:35:27 +0000
4462+++ modules/org/expath/ns/file.xq.src/file_module.cpp 2013-08-06 14:19:26 +0000
4463@@ -1,12 +1,12 @@
4464 /*
4465 * Copyright 2006-2008 The FLWOR Foundation.
4466- *
4467+ *
4468 * Licensed under the Apache License, Version 2.0 (the "License");
4469 * you may not use this file except in compliance with the License.
4470 * You may obtain a copy of the License at
4471- *
4472+ *
4473 * http://www.apache.org/licenses/LICENSE-2.0
4474- *
4475+ *
4476 * Unless required by applicable law or agreed to in writing, software
4477 * distributed under the License is distributed on an "AS IS" BASIS,
4478 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4479@@ -17,87 +17,87 @@
4480 #include "file.h"
4481 #include "file_module.h"
4482 #include "file_function.h"
4483-#include <cassert>
4484-
4485-namespace zorba { namespace filemodule {
4486-
4487- const char* FileModule::theNamespace = "http://expath.org/ns/file";
4488-
4489-
4490-FileModule::~FileModule()
4491-{
4492- for (FuncMap_t::const_iterator lIter = theFunctions.begin();
4493- lIter != theFunctions.end(); ++lIter) {
4494- delete lIter->second;
4495+
4496+namespace zorba {
4497+namespace filemodule {
4498+
4499+///////////////////////////////////////////////////////////////////////////////
4500+
4501+FileModule::~FileModule() {
4502+ for ( FuncMap_t::const_iterator i = theFunctions.begin();
4503+ i != theFunctions.end(); ++i ) {
4504+ delete i->second;
4505 }
4506- theFunctions.clear();
4507 }
4508
4509-ExternalFunction*
4510-FileModule::getExternalFunction(const String& aLocalname)
4511-{
4512- ExternalFunction*& lFunc = theFunctions[aLocalname];
4513- if (!lFunc) {
4514- if (aLocalname == "base-name") {
4515- lFunc = new BaseNameFunction(this);
4516- } else if (aLocalname == "copy-file-impl") {
4517- lFunc = new CopyFileImplFunction(this);
4518- } else if (aLocalname == "create-directory") {
4519- lFunc = new CreateDirectoryFunction(this);
4520- } else if (aLocalname == "delete-file-impl") {
4521- lFunc = new DeleteFileImplFunction(this);
4522- } else if (aLocalname == "dir-name") {
4523- lFunc = new DirNameFunction(this);
4524- } else if (aLocalname == "exists") {
4525- lFunc = new ExistsFunction(this);
4526- } else if (aLocalname == "is-directory") {
4527- lFunc = new IsDirectoryFunction(this);
4528- } else if (aLocalname == "is-file") {
4529- lFunc = new IsFileFunction(this);
4530- } else if (aLocalname == "read-binary") {
4531- lFunc = new ReadBinaryFunction(this);
4532- } else if (aLocalname == "read-text") {
4533- lFunc = new ReadTextFunction(this);
4534- } else if (aLocalname == "read-text-lines") {
4535- lFunc = new ReadTextLinesFunction(this);
4536- } else if (aLocalname == "is-symlink") {
4537- lFunc = new IsSymlinkFunction(this);
4538- } else if (aLocalname == "write-text") {
4539- lFunc = new WriteTextFunction(this);
4540- } else if (aLocalname == "write-binary") {
4541- lFunc = new WriteBinaryFunction(this);
4542- } else if (aLocalname == "append-text") {
4543- lFunc = new AppendTextFunction(this);
4544- } else if (aLocalname == "append-binary") {
4545- lFunc = new AppendBinaryFunction(this);
4546- } else if (aLocalname == "list") {
4547- lFunc = new ListFunction(this);
4548- } else if (aLocalname == "last-modified") {
4549- lFunc = new LastModifiedFunction(this);
4550- } else if (aLocalname == "size") {
4551- lFunc = new SizeFunction(this);
4552- } else if (aLocalname == "directory-separator") {
4553- lFunc = new DirectorySeparator(this);
4554- } else if (aLocalname == "path-separator") {
4555- lFunc = new PathSeparator(this);
4556- } else if (aLocalname == "resolve-path") {
4557- lFunc = new ResolvePathFunction(this);
4558- } else if (aLocalname == "path-to-uri") {
4559- lFunc = new PathToUriFunction(this);
4560- } else if (aLocalname == "path-to-native") {
4561- lFunc = new PathToNativeFunction(this);
4562- }
4563+ExternalFunction* FileModule::getExternalFunction( String const &aLocalname ) {
4564+ ExternalFunction *&lFunc = theFunctions[ aLocalname ];
4565+ if ( !lFunc ) {
4566+ if ( aLocalname == "append-text" )
4567+ lFunc = new AppendTextFunction( this );
4568+ else if ( aLocalname == "append-text-lines" )
4569+ lFunc = new AppendTextLinesFunction( this );
4570+ else if ( aLocalname == "append-binary" )
4571+ lFunc = new AppendBinaryFunction( this );
4572+ else if ( aLocalname == "base-name" )
4573+ lFunc = new BaseNameFunction( this );
4574+ else if ( aLocalname == "copy-file-impl" )
4575+ lFunc = new CopyFileImplFunction( this );
4576+ else if ( aLocalname == "create-directory" )
4577+ lFunc = new CreateDirectoryFunction( this );
4578+ else if ( aLocalname == "delete-file-impl" )
4579+ lFunc = new DeleteFileImplFunction( this );
4580+ else if ( aLocalname == "dir-name" )
4581+ lFunc = new DirNameFunction( this );
4582+ else if ( aLocalname == "directory-separator" )
4583+ lFunc = new DirectorySeparator( this );
4584+ else if ( aLocalname == "exists" )
4585+ lFunc = new ExistsFunction( this );
4586+ else if ( aLocalname == "is-directory" )
4587+ lFunc = new IsDirectoryFunction( this );
4588+ else if ( aLocalname == "is-file" )
4589+ lFunc = new IsFileFunction( this );
4590+ else if ( aLocalname == "is-symlink" )
4591+ lFunc = new IsSymlinkFunction( this );
4592+ else if ( aLocalname == "last-modified" )
4593+ lFunc = new LastModifiedFunction( this );
4594+ else if ( aLocalname == "list" )
4595+ lFunc = new ListFunction( this );
4596+ else if ( aLocalname == "path-separator" )
4597+ lFunc = new PathSeparator( this );
4598+ else if ( aLocalname == "path-to-native" )
4599+ lFunc = new PathToNativeFunction( this );
4600+ else if ( aLocalname == "path-to-uri" )
4601+ lFunc = new PathToUriFunction( this );
4602+ else if ( aLocalname == "read-binary" )
4603+ lFunc = new ReadBinaryFunction( this );
4604+ else if ( aLocalname == "read-text" )
4605+ lFunc = new ReadTextFunction( this );
4606+ else if ( aLocalname == "read-text-lines" )
4607+ lFunc = new ReadTextLinesFunction( this );
4608+ else if ( aLocalname == "resolve-path" )
4609+ lFunc = new ResolvePathFunction( this );
4610+ else if ( aLocalname == "write-text" )
4611+ lFunc = new WriteTextFunction( this );
4612+ else if ( aLocalname == "write-text-lines" )
4613+ lFunc = new WriteTextLinesFunction( this );
4614+ else if ( aLocalname == "write-binary" )
4615+ lFunc = new WriteBinaryFunction( this );
4616+ else if ( aLocalname == "size" )
4617+ lFunc = new SizeFunction( this );
4618 }
4619 return lFunc;
4620 }
4621
4622-void
4623-FileModule::destroy()
4624-{
4625- if (dynamic_cast<FileModule*>(this)) {
4626- delete this;
4627- }
4628-}
4629+void FileModule::destroy() {
4630+ delete this;
4631+}
4632+
4633+String FileModule::getURI() const {
4634+ return "http://expath.org/ns/file";
4635+}
4636+
4637+///////////////////////////////////////////////////////////////////////////////
4638
4639 } // namespace filemodule
4640 } // namespace zorba
4641
4642=== modified file 'modules/org/expath/ns/file.xq.src/file_module.h'
4643--- modules/org/expath/ns/file.xq.src/file_module.h 2013-02-07 17:24:36 +0000
4644+++ modules/org/expath/ns/file.xq.src/file_module.h 2013-08-06 14:19:26 +0000
4645@@ -1,12 +1,12 @@
4646 /*
4647 * Copyright 2006-2008 The FLWOR Foundation.
4648- *
4649+ *
4650 * Licensed under the Apache License, Version 2.0 (the "License");
4651 * you may not use this file except in compliance with the License.
4652 * You may obtain a copy of the License at
4653- *
4654+ *
4655 * http://www.apache.org/licenses/LICENSE-2.0
4656- *
4657+ *
4658 * Unless required by applicable law or agreed to in writing, software
4659 * distributed under the License is distributed on an "AS IS" BASIS,
4660 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4661@@ -22,67 +22,44 @@
4662 #include <zorba/zorba.h>
4663 #include <zorba/external_module.h>
4664
4665-namespace zorba { namespace filemodule {
4666-
4667-class FileModule : public ExternalModule
4668-{
4669-private:
4670- mutable ItemFactory* theFactory;
4671-
4672-public:
4673- static const char* theNamespace;
4674-
4675-protected:
4676- class ltstr
4677- {
4678- public:
4679- bool operator()(const String& s1, const String& s2) const
4680- {
4681- return s1.compare(s2) < 0;
4682- }
4683- };
4684-
4685- typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;
4686- FuncMap_t theFunctions;
4687-
4688-public:
4689- static void
4690- streamReleaser(std::istream* stream)
4691- {
4692+namespace zorba {
4693+namespace filemodule {
4694+
4695+///////////////////////////////////////////////////////////////////////////////
4696+
4697+class FileModule : public ExternalModule {
4698+public:
4699+ static void streamReleaser( std::istream *stream ) {
4700 delete stream;
4701 }
4702
4703- FileModule() : theFactory(0) {}
4704-
4705+ FileModule() : theFactory(0) { }
4706 virtual ~FileModule();
4707-
4708- virtual String
4709- getURI() const { return theNamespace; }
4710-
4711- virtual ExternalFunction*
4712- getExternalFunction(const String& aLocalname);
4713-
4714- virtual void
4715- destroy();
4716-
4717- ItemFactory*
4718- getItemFactory() const
4719- {
4720- if (!theFactory)
4721- {
4722+
4723+ virtual void destroy();
4724+ virtual ExternalFunction* getExternalFunction( String const &aLocalname );
4725+ virtual String getURI() const;
4726+
4727+ ItemFactory* getItemFactory() const {
4728+ if ( !theFactory )
4729 theFactory = Zorba::getInstance(0)->getItemFactory();
4730- }
4731-
4732 return theFactory;
4733 }
4734+
4735+protected:
4736+ typedef std::map<String,ExternalFunction*> FuncMap_t;
4737+ FuncMap_t theFunctions;
4738+
4739+private:
4740+ mutable ItemFactory *theFactory;
4741 };
4742
4743+///////////////////////////////////////////////////////////////////////////////
4744
4745-} /* namespace filemodule */
4746-} /* namespace zorba */
4747+} // namespace filemodule
4748+} // namespace zorba
4749
4750 #endif /* ZORBA_FILEMODULE_FILEMODULE_H */
4751-
4752 /*
4753 * Local variables:
4754 * mode: c++
4755
4756=== modified file 'scripts/notice-generator.xq.in'
4757--- scripts/notice-generator.xq.in 2013-02-07 17:24:36 +0000
4758+++ scripts/notice-generator.xq.in 2013-08-06 14:19:26 +0000
4759@@ -171,12 +171,8 @@
4760 ()
4761 else
4762 let $contents := local:contents($notice)
4763- return file:write (
4764- fn:concat($relpath-from-this, "/NOTICE.txt"), $contents,
4765- <output:serialization-parameters
4766- xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
4767- <output:method value="text"/>
4768- </output:serialization-parameters>
4769+ return file:write-text(
4770+ fn:concat($relpath-from-this, "/NOTICE.txt"), $contents
4771 )
4772 };
4773
4774
4775=== modified file 'src/util/fs_util.cpp'
4776--- src/util/fs_util.cpp 2013-06-17 22:19:13 +0000
4777+++ src/util/fs_util.cpp 2013-08-06 14:19:26 +0000
4778@@ -44,14 +44,21 @@
4779
4780 ///////////////////////////////////////////////////////////////////////////////
4781
4782-char const *const type_string[] = {
4783- "non_existant",
4784- "directory",
4785- "file",
4786- "link",
4787- "volume",
4788- "other"
4789-};
4790+ostream& operator<<( ostream &o, type t ) {
4791+ static char const *const string_of[] = {
4792+ "non_existant",
4793+ "directory",
4794+ "file",
4795+ "link",
4796+ "volume",
4797+ "other"
4798+ };
4799+ if ( t >= 0 && t <= other )
4800+ o << string_of[ t ];
4801+ else
4802+ o << "<invalid fs::type " << (int)t << '>';
4803+ return o;
4804+}
4805
4806 ////////// helper functions ///////////////////////////////////////////////////
4807
4808
4809=== modified file 'test/fots_driver/reporting.xq'
4810--- test/fots_driver/reporting.xq 2013-05-20 17:56:33 +0000
4811+++ test/fots_driver/reporting.xq 2013-08-06 14:19:26 +0000
4812@@ -80,11 +80,11 @@
4813 'run-test-sets',
4814 fn:false());
4815
4816- file:write(if(contains($FOTSZorbaManifestPath,"XQ30"))
4817- then "results_XQ30.xml"
4818- else "results_XQ10.xml",
4819- $results,
4820- $util:writeXML);
4821+ file:write-text(if(contains($FOTSZorbaManifestPath,"XQ30"))
4822+ then "results_XQ30.xml"
4823+ else "results_XQ10.xml",
4824+ serialize($results),
4825+ $util:writeXML);
4826
4827 reporting:W3C-reporting($results,
4828 $FOTSZorbaManifestPath,
4829
4830=== modified file 'test/fots_driver/util.xq'
4831--- test/fots_driver/util.xq 2013-03-12 16:41:24 +0000
4832+++ test/fots_driver/util.xq 2013-08-06 14:19:26 +0000
4833@@ -130,7 +130,7 @@
4834 $query as xs:string,
4835 $queryName as xs:string
4836 ) {
4837- file:write(concat("query_", $queryName, ".xq"),
4838- $query,
4839- $util:writeText);
4840+ file:write-text(concat("query_", $queryName, ".xq"),
4841+ $query,
4842+ $util:writeText);
4843 };
4844
4845=== modified file 'test/rbkt/Queries/zorba/file/common.xqlib'
4846--- test/rbkt/Queries/zorba/file/common.xqlib 2013-02-07 17:24:36 +0000
4847+++ test/rbkt/Queries/zorba/file/common.xqlib 2013-08-06 14:19:26 +0000
4848@@ -37,8 +37,8 @@
4849 }
4850 };
4851
4852-declare %ann:sequential function commons:testWriteXml($path as xs:string, $xml as item()) as xs:string* {
4853- file:write($path, $xml, ());
4854+declare %ann:sequential function commons:testWriteXml($path as xs:string, $xml as node()) as xs:string* {
4855+ file:write-text($path, serialize($xml));
4856 "SUCCESS"
4857 };
4858
4859@@ -66,13 +66,15 @@
4860 };
4861
4862 declare %ann:sequential function commons:testWriteSerializeXml($path as xs:string, $xml as item()) as xs:string* {
4863- file:write(
4864+ file:write-text(
4865 $path,
4866- $xml,
4867- <output:serialization-parameters>
4868- <output:method value="xml"/>
4869- </output:serialization-parameters>);
4870-
4871+ fn:serialize(
4872+ $xml,
4873+ <output:serialization-parameters>
4874+ <output:method value="xml"/>
4875+ </output:serialization-parameters>
4876+ )
4877+ );
4878 "SUCCESS";
4879 };
4880
4881@@ -138,3 +140,4 @@
4882 else
4883 fn:false()
4884 };
4885+(: vim:set syntax=xquery et sw=2 ts=2: :)
4886
4887=== modified file 'test/rbkt/Queries/zorba/file/file_read_serialize.xq'
4888--- test/rbkt/Queries/zorba/file/file_read_serialize.xq 2013-02-07 17:24:36 +0000
4889+++ test/rbkt/Queries/zorba/file/file_read_serialize.xq 2013-08-06 14:19:26 +0000
4890@@ -11,8 +11,7 @@
4891 return replace value of node $price with xs:double($price) * 2;
4892
4893 (: write the updated data to a new file :)
4894-file:write("new-prices.xml", $local:my-doc, ());
4895+file:write-text("new-prices.xml", $local:my-doc);
4896
4897 (: return the new data as result of the program :)
4898 $local:my-doc
4899-
4900
4901=== modified file 'test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_02.xq'
4902--- test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_02.xq 2013-07-17 09:01:57 +0000
4903+++ test/rbkt/Queries/zorba/jsoniq/roundtrip/roundtrip_02.xq 2013-08-06 14:19:26 +0000
4904@@ -13,7 +13,7 @@
4905 "EQName" : fn:QName("http://jsoniq.org/roundtrip", "value")
4906 };
4907 variable $enc := jn:encode-for-roundtrip($obj);
4908-f:write($filename, $enc, <o:serialization-parameters><o:method value="json"/></o:serialization-parameters>);
4909+f:write-text($filename, serialize($enc, <o:serialization-parameters><o:method value="json"/></o:serialization-parameters>));
4910 variable $read := f:read-text($filename);
4911 variable $dec := jn:decode-from-roundtrip(jn:parse-json($read));
4912 f:delete($filename);

Subscribers

People subscribed via source and target branches