Merge lp:~zorba-coders/zorba/feature-fetch_binary into lp:zorba

Proposed by Matthias Brantner
Status: Superseded
Proposed branch: lp:~zorba-coders/zorba/feature-fetch_binary
Merge into: lp:zorba
Diff against target: 987 lines (+438/-102)
34 files modified
include/zorba/uri_resolvers.h (+5/-1)
modules/com/zorba-xquery/www/modules/CMakeLists.txt (+1/-1)
modules/com/zorba-xquery/www/modules/fetch.xq (+93/-46)
src/api/uri_resolver_wrappers.cpp (+3/-1)
src/api/uriresolverimpl.cpp (+7/-4)
src/api/uriresolverimpl.h (+9/-2)
src/context/default_url_resolvers.cpp (+2/-1)
src/context/uri_resolver.cpp (+4/-2)
src/context/uri_resolver.h (+11/-1)
src/functions/pregenerated/func_fetch.cpp (+25/-1)
src/functions/pregenerated/func_fetch.h (+17/-0)
src/functions/pregenerated/function_enum.h (+2/-1)
src/runtime/fetch/fetch_impl.cpp (+116/-30)
src/runtime/fetch/pregenerated/fetch.cpp (+22/-0)
src/runtime/fetch/pregenerated/fetch.h (+36/-0)
src/runtime/nodes/nodes_impl.cpp (+4/-2)
src/runtime/spec/fetch/fetch.xml (+29/-3)
src/runtime/visitors/pregenerated/planiter_visitor.h (+5/-0)
src/runtime/visitors/pregenerated/printer_visitor.cpp (+14/-0)
src/runtime/visitors/pregenerated/printer_visitor.h (+3/-0)
test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable_binary.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/fetch/fetch_some_transcode.xml.res (+1/-0)
test/rbkt/Queries/zorba/fetch/fetch_bogus1.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_bogus2.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_module1.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_module2.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_random_file.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_schema1.xq (+1/-1)
test/rbkt/Queries/zorba/fetch/fetch_seekable.xml.res (+1/-0)
test/rbkt/Queries/zorba/fetch/fetch_seekable.xq (+8/-0)
test/rbkt/Queries/zorba/fetch/fetch_seekable_binary.xq (+8/-0)
test/rbkt/Queries/zorba/fetch/fetch_some_transcode.xq (+3/-0)
test/rbkt/Queries/zorba/fetch/iso-8859-1.txt (+1/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/feature-fetch_binary
Reviewer Review Type Date Requested Status
Matthias Brantner Pending
Review via email: mp+105155@code.launchpad.net

This proposal has been superseded by a proposal from 2012-05-09.

Commit message

- fetch:content-binary
- fetch:content#3 (with encoding parameter)
- StreamResource::isStreamSeekable to make sure the streamable strings returned by fetch are seekable.

Description of the change

- fetch:content-binary
- fetch:content#3 (with encoding parameter)
- StreamResource::isStreamSeekable to make sure the streamable strings returned by fetch are seekable.

To post a comment you must log in.
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

The attempt to merge lp:~zorba-coders/zorba/feature-fetch_binary into lp:zorba failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:274 (message):
  Validation queue job feature-fetch_binary-2012-05-09T01-28-08.563Z is
  finished. The final status was:

  13 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

10834. By Matthias Brantner

- documentation
- more robust tests

10835. By Matthias Brantner

fixed unintended indentation change

10836. By Matthias Brantner

improved error messages + warning fixes

10837. By Matthias Brantner

increase major version number of fetch module

10838. By Matthias Brantner

fetch became non-pure

10839. By Matthias Brantner

expose the SOME_CONTENT entity in the api

10840. By Matthias Brantner

merge + changelog

10841. By Matthias Brantner

change version of the fetch module (3.0 => 2.1)

10842. By Matthias Brantner

improved documentation

10843. By Matthias Brantner

code improvements as suggested by review

10844. By Matthias Brantner

added StaticContext::fetchBinary + StaticContext::fetch with encoding to C++ api

10845. By Matthias Brantner

documentation improvements

10846. By Matthias Brantner

merge

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2=== modified file 'include/zorba/uri_resolvers.h'
3--- include/zorba/uri_resolvers.h 2012-05-03 12:31:51 +0000
4+++ include/zorba/uri_resolvers.h 2012-05-09 21:52:19 +0000
5@@ -84,9 +84,11 @@
6 * @param aStreamReleaser A function pointer which is invoked once
7 * the StreamResource is destroyed. Normally this function will delete
8 * the std::istream object passed to it.
9+ * @param aIsStreamSeekable Determines whether the given stream is seekable.
10 */
11 static StreamResource* create(std::istream* aStream,
12- StreamReleaser aStreamReleaser);
13+ StreamReleaser aStreamReleaser,
14+ bool aIsStreamSeekable = false);
15
16 /**
17 * @brief Retrieve the istream associated with this Resource.
18@@ -99,6 +101,8 @@
19 virtual StreamReleaser getStreamReleaser() = 0;
20
21 virtual ~StreamResource() = 0;
22+
23+ virtual bool isStreamSeekable() const = 0;
24 };
25
26 /**
27
28=== modified file 'modules/com/zorba-xquery/www/modules/CMakeLists.txt'
29--- modules/com/zorba-xquery/www/modules/CMakeLists.txt 2012-05-03 12:31:51 +0000
30+++ modules/com/zorba-xquery/www/modules/CMakeLists.txt 2012-05-09 21:52:19 +0000
31@@ -43,7 +43,7 @@
32 DECLARE_ZORBA_SCHEMA(FILE xqdoc.xsd URI "http://www.xqdoc.org/1.0")
33 DECLARE_ZORBA_MODULE(FILE datetime.xq VERSION 2.0
34 URI "http://www.zorba-xquery.com/modules/datetime")
35-DECLARE_ZORBA_MODULE(FILE fetch.xq VERSION 2.0
36+DECLARE_ZORBA_MODULE(FILE fetch.xq VERSION 2.1
37 URI "http://www.zorba-xquery.com/modules/fetch")
38 DECLARE_ZORBA_MODULE(FILE math.xq VERSION 2.0
39 URI "http://www.zorba-xquery.com/modules/math")
40
41=== modified file 'modules/com/zorba-xquery/www/modules/fetch.xq'
42--- modules/com/zorba-xquery/www/modules/fetch.xq 2012-05-03 12:31:51 +0000
43+++ modules/com/zorba-xquery/www/modules/fetch.xq 2012-05-09 21:52:19 +0000
44@@ -17,15 +17,13 @@
45 :)
46
47 (:~
48- : This module provides functions to fetch the contents or the type
49- : of the content for a resource identified by a URI.
50- : For example, it fetches content for file or http resources if Zorba
51- : allows file or http access, respectively.
52- :
53- : <p>The errors raised by functions of this module have the namespace
54- : <tt>http://www.zorba-xquery.com/errors</tt> (associated with prefix zerr).</p>
55- :
56- : @see <a href="www.zorba-xquery.com_errors.html">http://www.zorba-xquery.com/errors</a>
57+ : <p>This module provides functions to fetch the content of a resource identified
58+ : by a URI. For example, it fetches the content of file or http resources.</p>
59+ :
60+ : <p>In order to retrieve such content, the functions use the
61+ : URI resolution and URL resolver process as documented at
62+ : <a href="../../html/uriresolvers.html">
63+ : URI Resolvers</a>.</p>
64 :
65 : @author Matthias Brantner
66 :
67@@ -38,23 +36,15 @@
68 declare namespace zerr = "http://www.zorba-xquery.com/errors";
69
70 declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
71-declare option ver:module-version "2.0";
72+declare option ver:module-version "2.1";
73
74 (:~
75 : <p>Tries to fetch the resource referred to by the given URI.</p>
76 :
77- : <p>In order to retrieve the content, the functions uses the
78- : URI resolution and URL resolver process as documented at
79- : <a href="../../html/uriresolvers.html">
80- : URI Resolvers</a>. Therefore, it queries all URI mappers
81- : and resolvers with kind <tt>EntityData::SOME_CONTENT</tt>.</p>
82+ : <p>It queries all URI mappers and resolvers with kind
83+ : <tt>EntityData::SOME_CONTENT</tt>.</p>
84 :
85- : <p>The function is annotated with the <tt>an:streamable</tt>
86- : annotation, that is it returns a streamable string. A streamable
87- : string can only be consumed once. Please see section "Streamable Strings"
88- : in the <a href="../../html/options_and_annotations.html">
89- : documentation of Zorba's annotations</a>.
90- : </p>
91+ : <p>The content is assumed to be UTF-8 encoded.</p>
92 :
93 : @param $uri the resource to fetch.
94 : @return the resource referred to by the given URI as streamble string.
95@@ -73,28 +63,85 @@
96 (:~
97 : <p>Tries to fetch the resource referred to by the given URI.</p>
98 :
99- : <p>In order to retrieve the content, the functions uses the
100- : URI resolution and URL resolver process as documented at
101- : <a href="../../html/uriresolvers.html">
102- : URI Resolvers</a>. Therefore, it queries all URI mappers
103- : and resolvers with the specified entity kind.</p>
104- :
105- : <p>The function is annotated with the <tt>an:streamable</tt>
106- : annotation, that is it returns a streamable string. A streamable
107- : string can only be consumed once. Please see section "Streamable Strings"
108- : in the <a href="../../html/options_and_annotations.html">
109- : documentation of Zorba's annotations</a>.
110- : </p>
111- :
112- : @param $uri the resource to fetch.
113- : @param $entityKind the kind of resource to fetch.
114- : @return the resource referred to by the given URI as streamble string.
115- :
116- : @error zerr:ZXQP0025 if the URI could not be resolved
117- : or did not resolve to a <tt>StreamResource</tt>.
118- :
119- : @see <a href="../../html/uriresolvers.html">URI Resolvers</a>.
120- : @see <a href="../../html/options_and_annotations.html">Documentation of Zorba's annotations</a>.
121- :)
122-
123-declare %an:streamable function fetch:content($uri as xs:string, $entityKind as xs:string) as xs:string external;
124+ : <p>It queries all URI mappers and resolvers with kind the specified
125+ : entity kind.</p>
126+ :
127+ : <p>The content is assumed to be UTF-8 encoded.</p>
128+ :
129+ : @param $uri the resource to fetch.
130+ : @param $entity-kind the kind of resource to fetch.
131+ : @return the resource referred to by the given URI as streamble string.
132+ :
133+ : @error zerr:ZXQP0025 if the URI could not be resolved
134+ : or did not resolve to a <tt>StreamResource</tt>.
135+ :
136+ : @see <a href="../../html/uriresolvers.html">URI Resolvers</a>.
137+ : @see <a href="../../html/options_and_annotations.html">Documentation of Zorba's annotations</a>.
138+ :)
139+declare %an:streamable function fetch:content($uri as xs:string, $entity-kind as xs:string)
140+as xs:string
141+{
142+ fetch:content($uri, $entity-kind, "UTF-8")
143+};
144+
145+(:~
146+ : <p>Tries to fetch the resource referred to by the given URI.</p>
147+ :
148+ : <p>It queries all URI mappers and resolvers with kind the specified
149+ : entity kind.</p>
150+ :
151+ : @param $uri the resource to fetch.
152+ : @param $entity-kind the kind of resource to fetch.
153+ : @param $encoding the encoding of the content
154+ : @return the resource referred to by the given URI as streamble string.
155+ :
156+ : @error zerr:ZXQP0025 if the URI could not be resolved
157+ : or did not resolve to a <tt>StreamResource</tt>.
158+ : @error zerr:ZXQP0006 if the given encoding is invalid or not supported.
159+ :
160+ : @see <a href="../../html/uriresolvers.html">URI Resolvers</a>.
161+ : @see <a href="../../html/options_and_annotations.html">Documentation of Zorba's annotations</a>.
162+ :)
163+declare %an:streamable function fetch:content(
164+ $uri as xs:string,
165+ $entity-kind as xs:string,
166+ $encoding as xs:string)
167+as xs:string external;
168+
169+(:~
170+ : <p>Tries to fetch the resource referred to by the given URI and
171+ : returning it as base64Binary.</p>
172+ :
173+ : <p>It queries all URI mappers and resolvers with kind
174+ : <tt>EntityData::SOME_CONTENT</tt>.</p>
175+
176+ : @param $uri the resource to fetch.
177+ : @return the resource referred to by the given URI as streamble base64Binary.
178+ :
179+ : @error zerr:ZXQP0025 if the URI could not be resolved
180+ : or did not resolve to a <tt>StreamResource</tt>.
181+ :)
182+declare %an:streamable function fetch:content-binary($uri as xs:string)
183+as xs:base64Binary
184+{
185+ fetch:content-binary($uri, "SOME_CONTENT")
186+};
187+
188+(:~
189+ : <p>Tries to fetch the resource referred to by the given URI and
190+ : returning it as base64Binary.</p>
191+ :
192+ : <p>It queries all URI mappers and resolvers with kind the specified
193+ : entity kind.</p>
194+ :
195+ : @param $uri the resource to fetch.
196+ : @param $entity-kind the kind of resource to fetch.
197+ : @return the resource referred to by the given URI as streamble base64Binary.
198+ :
199+ : @error zerr:ZXQP0025 if the URI could not be resolved
200+ : or did not resolve to a <tt>StreamResource</tt>.
201+ :)
202+declare %an:streamable function fetch:content-binary(
203+ $uri as xs:string,
204+ $entity-kind as xs:string)
205+as xs:base64Binary external;
206
207=== modified file 'src/api/uri_resolver_wrappers.cpp'
208--- src/api/uri_resolver_wrappers.cpp 2012-05-03 12:31:51 +0000
209+++ src/api/uri_resolver_wrappers.cpp 2012-05-09 21:52:19 +0000
210@@ -146,7 +146,9 @@
211 // StreamResource, by passing the StreamReleaser to it and setting the
212 // user's StreamResource's StreamReleaser to nullptr.
213 lRetval = new internal::StreamResource(lUserStream->getStream(),
214- lUserStream->getStreamReleaser());
215+ lUserStream->getStreamReleaser(),
216+ "",
217+ lUserStream->isStreamSeekable());
218 lUserStream->setStreamReleaser(nullptr);
219 }
220 #ifndef ZORBA_NO_FULL_TEXT
221
222=== modified file 'src/api/uriresolverimpl.cpp'
223--- src/api/uriresolverimpl.cpp 2012-05-03 12:31:51 +0000
224+++ src/api/uriresolverimpl.cpp 2012-05-09 21:52:19 +0000
225@@ -43,15 +43,18 @@
226 }
227
228 StreamResource* StreamResource::create(std::istream* aStream,
229- StreamReleaser aStreamReleaser)
230+ StreamReleaser aStreamReleaser,
231+ bool aIsStreamSeekable)
232 {
233- return new StreamResourceImpl(aStream, aStreamReleaser);
234+ return new StreamResourceImpl(aStream, aStreamReleaser, aIsStreamSeekable);
235 }
236
237 StreamResourceImpl::StreamResourceImpl(std::istream* aStream,
238- StreamReleaser aStreamReleaser)
239+ StreamReleaser aStreamReleaser,
240+ bool aIsStreamSeekable)
241 : theStream(aStream),
242- theStreamReleaser(aStreamReleaser)
243+ theStreamReleaser(aStreamReleaser),
244+ theIsStreamSeekable(aIsStreamSeekable)
245 {
246 }
247
248
249=== modified file 'src/api/uriresolverimpl.h'
250--- src/api/uriresolverimpl.h 2012-05-03 12:31:51 +0000
251+++ src/api/uriresolverimpl.h 2012-05-09 21:52:19 +0000
252@@ -39,14 +39,21 @@
253
254 virtual void destroy() const;
255
256+ virtual bool isStreamSeekable() const { return theIsStreamSeekable; }
257+
258 private:
259
260- StreamResourceImpl(std::istream* aStream, StreamReleaser aStreamReleaser);
261+ StreamResourceImpl(
262+ std::istream* aStream,
263+ StreamReleaser aStreamReleaser,
264+ bool aIsStreamSeekable);
265
266 friend StreamResource* StreamResource::create(std::istream *aStream,
267- StreamReleaser aStreamReleaser);
268+ StreamReleaser aStreamReleaser,
269+ bool aIsStreamSeekable);
270 std::istream* theStream;
271 StreamReleaser theStreamReleaser;
272+ bool theIsStreamSeekable;
273
274 };
275
276
277=== modified file 'src/context/default_url_resolvers.cpp'
278--- src/context/default_url_resolvers.cpp 2012-05-03 12:31:51 +0000
279+++ src/context/default_url_resolvers.cpp 2012-05-09 21:52:19 +0000
280@@ -107,7 +107,8 @@
281 zstring lPath = fs::get_normalized_path(aUrl);
282 if (fs::get_type(lPath) == fs::file) {
283 std::ifstream* lStream = new std::ifstream(lPath.c_str());
284- return new StreamResource(lStream, &fileStreamReleaser);
285+ return new StreamResource(
286+ lStream, &fileStreamReleaser, "", true /* seekable */);
287 }
288 return NULL;
289 }
290
291=== modified file 'src/context/uri_resolver.cpp'
292--- src/context/uri_resolver.cpp 2012-05-03 12:31:51 +0000
293+++ src/context/uri_resolver.cpp 2012-05-09 21:52:19 +0000
294@@ -46,11 +46,13 @@
295
296 StreamResource::StreamResource
297 (std::istream* aStream, StreamReleaser aStreamReleaser,
298- zstring aStreamUrl /* = "" */)
299+ zstring aStreamUrl /* = "" */,
300+ bool aIsStreamSeekable)
301 : Resource(),
302 theStream(aStream),
303 theStreamReleaser(aStreamReleaser),
304- theStreamUrl(aStreamUrl)
305+ theStreamUrl(aStreamUrl),
306+ theIsStreamSeekable(aIsStreamSeekable)
307 {}
308
309 StreamResource::~StreamResource()
310
311=== modified file 'src/context/uri_resolver.h'
312--- src/context/uri_resolver.h 2012-05-03 12:31:51 +0000
313+++ src/context/uri_resolver.h 2012-05-09 21:52:19 +0000
314@@ -97,10 +97,13 @@
315 * are certain unusual circumstances where a URLResolver may wish to
316 * return a stream over some other URL than the one passed to it. In
317 * that case, the URLResolver may pass the true URL here.
318+ * @param aIsStreamSeekable determines whether the stream passed as first
319+ * argument is seekable.
320 */
321 StreamResource(std::istream* aStream,
322 StreamReleaser aStreamReleaser,
323- zstring aStreamUrl = "");
324+ zstring aStreamUrl = "",
325+ bool aIsStreamSeekable = false);
326
327 virtual ~StreamResource();
328
329@@ -127,11 +130,18 @@
330 */
331 zstring getStreamUrl();
332
333+ /**
334+ * @brief Returns true if the stream returned by getStream is seekable,
335+ * false otherwise.
336+ */
337+ bool isStreamSeekable() const { return theIsStreamSeekable; }
338+
339 private:
340
341 std::istream* theStream;
342 StreamReleaser theStreamReleaser;
343 zstring theStreamUrl;
344+ bool theIsStreamSeekable;
345 };
346
347 /**
348
349=== modified file 'src/functions/pregenerated/func_fetch.cpp'
350--- src/functions/pregenerated/func_fetch.cpp 2012-05-03 12:31:51 +0000
351+++ src/functions/pregenerated/func_fetch.cpp 2012-05-09 21:52:19 +0000
352@@ -41,6 +41,16 @@
353 return new FetchContentIterator(sctx, loc, argv);
354 }
355
356+PlanIter_t fn_zorba_fetch_content_binary::codegen(
357+ CompilerCB*,
358+ static_context* sctx,
359+ const QueryLoc& loc,
360+ std::vector<PlanIter_t>& argv,
361+ expr& ann) const
362+{
363+ return new FetchContentBinaryIterator(sctx, loc, argv);
364+}
365+
366 PlanIter_t fn_zorba_fetch_content_type::codegen(
367 CompilerCB*,
368 static_context* sctx,
369@@ -60,8 +70,22 @@
370 (createQName("http://www.zorba-xquery.com/modules/fetch","","content"),
371 GENV_TYPESYSTEM.STRING_TYPE_ONE,
372 GENV_TYPESYSTEM.STRING_TYPE_ONE,
373+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
374 GENV_TYPESYSTEM.STRING_TYPE_ONE),
375- FunctionConsts::FN_ZORBA_FETCH_CONTENT_2);
376+ FunctionConsts::FN_ZORBA_FETCH_CONTENT_3);
377+
378+ }
379+
380+
381+ {
382+
383+
384+ DECL_WITH_KIND(sctx, fn_zorba_fetch_content_binary,
385+ (createQName("http://www.zorba-xquery.com/modules/fetch","","content-binary"),
386+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
387+ GENV_TYPESYSTEM.STRING_TYPE_ONE,
388+ GENV_TYPESYSTEM.BASE64BINARY_TYPE_ONE),
389+ FunctionConsts::FN_ZORBA_FETCH_CONTENT_BINARY_2);
390
391 }
392
393
394=== modified file 'src/functions/pregenerated/func_fetch.h'
395--- src/functions/pregenerated/func_fetch.h 2012-05-03 12:31:51 +0000
396+++ src/functions/pregenerated/func_fetch.h 2012-05-09 21:52:19 +0000
397@@ -55,6 +55,23 @@
398 };
399
400
401+//fn-zorba-fetch:content-binary
402+class fn_zorba_fetch_content_binary : public function
403+{
404+public:
405+ fn_zorba_fetch_content_binary(const signature& sig, FunctionConsts::FunctionKind kind)
406+ :
407+ function(sig, kind)
408+ {
409+
410+ }
411+
412+ bool accessesDynCtx() const { return true; }
413+
414+ CODEGEN_DECL();
415+};
416+
417+
418 //fn-zorba-fetch:content-type
419 class fn_zorba_fetch_content_type : public function
420 {
421
422=== modified file 'src/functions/pregenerated/function_enum.h'
423--- src/functions/pregenerated/function_enum.h 2012-05-08 03:09:12 +0000
424+++ src/functions/pregenerated/function_enum.h 2012-05-09 21:52:19 +0000
425@@ -137,7 +137,8 @@
426 FN_TRACE_2,
427 OP_ZORBA_READ_LINE_0,
428 FN_ZORBA_UTIL_PRINT_1,
429- FN_ZORBA_FETCH_CONTENT_2,
430+ FN_ZORBA_FETCH_CONTENT_3,
431+ FN_ZORBA_FETCH_CONTENT_BINARY_2,
432 FN_ZORBA_FETCH_CONTENT_TYPE_1,
433 FN_PUT_2,
434 FULL_TEXT_CURRENT_LANG_0,
435
436=== modified file 'src/runtime/fetch/fetch_impl.cpp'
437--- src/runtime/fetch/fetch_impl.cpp 2012-05-03 12:31:51 +0000
438+++ src/runtime/fetch/fetch_impl.cpp 2012-05-09 21:52:19 +0000
439@@ -15,6 +15,8 @@
440 */
441 #include "stdafx.h"
442
443+#include <zorba/transcode_stream.h>
444+
445 #include "diagnostics/assert.h"
446 #include "diagnostics/xquery_diagnostics.h"
447
448@@ -30,33 +32,17 @@
449
450 /*******************************************************************************
451 ********************************************************************************/
452-void
453-FetchContentIterator::destroyStream(std::istream& aStream)
454-{
455- delete &aStream;
456-}
457-
458-bool
459-FetchContentIterator::nextImpl(
460- store::Item_t& result,
461- PlanState& aPlanState) const
462-{
463- store::Item_t lUri;
464- store::Item_t lEntityKind;
465+std::auto_ptr<internal::Resource>
466+getFetchResource(
467+ const store::Item_t& aUri,
468+ const store::Item_t& aKind,
469+ const static_context* aSctx,
470+ const QueryLoc& aLoc)
471+{
472 internal::EntityData::Kind lKind;
473- zstring lKindStr;
474- zstring lErrorMessage;
475- std::auto_ptr<internal::Resource> lRes;
476- internal::StreamResource* lStreamRes;
477-
478- PlanIteratorState* state;
479- DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
480-
481- consumeNext(lUri, theChildren[0].getp(), aPlanState);
482- consumeNext(lEntityKind, theChildren[1].getp(), aPlanState);
483+ zstring lKindStr = aKind->getStringValue();
484
485 // Figure out the EntityKind (any better way to do this?)
486- lKindStr = lEntityKind->getStringValue();
487 if ( ! lKindStr.compare("SOME_CONTENT")) {
488 lKind = internal::EntityData::SOME_CONTENT;
489 }
490@@ -70,7 +56,7 @@
491 else if ( ! lKindStr.compare("THESAURUS")) {
492 lKind = internal::EntityData::THESAURUS;
493 }
494- else if ( ! lKindStr.compare("STOP_WORDS")) {
495+ else if ( ! lKindStr.compare("STOP_WORDS")){
496 lKind = internal::EntityData::STOP_WORDS;
497 }
498 #endif /* ZORBA_NO_FULL_TEXT */
499@@ -78,14 +64,15 @@
500 throw XQUERY_EXCEPTION(
501 zerr::ZXQP0026_INVALID_ENUM_VALUE,
502 ERROR_PARAMS(lKindStr, "entityKind"),
503- ERROR_LOC(loc));
504+ ERROR_LOC(aLoc));
505 }
506
507 try {
508 // ask the uri mappers and resolvers to give
509 // me a resource of specified kind
510- lRes = theSctx->resolve_uri(
511- lUri->getStringValue(),
512+ zstring lErrorMessage;
513+ return aSctx->resolve_uri(
514+ aUri->getStringValue(),
515 lKind,
516 lErrorMessage);
517
518@@ -93,9 +80,41 @@
519 throw XQUERY_EXCEPTION(
520 zerr::ZXQP0025_ITEM_CREATION_FAILED,
521 ERROR_PARAMS( e.what() ),
522- ERROR_LOC( loc )
523+ ERROR_LOC( aLoc )
524 );
525 }
526+}
527+
528+/*******************************************************************************
529+********************************************************************************/
530+void
531+FetchContentIterator::destroyStream(std::istream& aStream)
532+{
533+ delete &aStream;
534+}
535+
536+bool
537+FetchContentIterator::nextImpl(
538+ store::Item_t& result,
539+ PlanState& aPlanState) const
540+{
541+ store::Item_t lUri;
542+ store::Item_t lEntityKind;
543+ store::Item_t lEncoding;
544+ zstring lEncodingStr("UTF-8");
545+ std::auto_ptr<internal::Resource> lRes;
546+ internal::StreamResource* lStreamRes;
547+
548+ PlanIteratorState* state;
549+ DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
550+
551+ consumeNext(lUri, theChildren[0].getp(), aPlanState);
552+ consumeNext(lEntityKind, theChildren[1].getp(), aPlanState);
553+ consumeNext(lEncoding, theChildren[2].getp(), aPlanState);
554+
555+ lEncodingStr = lEncoding->getStringValue();
556+
557+ lRes = getFetchResource(lUri, lEntityKind, theSctx, loc);
558
559 lStreamRes = dynamic_cast<internal::StreamResource*>(lRes.get());
560 if ( !lStreamRes ) {
561@@ -106,13 +125,80 @@
562 );
563 }
564
565+ if (transcode::is_necessary(lEncodingStr.c_str()))
566+ {
567+ if (!transcode::is_supported(lEncodingStr.c_str()))
568+ {
569+ throw XQUERY_EXCEPTION(
570+ zerr::ZXQP0006_UNKNOWN_ENCODING,
571+ ERROR_PARAMS( lEncodingStr.c_str() ),
572+ ERROR_LOC( loc )
573+ );
574+ }
575+ transcode::attach(*lStreamRes->getStream(), lEncodingStr.c_str());
576+ }
577+
578 // return the resource in a streamable string. This transfers memory
579 // ownership of the istream (via its StreamReleaser) to the StreamableString
580 // object, so we then remove the StreamReleaser from the StreamResource.
581 GENV_ITEMFACTORY->createStreamableString(
582 result,
583 *lStreamRes->getStream(),
584- lStreamRes->getStreamReleaser()
585+ lStreamRes->getStreamReleaser(),
586+ lStreamRes->isStreamSeekable()
587+ );
588+ lStreamRes->setStreamReleaser(nullptr);
589+
590+ STACK_PUSH(result != NULL, state);
591+
592+ STACK_END(state);
593+}
594+
595+
596+/*******************************************************************************
597+********************************************************************************/
598+void
599+FetchContentBinaryIterator::destroyStream(std::istream& aStream)
600+{
601+ delete &aStream;
602+}
603+
604+bool
605+FetchContentBinaryIterator::nextImpl(
606+ store::Item_t& result,
607+ PlanState& aPlanState) const
608+{
609+ store::Item_t lUri;
610+ store::Item_t lEntityKind;
611+ std::auto_ptr<internal::Resource> lRes;
612+ internal::StreamResource* lStreamRes;
613+
614+ PlanIteratorState* state;
615+ DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
616+
617+ consumeNext(lUri, theChildren[0].getp(), aPlanState);
618+ consumeNext(lEntityKind, theChildren[1].getp(), aPlanState);
619+
620+ lRes = getFetchResource(lUri, lEntityKind, theSctx, loc);
621+
622+ lStreamRes = dynamic_cast<internal::StreamResource*>(lRes.get());
623+ if ( !lStreamRes ) {
624+ throw XQUERY_EXCEPTION(
625+ zerr::ZXQP0025_ITEM_CREATION_FAILED,
626+ ERROR_PARAMS( "Resource not available." ),
627+ ERROR_LOC( loc )
628+ );
629+ }
630+
631+ // return the resource in a streamable base64. This transfers memory
632+ // ownership of the istream (via its StreamReleaser) to the StreamableBase64BinaryItem
633+ // object, so we then remove the StreamReleaser from the StreamResource.
634+ GENV_ITEMFACTORY->createStreamableBase64Binary(
635+ result,
636+ *lStreamRes->getStream(),
637+ lStreamRes->getStreamReleaser(),
638+ lStreamRes->isStreamSeekable(),
639+ false
640 );
641 lStreamRes->setStreamReleaser(nullptr);
642
643
644=== modified file 'src/runtime/fetch/pregenerated/fetch.cpp'
645--- src/runtime/fetch/pregenerated/fetch.cpp 2012-05-03 12:31:51 +0000
646+++ src/runtime/fetch/pregenerated/fetch.cpp 2012-05-09 21:52:19 +0000
647@@ -54,6 +54,28 @@
648 // </FetchContentIterator>
649
650
651+// <FetchContentBinaryIterator>
652+FetchContentBinaryIterator::class_factory<FetchContentBinaryIterator>
653+FetchContentBinaryIterator::g_class_factory;
654+
655+
656+void FetchContentBinaryIterator::accept(PlanIterVisitor& v) const {
657+ v.beginVisit(*this);
658+
659+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
660+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
661+ for ( ; lIter != lEnd; ++lIter ){
662+ (*lIter)->accept(v);
663+ }
664+
665+ v.endVisit(*this);
666+}
667+
668+FetchContentBinaryIterator::~FetchContentBinaryIterator() {}
669+
670+// </FetchContentBinaryIterator>
671+
672+
673 // <FetchContentTypeIterator>
674 FetchContentTypeIterator::class_factory<FetchContentTypeIterator>
675 FetchContentTypeIterator::g_class_factory;
676
677=== modified file 'src/runtime/fetch/pregenerated/fetch.h'
678--- src/runtime/fetch/pregenerated/fetch.h 2012-05-03 12:31:51 +0000
679+++ src/runtime/fetch/pregenerated/fetch.h 2012-05-09 21:52:19 +0000
680@@ -73,6 +73,42 @@
681 *
682 * Author: Matthias Brantner
683 */
684+class FetchContentBinaryIterator : public NaryBaseIterator<FetchContentBinaryIterator, PlanIteratorState>
685+{
686+public:
687+ SERIALIZABLE_CLASS(FetchContentBinaryIterator);
688+
689+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(FetchContentBinaryIterator,
690+ NaryBaseIterator<FetchContentBinaryIterator, PlanIteratorState>);
691+
692+ void serialize( ::zorba::serialization::Archiver& ar)
693+ {
694+ serialize_baseclass(ar,
695+ (NaryBaseIterator<FetchContentBinaryIterator, PlanIteratorState>*)this);
696+ }
697+
698+ FetchContentBinaryIterator(
699+ static_context* sctx,
700+ const QueryLoc& loc,
701+ std::vector<PlanIter_t>& children)
702+ :
703+ NaryBaseIterator<FetchContentBinaryIterator, PlanIteratorState>(sctx, loc, children)
704+ {}
705+
706+ virtual ~FetchContentBinaryIterator();
707+
708+public:
709+ static void destroyStream(std::istream& aStream);
710+ void accept(PlanIterVisitor& v) const;
711+
712+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
713+};
714+
715+
716+/**
717+ *
718+ * Author: Matthias Brantner
719+ */
720 class FetchContentTypeIterator : public NaryBaseIterator<FetchContentTypeIterator, PlanIteratorState>
721 {
722 public:
723
724=== modified file 'src/runtime/nodes/nodes_impl.cpp'
725--- src/runtime/nodes/nodes_impl.cpp 2012-05-03 12:31:51 +0000
726+++ src/runtime/nodes/nodes_impl.cpp 2012-05-09 21:52:19 +0000
727@@ -638,11 +638,13 @@
728 lIterator->open();
729 while(lIterator->next(lItem))
730 {
731- if(lItem->getNodeKind() == aNode->getNodeKind())
732+ if (lItem->getNodeKind() == aNode->getNodeKind())
733+ {
734 if(lItem->equals(aNode))
735 break;
736 else
737 count++;
738+ }
739 }
740 lIterator->close();
741 return count;
742@@ -663,7 +665,7 @@
743 PlanIteratorState* state;
744 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
745
746- if (consumeNext(inNode, theChildren[0], planState));
747+ if (consumeNext(inNode, theChildren[0], planState))
748 {
749 do
750 {
751
752=== modified file 'src/runtime/spec/fetch/fetch.xml'
753--- src/runtime/spec/fetch/fetch.xml 2012-05-03 12:31:51 +0000
754+++ src/runtime/spec/fetch/fetch.xml 2012-05-09 21:52:19 +0000
755@@ -16,7 +16,8 @@
756 <zorba:function>
757 <zorba:signature localname="content" prefix="fn-zorba-fetch">
758 <zorba:param>xs:string</zorba:param>
759- <zorba:param>xs:string</zorba:param>
760+ <zorba:param>xs:string</zorba:param> <!-- entityKind -->
761+ <zorba:param>xs:string</zorba:param> <!-- encoding -->
762 <zorba:output>xs:string</zorba:output>
763 </zorba:signature>
764
765@@ -25,8 +26,33 @@
766 </zorba:methods>
767 </zorba:function>
768
769- <zorba:method static="true" name="destroyStream"
770- return="void">
771+ <zorba:method static="true" name="destroyStream" return="void">
772+ <zorba:param type="std::istream&amp;" name="aStream"/>
773+ </zorba:method>
774+
775+</zorba:iterator>
776+
777+<!--
778+/*********************************************************************
779+*********************************************************************/
780+-->
781+<zorba:iterator name="FetchContentBinaryIterator">
782+
783+ <zorba:description author="Matthias Brantner"></zorba:description>
784+
785+ <zorba:function>
786+ <zorba:signature localname="content-binary" prefix="fn-zorba-fetch">
787+ <zorba:param>xs:string</zorba:param>
788+ <zorba:param>xs:string</zorba:param>
789+ <zorba:output>xs:base64Binary</zorba:output>
790+ </zorba:signature>
791+
792+ <zorba:methods>
793+ <zorba:accessesDynCtx returnValue="true"/>
794+ </zorba:methods>
795+ </zorba:function>
796+
797+ <zorba:method static="true" name="destroyStream" return="void">
798 <zorba:param type="std::istream&amp;" name="aStream"/>
799 </zorba:method>
800
801
802=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
803--- src/runtime/visitors/pregenerated/planiter_visitor.h 2012-05-03 12:31:51 +0000
804+++ src/runtime/visitors/pregenerated/planiter_visitor.h 2012-05-09 21:52:19 +0000
805@@ -189,6 +189,8 @@
806
807 class FetchContentIterator;
808
809+ class FetchContentBinaryIterator;
810+
811 class FetchContentTypeIterator;
812
813 class FnPutIterator;
814@@ -897,6 +899,9 @@
815 virtual void beginVisit ( const FetchContentIterator& ) = 0;
816 virtual void endVisit ( const FetchContentIterator& ) = 0;
817
818+ virtual void beginVisit ( const FetchContentBinaryIterator& ) = 0;
819+ virtual void endVisit ( const FetchContentBinaryIterator& ) = 0;
820+
821 virtual void beginVisit ( const FetchContentTypeIterator& ) = 0;
822 virtual void endVisit ( const FetchContentTypeIterator& ) = 0;
823
824
825=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
826--- src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-05-03 12:31:51 +0000
827+++ src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-05-09 21:52:19 +0000
828@@ -1219,6 +1219,20 @@
829 // </FetchContentIterator>
830
831
832+// <FetchContentBinaryIterator>
833+void PrinterVisitor::beginVisit ( const FetchContentBinaryIterator& a) {
834+ thePrinter.startBeginVisit("FetchContentBinaryIterator", ++theId);
835+ printCommons( &a, theId );
836+ thePrinter.endBeginVisit( theId );
837+}
838+
839+void PrinterVisitor::endVisit ( const FetchContentBinaryIterator& ) {
840+ thePrinter.startEndVisit();
841+ thePrinter.endEndVisit();
842+}
843+// </FetchContentBinaryIterator>
844+
845+
846 // <FetchContentTypeIterator>
847 void PrinterVisitor::beginVisit ( const FetchContentTypeIterator& a) {
848 thePrinter.startBeginVisit("FetchContentTypeIterator", ++theId);
849
850=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
851--- src/runtime/visitors/pregenerated/printer_visitor.h 2012-05-03 12:31:51 +0000
852+++ src/runtime/visitors/pregenerated/printer_visitor.h 2012-05-09 21:52:19 +0000
853@@ -286,6 +286,9 @@
854 void beginVisit( const FetchContentIterator& );
855 void endVisit ( const FetchContentIterator& );
856
857+ void beginVisit( const FetchContentBinaryIterator& );
858+ void endVisit ( const FetchContentBinaryIterator& );
859+
860 void beginVisit( const FetchContentTypeIterator& );
861 void endVisit ( const FetchContentTypeIterator& );
862
863
864=== added file 'test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable.xml.res'
865--- test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable.xml.res 1970-01-01 00:00:00 +0000
866+++ test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable.xml.res 2012-05-09 21:52:19 +0000
867@@ -0,0 +1,1 @@
868+true true true
869
870=== added file 'test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable_binary.xml.res'
871--- test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable_binary.xml.res 1970-01-01 00:00:00 +0000
872+++ test/rbkt/ExpQueryResults/zorba/fetch/fetch_seekable_binary.xml.res 2012-05-09 21:52:19 +0000
873@@ -0,0 +1,1 @@
874+8 5Pb8Cg==
875
876=== added file 'test/rbkt/ExpQueryResults/zorba/fetch/fetch_some_transcode.xml.res'
877--- test/rbkt/ExpQueryResults/zorba/fetch/fetch_some_transcode.xml.res 1970-01-01 00:00:00 +0000
878+++ test/rbkt/ExpQueryResults/zorba/fetch/fetch_some_transcode.xml.res 2012-05-09 21:52:19 +0000
879@@ -0,0 +1,1 @@
880+äöü
881
882=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_bogus1.xq'
883--- test/rbkt/Queries/zorba/fetch/fetch_bogus1.xq 2012-05-03 12:31:51 +0000
884+++ test/rbkt/Queries/zorba/fetch/fetch_bogus1.xq 2012-05-09 21:52:19 +0000
885@@ -1,4 +1,4 @@
886 (: Fetch with unknown entity kind :)
887-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
888+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
889
890 fetch:content("http://www.zorba-xquery.com/modules/ext", "NOTHING")
891
892=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_bogus2.xq'
893--- test/rbkt/Queries/zorba/fetch/fetch_bogus2.xq 2012-05-03 12:31:51 +0000
894+++ test/rbkt/Queries/zorba/fetch/fetch_bogus2.xq 2012-05-09 21:52:19 +0000
895@@ -1,4 +1,4 @@
896 (: Fetch a valid module URI but as SOME_CONTENT :)
897-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
898+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
899
900 fetch:content("http://www.flworfound.org/modules/ext", "SOME_CONTENT")
901
902=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_module1.xq'
903--- test/rbkt/Queries/zorba/fetch/fetch_module1.xq 2012-05-03 12:31:51 +0000
904+++ test/rbkt/Queries/zorba/fetch/fetch_module1.xq 2012-05-09 21:52:19 +0000
905@@ -1,4 +1,4 @@
906 (: Fetch a module's content :)
907-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
908+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
909
910 fetch:content("http://www.zorba-xquery.com/modules/ext", "MODULE")
911
912=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_module2.xq'
913--- test/rbkt/Queries/zorba/fetch/fetch_module2.xq 2012-05-03 12:31:51 +0000
914+++ test/rbkt/Queries/zorba/fetch/fetch_module2.xq 2012-05-09 21:52:19 +0000
915@@ -1,4 +1,4 @@
916 (: Fetch a module's content with versioning :)
917-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
918+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
919
920 fetch:content("http://www.zorba-xquery.com/modules/ext#1.0", "MODULE")
921
922=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_random_file.xq'
923--- test/rbkt/Queries/zorba/fetch/fetch_random_file.xq 2012-02-01 17:13:01 +0000
924+++ test/rbkt/Queries/zorba/fetch/fetch_random_file.xq 2012-05-09 21:52:19 +0000
925@@ -1,4 +1,4 @@
926 (: Fetch a random file from the filesystem :)
927-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
928+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
929
930 fetch:content("http://www.zorba-xquery.com/random-file", "SOME_CONTENT")
931
932=== modified file 'test/rbkt/Queries/zorba/fetch/fetch_schema1.xq'
933--- test/rbkt/Queries/zorba/fetch/fetch_schema1.xq 2012-05-03 12:31:51 +0000
934+++ test/rbkt/Queries/zorba/fetch/fetch_schema1.xq 2012-05-09 21:52:19 +0000
935@@ -1,5 +1,5 @@
936 (: Fetch a schemas's content :)
937-import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch#2.0";
938+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
939
940 fn:parse-xml(
941 fetch:content("http://www.zorba-xquery.com/modules/theschema", "SCHEMA")
942
943=== added file 'test/rbkt/Queries/zorba/fetch/fetch_seekable.xml.res'
944--- test/rbkt/Queries/zorba/fetch/fetch_seekable.xml.res 1970-01-01 00:00:00 +0000
945+++ test/rbkt/Queries/zorba/fetch/fetch_seekable.xml.res 2012-05-09 21:52:19 +0000
946@@ -0,0 +1,1 @@
947+true true true
948
949=== added file 'test/rbkt/Queries/zorba/fetch/fetch_seekable.xq'
950--- test/rbkt/Queries/zorba/fetch/fetch_seekable.xq 1970-01-01 00:00:00 +0000
951+++ test/rbkt/Queries/zorba/fetch/fetch_seekable.xq 2012-05-09 21:52:19 +0000
952@@ -0,0 +1,8 @@
953+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
954+
955+import module namespace s = "http://www.zorba-xquery.com/modules/string";
956+
957+(: make sure the returned string is streamable and can be consumed twice, i.e. is seekable :)
958+let $x := fetch:content(fn:resolve-uri("iso-8859-1.txt"))
959+return (s:is-streamable($x), string-length($x) gt 0, string-length($x) gt 0)
960+
961
962=== added file 'test/rbkt/Queries/zorba/fetch/fetch_seekable_binary.xq'
963--- test/rbkt/Queries/zorba/fetch/fetch_seekable_binary.xq 1970-01-01 00:00:00 +0000
964+++ test/rbkt/Queries/zorba/fetch/fetch_seekable_binary.xq 2012-05-09 21:52:19 +0000
965@@ -0,0 +1,8 @@
966+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
967+
968+import module namespace b = "http://www.zorba-xquery.com/modules/converters/base64";
969+
970+(: make sure the returned string is streamable and can be consumed twice, i.e. is seekable :)
971+let $x := fetch:content-binary(fn:resolve-uri("iso-8859-1.txt"))
972+return (string-length(xs:string($x)), $x)
973+
974
975=== added file 'test/rbkt/Queries/zorba/fetch/fetch_some_transcode.xq'
976--- test/rbkt/Queries/zorba/fetch/fetch_some_transcode.xq 1970-01-01 00:00:00 +0000
977+++ test/rbkt/Queries/zorba/fetch/fetch_some_transcode.xq 2012-05-09 21:52:19 +0000
978@@ -0,0 +1,3 @@
979+import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";
980+
981+fetch:content(resolve-uri("iso-8859-1.txt"), "SOME_CONTENT", "ISO-8859-1")
982
983=== added file 'test/rbkt/Queries/zorba/fetch/iso-8859-1.txt'
984--- test/rbkt/Queries/zorba/fetch/iso-8859-1.txt 1970-01-01 00:00:00 +0000
985+++ test/rbkt/Queries/zorba/fetch/iso-8859-1.txt 2012-05-09 21:52:19 +0000
986@@ -0,0 +1,1 @@
987+äöü

Subscribers

People subscribed via source and target branches