Merge lp:~zorba-coders/zorba/ft-base64Binary into lp:zorba

Proposed by Matthias Brantner
Status: Merged
Approved by: Till Westmann
Approved revision: 10674
Merged at revision: 10677
Proposed branch: lp:~zorba-coders/zorba/ft-base64Binary
Merge into: lp:zorba
Diff against target: 1259 lines (+739/-105)
31 files modified
ChangeLog (+1/-0)
include/zorba/item.h (+23/-0)
include/zorba/item_factory.h (+20/-1)
modules/com/zorba-xquery/www/modules/converters/base64.xq (+6/-3)
modules/org/expath/ns/file.xq.src/file.cpp (+8/-13)
modules/org/expath/ns/file.xq.src/file_function.cpp (+20/-4)
src/api/item.cpp (+23/-0)
src/api/itemfactoryimpl.cpp (+20/-1)
src/api/itemfactoryimpl.h (+7/-0)
src/api/options.cpp (+1/-0)
src/api/serialization/serializer.cpp (+86/-40)
src/runtime/base64/base64_impl.cpp (+53/-21)
src/store/api/item.h (+8/-1)
src/store/api/item_factory.h (+25/-0)
src/store/naive/atomic_items.cpp (+204/-6)
src/store/naive/atomic_items.h (+97/-8)
src/store/naive/item.cpp (+19/-1)
src/store/naive/simple_item_factory.cpp (+30/-3)
src/store/naive/simple_item_factory.h (+13/-0)
src/types/casting.cpp (+12/-1)
src/zorbaserialization/zorba_class_serializer.cpp (+25/-2)
src/zorbatypes/binary.cpp (+10/-0)
test/rbkt/ExpQueryResults/zorba/base64/binary_1.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/base64/file_read_1.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/base64/file_read_2.xml.res (+1/-0)
test/rbkt/Queries/zorba/base64/binary_1.xq (+1/-0)
test/rbkt/Queries/zorba/base64/decoded-text (+1/-0)
test/rbkt/Queries/zorba/base64/encoded (+1/-0)
test/rbkt/Queries/zorba/base64/encoded-text (+1/-0)
test/rbkt/Queries/zorba/base64/file_read_1.xq (+10/-0)
test/rbkt/Queries/zorba/base64/file_read_2.xq (+11/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/ft-base64Binary
Reviewer Review Type Date Requested Status
Till Westmann Approve
Matthias Brantner Approve
Review via email: mp+94494@code.launchpad.net

This proposal supersedes a proposal from 2012-02-22.

Commit message

more efficient implementation of xs:base64Binary items

Description of the change

more efficient implementation of xs:base64Binary items

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

The attempt to merge lp:~zorba-coders/zorba/ft-base64Binary 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 ft-base64Binary-2012-02-22T01-41-08.742Z is finished.
  The final status was:

  7 tests did not succeed - changes not commited.

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

Revision history for this message
Matthias Brantner (matthias-brantner) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal

Validation queue job ft-base64Binary-2012-02-22T04-06-19.662Z is finished. The final status was:

All tests succeeded!

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1. Got: 1 Approve, 1 Pending.

Revision history for this message
Dennis Knochenwefel (dennis-knochenwefel) wrote : Posted in a previous version of this proposal

this also fixes bug #933490

Revision history for this message
Till Westmann (tillw) wrote : Posted in a previous version of this proposal

include/zorba/item.h: Docs do not say what happens, if
getBase64BinaryValue is called when the item is streamable.

include/zorba/item_factory.h: "whence" isn't the most commonly used word
(http://en.wiktionary.org/wiki/whence) maybe we could use another one

src/runtime/base64/base64_impl.cpp:43 is it ok to ignore the result of
consumeNext because the input can't be an empty sequence? If so, should
we add a comment?

Could we implement Base64BinaryItem::getStringValue() using
Base64BinaryItem::getStringValue2(zstring& val)?

Does Base64BinaryItem::getStringValue2(zstring& val) work if val is not
empty? It seems that theValue would be prepended to the current content
of val. Could we implement this method by emptying val and calling
Base64BinaryItem::appendStringValue on it?

StreamableBase64BinaryItem::materialize():
- Is there a reason for the number 4048?
- In general those might be a lot of re-allocations, if the item is a
  little larger (e.g. if the item is 1MB, we've got more than 250
  re-allocations). I'm not sure where the right trade-off is, but it
  seems that this parameter might become expensive (if someone
  materializes a large item that should be streamed …)

I just hope that src/zorbaserialization/zorba_class_serializer.cpp works.

review: Approve
Revision history for this message
Matthias Brantner (matthias-brantner) wrote : Posted in a previous version of this proposal

> include/zorba/item.h: Docs do not say what happens, if
> getBase64BinaryValue is called when the item is streamable.
fixed

>
> include/zorba/item_factory.h: "whence" isn't the most commonly used word
> (http://en.wiktionary.org/wiki/whence) maybe we could use another one
fixed (although the comment was originally written by a native speaker ;-)
>
> src/runtime/base64/base64_impl.cpp:43 is it ok to ignore the result of
> consumeNext because the input can't be an empty sequence? If so, should
> we add a comment?
this is common practice in almost every iterator. It's not possible that
consumeNext returns false if the sequence-type of the function doesn't allow
the empty sequence.

>
> Could we implement Base64BinaryItem::getStringValue() using
> Base64BinaryItem::getStringValue2(zstring& val)?
done

>
> Does Base64BinaryItem::getStringValue2(zstring& val) work if val is not
> empty? It seems that theValue would be prepended to the current content
> of val. Could we implement this method by emptying val and calling
> Base64BinaryItem::appendStringValue on it?
fixed & done

> StreamableBase64BinaryItem::materialize():
> - Is there a reason for the number 4048?
no - I have no idea what the best value would be

> - In general those might be a lot of re-allocations, if the item is a
> little larger (e.g. if the item is 1MB, we've got more than 250
> re-allocations). I'm not sure where the right trade-off is, but it
> seems that this parameter might become expensive (if someone
> materializes a large item that should be streamed …)
Yes, it's really expensive if the stream is not seekable. The situation
is much better if the stream is seekable but I have no idea how to improve
the materialize if not.
>
> I just hope that src/zorbaserialization/zorba_class_serializer.cpp works.
me too

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 job ft-base64Binary-2012-02-24T04-04-11.789Z is finished. The final status was:

All tests succeeded!

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

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1. Got: 1 Approve, 1 Pending.

Revision history for this message
Till Westmann (tillw) :
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 job ft-base64Binary-2012-02-24T04-40-03.106Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2012-02-23 16:41:10 +0000
+++ ChangeLog 2012-02-24 04:03:18 +0000
@@ -21,6 +21,7 @@
21 * Fixed bug #911585 (management of variables during eval)21 * Fixed bug #911585 (management of variables during eval)
22 * Fixed bug #866423 (fn:empty and fn:exists iterators must reset their input in22 * Fixed bug #866423 (fn:empty and fn:exists iterators must reset their input in
23 case of early-out)23 case of early-out)
24 * More efficient implementation for base64Binary items
24 * Added index management function to the C++ api's StaticCollectionManager.25 * Added index management function to the C++ api's StaticCollectionManager.
25 * Fixed bug #872288 (reset recursive flag during node rename)26 * Fixed bug #872288 (reset recursive flag during node rename)
26 * Fixed bug #905041 (allow for the default element and function namespaces to be27 * Fixed bug #905041 (allow for the default element and function namespaces to be
2728
=== modified file 'include/zorba/item.h'
--- include/zorba/item.h 2012-01-11 17:30:25 +0000
+++ include/zorba/item.h 2012-02-24 04:03:18 +0000
@@ -363,6 +363,29 @@
363 std::istream&363 std::istream&
364 getStream();364 getStream();
365365
366 /**
367 * Returns true if the contents of a binary item is already encoded
368 *
369 * @return true if the content is already encoded, false otherwise
370 */
371 bool
372 isEncoded() const;
373
374 /**
375 * Returns the value and size of the given base64Binary item
376 *
377 * The value is a string which is base64 encoded if isEncoded()
378 * returns true. Otherwise, it is the original unencoded binary
379 * data.
380 *
381 * If the given item is streamable (i.e. isStreamable() returns true),
382 * the stream returned by getStream() should to be used to retrieve
383 * the value. Otherwise, the contents of the stream will be materialized
384 * in main memory.
385 */
386 const char*
387 getBase64BinaryValue(size_t& s) const;
388
366 /** \brief Returns the name of the collection this node is stored in.389 /** \brief Returns the name of the collection this node is stored in.
367 *390 *
368 * @return The name of the collection or 0 if the given item is not391 * @return The name of the collection or 0 if the given item is not
369392
=== modified file 'include/zorba/item_factory.h'
--- include/zorba/item_factory.h 2012-01-11 17:30:25 +0000
+++ include/zorba/item_factory.h 2012-02-24 04:03:18 +0000
@@ -54,7 +54,7 @@
54 /** \brief Creates a streamable String Item54 /** \brief Creates a streamable String Item
55 * see [http://www.w3.org/TR/xmlschema-2/#string]55 * see [http://www.w3.org/TR/xmlschema-2/#string]
56 *56 *
57 * @param stream An istream whence to read the string's content.57 * @param stream An istream from where to read the string's content.
58 * @param streamReleaser A function pointer which is invoked once58 * @param streamReleaser A function pointer which is invoked once
59 * the StreamableStringItem is destroyed. Normally this function59 * the StreamableStringItem is destroyed. Normally this function
60 * will delete the std::istream object passed to it.60 * will delete the std::istream object passed to it.
@@ -149,6 +149,25 @@
149 virtual Item 149 virtual Item
150 createBase64Binary(const unsigned char* aBinData, size_t aLength) = 0;150 createBase64Binary(const unsigned char* aBinData, size_t aLength) = 0;
151151
152 /** \brief Creates a streamable Base64Binary Item
153 * see [http://www.w3.org/TR/xmlschema-2/#base64Binary]
154 *
155 * @param stream An istream from where to read the binary's content.
156 * @param streamReleaser A function pointer which is invoked once
157 * the StreamableBase64Binary is destroyed. Normally this function
158 * will delete the std::istream object passed to it.
159 * @param seekable is the given stream seekable
160 * @param encoded is the contents of the given stream already base64
161 * encoded
162 * @return The streamable String Item
163 */
164 virtual Item
165 createStreamableBase64Binary(
166 std::istream &stream,
167 StreamReleaser streamReleaser,
168 bool seekable = false,
169 bool encoded = false) = 0;
170
152 /** \brief Creates a Boolean Item171 /** \brief Creates a Boolean Item
153 * see [http://www.w3.org/TR/xmlschema-2/#bool]172 * see [http://www.w3.org/TR/xmlschema-2/#bool]
154 *173 *
155174
=== modified file 'modules/com/zorba-xquery/www/modules/converters/base64.xq'
--- modules/com/zorba-xquery/www/modules/converters/base64.xq 2011-08-01 10:18:53 +0000
+++ modules/com/zorba-xquery/www/modules/converters/base64.xq 2012-02-24 04:03:18 +0000
@@ -28,14 +28,17 @@
28declare namespace ver = "http://www.zorba-xquery.com/options/versioning";28declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
29declare option ver:module-version "2.0";29declare option ver:module-version "2.0";
3030
31
32(:~31(:~
33 : Decode a xs:base64Binary.32 : Decode a xs:base64Binary.
34 :33 :
34 : The function assumes that the content after decoding is valid
35 : UTF-8.
36 :
35 : @param $base64 The xs:base64Binary item to decode37 : @param $base64 The xs:base64Binary item to decode
36 : @return the decoded xs:base64Binary item as string38 : @return the base64 decoded value as string
37 :)39 :)
38declare function base64:decode($base64 as xs:base64Binary) as xs:string external;40declare function base64:decode($base64 as xs:base64Binary)
41as xs:string external;
3942
40(:~43(:~
41 : Encode a xs:string as xs:base64Binary.44 : Encode a xs:string as xs:base64Binary.
4245
=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
--- modules/org/expath/ns/file.xq.src/file.cpp 2012-02-16 14:11:02 +0000
+++ modules/org/expath/ns/file.xq.src/file.cpp 2012-02-24 04:03:18 +0000
@@ -144,19 +144,14 @@
144 // actual read144 // actual read
145 Item lItem;145 Item lItem;
146 try {146 try {
147 std::ifstream lInStream;147 std::unique_ptr<std::ifstream> lInStream;
148 lFile->openInputStream(lInStream, true, false);148 lInStream.reset( new std::ifstream() );
149149 lFile->openInputStream(*lInStream.get(), true, false);
150 std::stringstream lStrStream;150
151 char lBuf[1024];151 lItem = theModule->getItemFactory()->createStreamableBase64Binary(
152 while (!lInStream.eof()) {152 *lInStream.release(), &FileModule::streamReleaser, true
153 lInStream.read(lBuf, 1024);153 );
154 lStrStream.write(lBuf, lInStream.gcount());154
155 }
156
157 String lContent(lStrStream.str());
158 String lEncodedContent = encoding::Base64::encode(lContent);
159 lItem = theModule->getItemFactory()->createBase64Binary(lEncodedContent.data(), lEncodedContent.size());
160 } catch (ZorbaException& ze) {155 } catch (ZorbaException& ze) {
161 std::stringstream lSs;156 std::stringstream lSs;
162 lSs << "An unknown error occured: " << ze.what() << "Can not read file";157 lSs << "An unknown error occured: " << ze.what() << "Can not read file";
163158
=== modified file 'modules/org/expath/ns/file.xq.src/file_function.cpp'
--- modules/org/expath/ns/file.xq.src/file_function.cpp 2012-02-16 14:11:02 +0000
+++ modules/org/expath/ns/file.xq.src/file_function.cpp 2012-02-24 04:03:18 +0000
@@ -26,6 +26,7 @@
26#include <zorba/user_exception.h>26#include <zorba/user_exception.h>
27#include <zorba/util/path.h>27#include <zorba/util/path.h>
28#include <zorba/xquery_functions.h>28#include <zorba/xquery_functions.h>
29#include <zorba/singleton_item_sequence.h>
29#include <zorba/zorba.h>30#include <zorba/zorba.h>
3031
31#include "file_module.h"32#include "file_module.h"
@@ -255,10 +256,25 @@
255256
256 // if this is a binary write257 // if this is a binary write
257 if (lBinary) {258 if (lBinary) {
258 Zorba_SerializerOptions lOptions;259 Item lBinaryItem;
259 lOptions.ser_method = ZORBA_SERIALIZATION_METHOD_BINARY;260 Iterator_t lContentSeq = aArgs[1]->getIterator();
260 Serializer_t lSerializer = Serializer::createSerializer(lOptions);261 lContentSeq->open();
261 lSerializer->serialize(aArgs[1], lOutStream);262 while (lContentSeq->next(lBinaryItem))
263 {
264 if (lBinaryItem.isStreamable() && !lBinaryItem.isEncoded())
265 {
266 lOutStream << lBinaryItem.getStream().rdbuf();
267 }
268 else
269 {
270 Zorba_SerializerOptions lOptions;
271 lOptions.ser_method = ZORBA_SERIALIZATION_METHOD_BINARY;
272 Serializer_t lSerializer = Serializer::createSerializer(lOptions);
273 SingletonItemSequence lSeq(lBinaryItem);
274 lSerializer->serialize(&lSeq, lOutStream);
275 }
276
277 }
262 }278 }
263 // if we only write text279 // if we only write text
264 else {280 else {
265281
=== modified file 'src/api/item.cpp'
--- src/api/item.cpp 2012-02-02 09:56:52 +0000
+++ src/api/item.cpp 2012-02-24 04:03:18 +0000
@@ -470,6 +470,29 @@
470 // TODO: throw exception470 // TODO: throw exception
471}471}
472472
473bool
474Item::isEncoded() const
475{
476 ITEM_TRY
477 SYNC_CODE(AutoLock lock(GENV_STORE.getGlobalLock(), Lock::READ);)
478
479 return m_item->isEncoded();
480 ITEM_CATCH
481 // TODO: throw exception
482}
483
484const char*
485Item::getBase64BinaryValue(size_t& s) const
486{
487 ITEM_TRY
488 SYNC_CODE(AutoLock lock(GENV_STORE.getGlobalLock(), Lock::READ);)
489
490 return m_item->getBase64BinaryValue(s);
491 ITEM_CATCH
492 // TODO: throw exception
493}
494
495
473Item496Item
474Item::getCollectionName() const497Item::getCollectionName() const
475{498{
476499
=== modified file 'src/api/itemfactoryimpl.cpp'
--- src/api/itemfactoryimpl.cpp 2012-01-11 17:30:25 +0000
+++ src/api/itemfactoryimpl.cpp 2012-02-24 04:03:18 +0000
@@ -212,13 +212,32 @@
212 std::stringstream lSs;212 std::stringstream lSs;
213 while (aEncodedStream.good()) 213 while (aEncodedStream.good())
214 {214 {
215 lSs.put(aEncodedStream.get());215 char c = aEncodedStream.get();
216 if (aEncodedStream.good())
217 {
218 lSs.put(c);
219 }
216 }220 }
217 std::string lContent = lSs.str();221 std::string lContent = lSs.str();
218 return createBase64Binary(lContent.c_str(), lContent.size());222 return createBase64Binary(lContent.c_str(), lContent.size());
219}223}
220224
221225
226Item
227ItemFactoryImpl::createStreamableBase64Binary(
228 std::istream &stream,
229 StreamReleaser streamReleaser,
230 bool seekable,
231 bool encoded)
232{
233 store::Item_t lItem;
234 theItemFactory->createStreamableBase64Binary(
235 lItem, stream, streamReleaser, seekable, encoded
236 );
237 return &*lItem;
238}
239
240
222Item ItemFactoryImpl::createBoolean(bool aValue)241Item ItemFactoryImpl::createBoolean(bool aValue)
223{242{
224 store::Item_t lItem;243 store::Item_t lItem;
225244
=== modified file 'src/api/itemfactoryimpl.h'
--- src/api/itemfactoryimpl.h 2012-01-11 17:30:25 +0000
+++ src/api/itemfactoryimpl.h 2012-02-24 04:03:18 +0000
@@ -69,6 +69,13 @@
69 virtual Item 69 virtual Item
70 createBase64Binary(const unsigned char* aBinData, size_t aLength);70 createBase64Binary(const unsigned char* aBinData, size_t aLength);
7171
72 virtual Item
73 createStreamableBase64Binary(
74 std::istream &stream,
75 StreamReleaser streamReleaser,
76 bool seekable = false,
77 bool encoded = false);
78
72 virtual Item 79 virtual Item
73 createBoolean(bool aValue);80 createBoolean(bool aValue);
74 81
7582
=== modified file 'src/api/options.cpp'
--- src/api/options.cpp 2012-01-11 17:30:25 +0000
+++ src/api/options.cpp 2012-02-24 04:03:18 +0000
@@ -63,6 +63,7 @@
63 else if (strcmp(value, "html") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_HTML;63 else if (strcmp(value, "html") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_HTML;
64 else if (strcmp(value, "xhtml") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_XHTML;64 else if (strcmp(value, "xhtml") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_XHTML;
65 else if (strcmp(value, "text") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_TEXT;65 else if (strcmp(value, "text") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_TEXT;
66 else if (strcmp(value, "binary") == 0) ser_method = ZORBA_SERIALIZATION_METHOD_BINARY;
66 else67 else
67 {68 {
68 ; // TODO signal errors for incorrect values?69 ; // TODO signal errors for incorrect values?
6970
=== modified file 'src/api/serialization/serializer.cpp'
--- src/api/serialization/serializer.cpp 2012-01-11 17:30:25 +0000
+++ src/api/serialization/serializer.cpp 2012-02-24 04:03:18 +0000
@@ -368,22 +368,50 @@
368void serializer::emitter::emit_streamable_item(store::Item* item)368void serializer::emitter::emit_streamable_item(store::Item* item)
369{369{
370 // Streamable item370 // Streamable item
371 char buffer[1024];371 store::SchemaTypeCode lTypeCode = item->getTypeCode();
372 int rollover = 0;372
373 std::streambuf * pbuf;373 switch (lTypeCode)
374 std::streamsize read_bytes;374 {
375 std::istream& is = item->getStream();375 case store::XS_STRING:
376376 {
377 // read bytes and do string expansion377 char buffer[1024];
378 do378 int rollover = 0;
379 {379 std::streambuf * pbuf;
380 //std::istream::read uses a try/catch internally so the Zorba_Exception is lost: that is why we are using std::streambuf::sgetn380 std::streamsize read_bytes;
381 pbuf = is.rdbuf();381 std::istream& is = item->getStream();
382 read_bytes = pbuf->sgetn(buffer + rollover, 1024 - rollover);382
383 rollover = emit_expanded_string(buffer, static_cast<zstring::size_type>(read_bytes + rollover));383 // read bytes and do string expansion
384 memmove(buffer, buffer + 1024 - rollover, rollover);384 do
385 }385 {
386 while (read_bytes > 0);386 //std::istream::read uses a try/catch internally so the Zorba_Exception is lost: that is why we are using std::streambuf::sgetn
387 pbuf = is.rdbuf();
388 read_bytes = pbuf->sgetn(buffer + rollover, 1024 - rollover);
389 rollover = emit_expanded_string(buffer, static_cast<zstring::size_type>(read_bytes + rollover));
390 memmove(buffer, buffer + 1024 - rollover, rollover);
391 }
392 while (read_bytes > 0);
393 break;
394 }
395 case store::XS_BASE64BINARY:
396 {
397 if (item->isEncoded())
398 {
399 std::istream& is = item->getStream();
400 char buf[1024];
401 while (is.good())
402 {
403 is.read(buf, 1024);
404 tr.write(buf, is.gcount());
405 }
406 }
407 else
408 {
409 tr << item->getStringValue();
410 }
411 break;
412 }
413 default: assert(false);
414 }
387415
388}416}
389417
@@ -1866,30 +1894,48 @@
1866********************************************************************************/1894********************************************************************************/
1867void serializer::binary_emitter::emit_item(store::Item* item)1895void serializer::binary_emitter::emit_item(store::Item* item)
1868{1896{
1869 xs_base64Binary lValue;1897 if (item->isStreamable())
18701898 {
1871 // First assume the item is a base64Binary item and try to get its value.1899 std::istream& stream = item->getStream();
1872 try1900 if (item->isEncoded())
1873 {1901 {
1874 lValue = item->getBase64BinaryValue();1902 tr << Base64::decode(stream);
1875 }1903 }
1876 catch (...)1904 else
1877 {1905 {
1878 // If this fails, then just get the string value of the item and convert1906 char buf[1024];
1879 // it to base641907 while (!stream.eof())
1880 zstring lStringValue;1908 {
1881 item->getStringValue2(lStringValue);1909 stream.read(buf, 1024);
1882 Base64::encode(lStringValue, lValue);1910 tr.write(buf, stream.gcount());
1883 }1911 }
18841912 }
1885 std::vector<char> lDecodedData;1913 }
1886 lValue.decode(lDecodedData);1914 else
18871915 {
1888 for (std::vector<char>::const_iterator lIter = lDecodedData.begin();1916 if (!item->isNode() &&
1889 lIter != lDecodedData.end();1917 item->getTypeCode() == store::XS_BASE64BINARY)
1890 ++lIter)1918 {
1891 {1919 size_t len;
1892 tr << *lIter;1920 const char* value = item->getBase64BinaryValue(len);
1921
1922 if (item->isEncoded())
1923 {
1924 std::stringstream tmp;
1925 tmp.write(value, len);
1926 tr << Base64::decode(tmp);
1927 }
1928 else
1929 {
1930 tr.write(value, len);
1931 }
1932 }
1933 else
1934 {
1935 zstring lStringValue;
1936 item->getStringValue2(lStringValue);
1937 tr << lStringValue;
1938 }
1893 }1939 }
1894}1940}
18951941
18961942
=== modified file 'src/runtime/base64/base64_impl.cpp'
--- src/runtime/base64/base64_impl.cpp 2011-06-14 17:26:33 +0000
+++ src/runtime/base64/base64_impl.cpp 2012-02-24 04:03:18 +0000
@@ -22,37 +22,74 @@
2222
23#include "runtime/base64/base64.h"23#include "runtime/base64/base64.h"
2424
25
26#include "store/api/item.h"25#include "store/api/item.h"
27#include "store/api/item_factory.h"26#include "store/api/item_factory.h"
2827
29namespace zorba {28namespace zorba {
3029
31bool Base64DecodeIterator::nextImpl(store::Item_t& result, PlanState& planState) const30bool Base64DecodeIterator::nextImpl(
31 store::Item_t& result,
32 PlanState& planState) const
32{33{
33 store::Item_t lItem;34 store::Item_t lItem;
34 Base64 lDecodedData;
35 zstring lResultString;35 zstring lResultString;
36 const char* lContent;
37 size_t lSize;
38 result = NULL;
3639
37 PlanIteratorState *state;40 PlanIteratorState *state;
38 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);41 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
3942
40 if (consumeNext(lItem, theChildren[0].getp(), planState))43 consumeNext(lItem, theChildren[0].getp(), planState);
41 {44
42 lDecodedData = lItem->getBase64BinaryValue();45 if (lItem->isStreamable())
43 lResultString = lDecodedData.decode().str();46 {
47 if (lItem->isEncoded())
48 {
49 // decode and eventually transcode
50 lResultString = Base64::decode(lItem->getStream());
51 }
52 else
53 {
54 // streamable string eventually transcoding
55 GENV_ITEMFACTORY->createStreamableString(
56 result,
57 lItem->getStream(),
58 lItem->getStreamReleaser(),
59 lItem->isSeekable());
60 }
61 }
62 else
63 {
64 lContent = lItem->getBase64BinaryValue(lSize);
65
66 if (lItem->isEncoded())
67 {
68 std::vector<char> encoded(lContent, lContent+lSize);
69 std::vector<char> decoded;
70 Base64::decode(encoded, decoded);
71 lResultString.insert(0, &decoded[0], decoded.size());
72 }
73 else
74 {
75 lResultString.insert(0, lContent, lSize);
76 }
77 }
78 if (!result) // otherwise it's a streamable string already
79 {
44 GENV_ITEMFACTORY->createString(result, lResultString);80 GENV_ITEMFACTORY->createString(result, lResultString);
45 STACK_PUSH (true, state);
46 }81 }
82 STACK_PUSH (true, state);
4783
48 STACK_END (state);84 STACK_END (state);
49}85}
5086
5187
52bool Base64EncodeIterator::nextImpl(store::Item_t& result, PlanState& planState) const88bool Base64EncodeIterator::nextImpl(
89 store::Item_t& result,
90 PlanState& planState) const
53{91{
54 store::Item_t lItem;92 store::Item_t lItem;
55 Base64 lBase64;
56 zstring lTmpString;93 zstring lTmpString;
5794
58 PlanIteratorState* state;95 PlanIteratorState* state;
@@ -61,17 +98,12 @@
61 if (consumeNext(lItem, theChildren[0].getp(), planState)) 98 if (consumeNext(lItem, theChildren[0].getp(), planState))
62 {99 {
63 lItem->getStringValue2(lTmpString);100 lItem->getStringValue2(lTmpString);
64 Base64::encode(lTmpString, lBase64);101 // create a base64Binary item
65 if (GENV_ITEMFACTORY->createBase64Binary(result, lBase64)) 102 // the content is the non-encoded string
66 {103 GENV_ITEMFACTORY->createBase64Binary(
67 STACK_PUSH (true, state);104 result, lTmpString.c_str(), lTmpString.size(), false
68 }105 );
69 else106 STACK_PUSH (true, state);
70 {
71 throw XQUERY_EXCEPTION(
72 zerr::ZXQP0025_ITEM_CREATION_FAILED, ERROR_LOC( loc )
73 );
74 }
75 }107 }
76 STACK_END (state);108 STACK_END (state);
77}109}
78110
=== modified file 'src/store/api/item.h'
--- src/store/api/item.h 2012-02-07 15:53:23 +0000
+++ src/store/api/item.h 2012-02-24 04:03:18 +0000
@@ -274,7 +274,14 @@
274274
275 /** Accessor for xs:base64Binary275 /** Accessor for xs:base64Binary
276 */276 */
277 virtual xs_base64Binary getBase64BinaryValue() const;277 virtual const char* getBase64BinaryValue(size_t& size) const;
278
279 /**
280 * Checks whether a base64 item's content is already encoded
281 *
282 * @return true only if it is.
283 */
284 virtual bool isEncoded() const;
278285
279 /** Accessor for xs:boolean286 /** Accessor for xs:boolean
280 */287 */
281288
=== modified file 'src/store/api/item_factory.h'
--- src/store/api/item_factory.h 2011-12-21 14:40:33 +0000
+++ src/store/api/item_factory.h 2012-02-24 04:03:18 +0000
@@ -205,6 +205,31 @@
205 virtual bool createBase64Binary(Item_t& result, xs_base64Binary value) = 0;205 virtual bool createBase64Binary(Item_t& result, xs_base64Binary value) = 0;
206206
207 /**207 /**
208 * Specification: [http://www.w3.org/TR/xmlschema-2/#base64Binary]
209 * creates a base64Binary item with the given content
210 * the encoded flag specifies whether the given content is already
211 * base64 encoded or not.
212 */
213 virtual bool createBase64Binary(
214 Item_t& result,
215 const char* value,
216 size_t size,
217 bool encoded) = 0;
218
219 /**
220 * Specification: [http://www.w3.org/TR/xmlschema-2/#base64Binary]
221 * the encoded flag specifies whether the given content is already
222 * base64 encoded or not.
223 */
224 virtual bool createStreamableBase64Binary(
225 Item_t& result,
226 std::istream&,
227 StreamReleaser,
228 bool seekable = false,
229 bool encoded = false) = 0;
230
231
232 /**
208 * Specification: [http://www.w3.org/TR/xmlschema-2/#bool]233 * Specification: [http://www.w3.org/TR/xmlschema-2/#bool]
209 * @param value234 * @param value
210 */235 */
211236
=== modified file 'src/store/naive/atomic_items.cpp'
--- src/store/naive/atomic_items.cpp 2012-02-15 10:25:02 +0000
+++ src/store/naive/atomic_items.cpp 2012-02-24 04:03:18 +0000
@@ -3059,6 +3059,45 @@
3059/*******************************************************************************3059/*******************************************************************************
3060 class Base64BinaryItem3060 class Base64BinaryItem
3061********************************************************************************/3061********************************************************************************/
3062bool
3063Base64BinaryItem::equals(
3064 const store::Item* other,
3065 long timezone,
3066 const XQPCollator* aCollation) const
3067{
3068 if (isEncoded() == other->isEncoded())
3069 {
3070 size_t this_size, other_size;
3071 const char* this_data = getBase64BinaryValue(this_size);
3072 const char* other_data = other->getBase64BinaryValue(other_size);
3073 return this_size == other_size &&
3074 memcmp(this_data, other_data, this_size) == 0;
3075 }
3076 else
3077 {
3078 return getStringValue().compare(other->getStringValue()) == 0;
3079 }
3080}
3081
3082
3083uint32_t
3084Base64BinaryItem::hash(long timezone, const XQPCollator* aCollation) const
3085{
3086 // always need to hash on the string-value because otherwise
3087 // a base64 item that is encoded would have a different hash-value
3088 // as a base64 item that is decoded but represents the same binary content
3089 return utf8::hash(getStringValue(), aCollation);
3090}
3091
3092
3093const char*
3094Base64BinaryItem::getBase64BinaryValue(size_t& size) const
3095{
3096 size = theValue.size();
3097 return &theValue[0];
3098}
3099
3100
3062store::Item* Base64BinaryItem::getType() const3101store::Item* Base64BinaryItem::getType() const
3063{3102{
3064 return GET_STORE().theSchemaTypeNames[store::XS_BASE64BINARY];3103 return GET_STORE().theSchemaTypeNames[store::XS_BASE64BINARY];
@@ -3067,19 +3106,32 @@
30673106
3068zstring Base64BinaryItem::getStringValue() const3107zstring Base64BinaryItem::getStringValue() const
3069{3108{
3070 return theValue.str();3109 zstring lRes;
3110 getStringValue2(lRes);
3111 return lRes;
3071}3112}
30723113
30733114
3074void Base64BinaryItem::getStringValue2(zstring& val) const3115void Base64BinaryItem::getStringValue2(zstring& val) const
3075{3116{
3076 val = theValue.str();3117 val.clear();
3118 appendStringValue(val);
3077}3119}
30783120
30793121
3080void Base64BinaryItem::appendStringValue(zstring& buf) const3122void Base64BinaryItem::appendStringValue(zstring& buf) const
3081{3123{
3082 buf += theValue.str();3124 if (theIsEncoded)
3125 {
3126 buf.insert(buf.size(), &theValue[0], theValue.size());
3127 }
3128 else
3129 {
3130 std::vector<char> encoded;
3131 encoded.reserve(theValue.size());
3132 Base64::encode(theValue, encoded);
3133 buf.insert(buf.size(), &encoded[0], encoded.size());
3134 }
3083}3135}
30843136
30853137
@@ -3092,9 +3144,155 @@
3092}3144}
30933145
30943146
3095uint32_t Base64BinaryItem::hash(long timezone, const XQPCollator* aCollation) const3147/*******************************************************************************
3096{3148 class StreamableStringItem
3097 return theValue.hash();3149********************************************************************************/
3150zstring StreamableBase64BinaryItem::getStringValue() const
3151{
3152 if (!theIsMaterialized)
3153 {
3154 materialize();
3155 }
3156 return Base64BinaryItem::getStringValue();
3157}
3158
3159
3160void StreamableBase64BinaryItem::getStringValue2(zstring& val) const
3161{
3162 if (!theIsMaterialized)
3163 {
3164 materialize();
3165 }
3166 Base64BinaryItem::getStringValue2(val);
3167}
3168
3169
3170void StreamableBase64BinaryItem::appendStringValue(zstring& buf) const
3171{
3172 if (!theIsMaterialized)
3173 {
3174 materialize();
3175 }
3176 Base64BinaryItem::appendStringValue(buf);
3177}
3178
3179
3180zstring StreamableBase64BinaryItem::show() const
3181{
3182 if (!theIsMaterialized)
3183 {
3184 materialize();
3185 }
3186 zstring res("xs:base64Binary(");
3187 appendStringValue(res);
3188 res += ")";
3189 return res;
3190}
3191
3192
3193uint32_t
3194StreamableBase64BinaryItem::hash(long timezone, const XQPCollator* aCollation) const
3195{
3196 if (!theIsMaterialized)
3197 {
3198 materialize();
3199 }
3200 return Base64BinaryItem::hash(timezone, aCollation);
3201}
3202
3203
3204const char*
3205StreamableBase64BinaryItem::getBase64BinaryValue(size_t& s) const
3206{
3207 if (!theIsMaterialized)
3208 {
3209 materialize();
3210 }
3211 return Base64BinaryItem::getBase64BinaryValue(s);
3212}
3213
3214
3215bool StreamableBase64BinaryItem::isStreamable() const
3216{
3217 return true;
3218}
3219
3220
3221bool StreamableBase64BinaryItem::isSeekable() const
3222{
3223 return theIsSeekable;
3224}
3225
3226
3227StreamReleaser StreamableBase64BinaryItem::getStreamReleaser()
3228{
3229 return theStreamReleaser;
3230}
3231
3232
3233void StreamableBase64BinaryItem::setStreamReleaser(StreamReleaser aReleaser)
3234{
3235 theStreamReleaser = aReleaser;
3236}
3237
3238
3239std::istream& StreamableBase64BinaryItem::getStream()
3240{
3241 // a non-seekable stream can only be consumed once
3242 // we raise an error if getStream is called twice
3243 // if a query requires a stream to be consumed more than once,
3244 // the query needs to make sure that the stream is explicitly
3245 // materialized before
3246 if (!theIsSeekable && theIsConsumed)
3247 {
3248 throw ZORBA_EXCEPTION( zerr::ZSTR0055_STREAMABLE_STRING_CONSUMED );
3249 }
3250 else
3251 {
3252 // if the stream is seekable, we seek to the beginning.
3253 // We are not using theIstream.seekg because the USER_ERROR that is thrown
3254 // by Zorba is lost possibly in an internal try/catch of the seekg
3255 std::streambuf * pbuf;
3256 pbuf = theIstream.rdbuf();
3257 pbuf->pubseekoff(0, std::ios::beg);
3258 }
3259 theIsConsumed = true;
3260 return theIstream;
3261}
3262
3263
3264void StreamableBase64BinaryItem::materialize() const
3265{
3266 StreamableBase64BinaryItem* const s
3267 = const_cast<StreamableBase64BinaryItem*>(this);
3268 std::istream& lStream = s->getStream();
3269
3270 s->theIsMaterialized = true;
3271 s->theIsConsumed = true;
3272
3273 if (isSeekable())
3274 {
3275 lStream.seekg(0, std::ios::end);
3276 size_t len = lStream.tellg();
3277 lStream.seekg(0, std::ios::beg);
3278 s->theValue.reserve(len);
3279 char buf[1024];
3280 while (lStream.good())
3281 {
3282 lStream.read(buf, 1024);
3283 s->theValue.insert(s->theValue.end(), buf, buf+lStream.gcount());
3284 }
3285 }
3286 else
3287 {
3288 char buf[4048];
3289 while (lStream.good())
3290 {
3291 lStream.read(buf, 4048);
3292 s->theValue.reserve(s->theValue.size() + lStream.gcount());
3293 s->theValue.insert(s->theValue.end(), buf, buf+lStream.gcount());
3294 }
3295 }
3098}3296}
30993297
31003298
31013299
=== modified file 'src/store/naive/atomic_items.h'
--- src/store/naive/atomic_items.h 2012-01-26 19:56:14 +0000
+++ src/store/naive/atomic_items.h 2012-02-24 04:03:18 +0000
@@ -20,6 +20,7 @@
20#include <zorba/config.h>20#include <zorba/config.h>
21#include <iostream>21#include <iostream>
22#include <vector>22#include <vector>
23#include <cstring>
2324
24#include <zorba/streams.h>25#include <zorba/streams.h>
25#ifndef ZORBA_NO_FULL_TEXT26#ifndef ZORBA_NO_FULL_TEXT
@@ -153,7 +154,10 @@
153154
154 const zstring& getString() const { return theBaseItem->getString(); }155 const zstring& getString() const { return theBaseItem->getString(); }
155156
156 xs_base64Binary getBase64BinaryValue() const { return theBaseItem->getBase64BinaryValue(); }157 const char* getBase64BinaryValue(size_t& s) const
158 {
159 return theBaseItem->getBase64BinaryValue(s);
160 }
157161
158 xs_hexBinary getHexBinaryValue() const { return theBaseItem->getHexBinaryValue(); }162 xs_hexBinary getHexBinaryValue() const { return theBaseItem->getHexBinaryValue(); }
159163
@@ -2218,30 +2222,115 @@
2218 friend class BasicItemFactory;2222 friend class BasicItemFactory;
22192223
2220protected:2224protected:
2221 xs_base64Binary theValue;2225 std::vector<char> theValue;
2226 bool theIsEncoded;
22222227
2223protected:2228protected:
2224 Base64BinaryItem(xs_base64Binary aValue) : theValue(aValue) {}2229 Base64BinaryItem(bool aIsEncoded)
2230 : theIsEncoded(aIsEncoded) {}
22252231
2226 Base64BinaryItem() {}2232 Base64BinaryItem(const char* aValue, size_t aSize, bool aIsEncoded = true)
2233 : theIsEncoded(aIsEncoded)
2234 {
2235 theValue.reserve(aSize);
2236 theValue.insert(theValue.begin(), aValue, aValue + aSize);
2237 }
22272238
2228public:2239public:
2229 xs_base64Binary getBase64BinaryValue() const { return theValue; }2240 const char* getBase64BinaryValue(size_t& data) const;
22302241
2231 store::SchemaTypeCode getTypeCode() const { return store::XS_BASE64BINARY; }2242 store::SchemaTypeCode getTypeCode() const { return store::XS_BASE64BINARY; }
22322243
2233 store::Item* getType() const;2244 store::Item* getType() const;
22342245
2246 bool isEncoded() const { return theIsEncoded; }
2247
2235 uint32_t hash(long timezone = 0, const XQPCollator* aCollation = 0) const;2248 uint32_t hash(long timezone = 0, const XQPCollator* aCollation = 0) const;
22362249
2237 bool equals(2250 bool equals(
2238 const store::Item* other,2251 const store::Item* other,
2239 long timezone = 0,2252 long timezone = 0,
2240 const XQPCollator* aCollation = 0 ) const2253 const XQPCollator* aCollation = 0 ) const;
2241 {2254
2242 return theValue.equal(other->getBase64BinaryValue());2255 zstring getStringValue() const;
2256
2257 void getStringValue2(zstring& val) const;
2258
2259 void appendStringValue(zstring& buf) const;
2260
2261 zstring show() const;
2262
2263protected:
2264 // used in hash doing simple xor of the data
2265 struct hash_functor
2266 {
2267 uint32_t hash_value;
2268
2269 void operator() (char c)
2270 {
2271 hash_value ^= (uint32_t) c;
2272 }
2273 };
2274};
2275
2276
2277/*******************************************************************************
2278 class StreamableBase64BinaryItem
2279********************************************************************************/
2280class StreamableBase64BinaryItem : public Base64BinaryItem
2281{
2282 friend class BasicItemFactory;
2283
2284protected:
2285 std::istream & theIstream;
2286
2287 bool theIsMaterialized;
2288 bool theIsConsumed;
2289 bool theIsSeekable;
2290
2291 StreamReleaser theStreamReleaser;
2292
2293protected:
2294 StreamableBase64BinaryItem(
2295 std::istream& aStream,
2296 StreamReleaser streamReleaser,
2297 bool seekable = false,
2298 bool is_encoded = false)
2299 : Base64BinaryItem(is_encoded),
2300 theIstream(aStream),
2301 theIsMaterialized(false),
2302 theIsConsumed(false),
2303 theIsSeekable(seekable),
2304 theStreamReleaser(streamReleaser)
2305 {}
2306
2307 void materialize() const;
2308
2309public:
2310 virtual ~StreamableBase64BinaryItem()
2311 {
2312 if (theStreamReleaser)
2313 {
2314 theStreamReleaser(&theIstream);
2315 }
2243 }2316 }
22442317
2318 bool isStreamable() const;
2319
2320 bool isSeekable() const;
2321
2322 std::istream& getStream();
2323
2324 StreamReleaser getStreamReleaser();
2325
2326 void setStreamReleaser(StreamReleaser aReleaser);
2327
2328 const char* getBase64BinaryValue(size_t&) const;
2329
2330 store::SchemaTypeCode getTypeCode() const { return store::XS_BASE64BINARY; }
2331
2332 uint32_t hash(long timezone = 0, const XQPCollator* aCollation = 0) const;
2333
2245 zstring getStringValue() const;2334 zstring getStringValue() const;
22462335
2247 void getStringValue2(zstring& val) const;2336 void getStringValue2(zstring& val) const;
22482337
=== modified file 'src/store/naive/item.cpp'
--- src/store/naive/item.cpp 2012-02-15 10:25:02 +0000
+++ src/store/naive/item.cpp 2012-02-24 04:03:18 +0000
@@ -430,7 +430,7 @@
430/**430/**
431 * Accessor for xs:base64Binary431 * Accessor for xs:base64Binary
432 */432 */
433xs_base64Binary Item::getBase64BinaryValue() const433const char* Item::getBase64BinaryValue(size_t&) const
434{434{
435 throw ZORBA_EXCEPTION(435 throw ZORBA_EXCEPTION(
436 zerr::ZSTR0040_TYPE_ERROR,436 zerr::ZSTR0040_TYPE_ERROR,
@@ -441,6 +441,24 @@
441 );441 );
442}442}
443443
444
445/**
446 * Checks whether a base64 item's content is already encoded
447 *
448 * @return true only if it is.
449 */
450bool Item::isEncoded() const
451{
452 throw ZORBA_EXCEPTION(
453 zerr::ZSTR0040_TYPE_ERROR,
454 ERROR_PARAMS(
455 ZED( OperationNotDef_23 ), "Item::isEncoded()",
456 getType()->getStringValue()
457 )
458 );
459}
460
461
444/**462/**
445 * Accessor for xs:boolean463 * Accessor for xs:boolean
446 */464 */
447465
=== modified file 'src/store/naive/simple_item_factory.cpp'
--- src/store/naive/simple_item_factory.cpp 2012-02-15 10:25:02 +0000
+++ src/store/naive/simple_item_factory.cpp 2012-02-24 04:03:18 +0000
@@ -997,9 +997,36 @@
997}997}
998998
999999
1000bool BasicItemFactory::createBase64Binary(store::Item_t& result, xs_base64Binary value)1000bool BasicItemFactory::createBase64Binary(
1001{1001 store::Item_t& result,
1002 result = new Base64BinaryItem(value);1002 xs_base64Binary value)
1003{
1004 const std::vector<char>& data = value.getData();
1005 result = new Base64BinaryItem(&data[0], data.size(), true);
1006 return true;
1007}
1008
1009bool BasicItemFactory::createBase64Binary(
1010 store::Item_t& result,
1011 const char* value,
1012 size_t size,
1013 bool encoded)
1014{
1015 result = new Base64BinaryItem(value, size, encoded);
1016 return true;
1017}
1018
1019
1020bool BasicItemFactory::createStreamableBase64Binary(
1021 store::Item_t& result,
1022 std::istream& aStream,
1023 StreamReleaser aReleaser,
1024 bool seekable,
1025 bool encoded)
1026{
1027 result = new StreamableBase64BinaryItem(
1028 aStream, aReleaser, seekable, encoded
1029 );
1003 return true;1030 return true;
1004}1031}
10051032
10061033
=== modified file 'src/store/naive/simple_item_factory.h'
--- src/store/naive/simple_item_factory.h 2011-12-21 14:40:33 +0000
+++ src/store/naive/simple_item_factory.h 2012-02-24 04:03:18 +0000
@@ -107,6 +107,19 @@
107107
108 bool createBase64Binary(store::Item_t& result, xs_base64Binary value);108 bool createBase64Binary(store::Item_t& result, xs_base64Binary value);
109109
110 bool createBase64Binary(
111 store::Item_t& result,
112 const char* value,
113 size_t size,
114 bool encoded);
115
116 bool createStreamableBase64Binary(
117 store::Item_t& result,
118 std::istream&,
119 StreamReleaser,
120 bool seekable = false,
121 bool encoded = false);
122
110 bool createBoolean(store::Item_t& result, xs_boolean value);123 bool createBoolean(store::Item_t& result, xs_boolean value);
111124
112125
113126
=== modified file 'src/types/casting.cpp'
--- src/types/casting.cpp 2012-01-30 15:23:21 +0000
+++ src/types/casting.cpp 2012-02-24 04:03:18 +0000
@@ -1267,7 +1267,18 @@
12671267
1268T1_TO_T2(b64, hxB)1268T1_TO_T2(b64, hxB)
1269{1269{
1270 return aFactory->createHexBinary(result, xs_hexBinary(aItem->getBase64BinaryValue()));1270 size_t s;
1271 const char* c = aItem->getBase64BinaryValue(s);
1272 Base64 tmp;
1273 if (aItem->isEncoded())
1274 {
1275 Base64::parseString(c, s, tmp);
1276 }
1277 else
1278 {
1279 Base64::encode((const unsigned char*)c, s, tmp);
1280 }
1281 return aFactory->createHexBinary(result, xs_hexBinary(tmp));
1271}1282}
12721283
12731284
12741285
=== modified file 'src/zorbaserialization/zorba_class_serializer.cpp'
--- src/zorbaserialization/zorba_class_serializer.cpp 2012-01-11 17:30:25 +0000
+++ src/zorbaserialization/zorba_class_serializer.cpp 2012-02-24 04:03:18 +0000
@@ -673,8 +673,31 @@
673 673
674 else if(name_of_type == "base64Binary")674 else if(name_of_type == "base64Binary")
675 {675 {
676 SERIALIZE_REF_FIELD(xs_base64Binary, value, getBase64BinaryValue());676 if (ar.is_serializing_out())
677 FINALIZE_SERIALIZE(createBase64Binary, (result, value_in));677 {
678 size_t s;
679 const char* c = obj->getBase64BinaryValue(s);
680 if (obj->isEncoded())
681 {
682 Base64 tmp;
683 Base64::parseString(c, s, tmp);
684 ar.dont_allow_delay();
685 ar & tmp;
686 }
687 else
688 {
689 Base64 tmp((const unsigned char*)c, s);
690 ar.dont_allow_delay();
691 ar & tmp;
692 }
693 }
694 else
695 {
696 ar.dont_allow_delay();
697 Base64 tmp;
698 ar & tmp;
699 FINALIZE_SERIALIZE(createBase64Binary, (result, tmp));
700 }
678 }701 }
679 else if(name_of_type == "hexBinary")702 else if(name_of_type == "hexBinary")
680 {703 {
681704
=== modified file 'src/zorbatypes/binary.cpp'
--- src/zorbatypes/binary.cpp 2011-06-14 17:26:33 +0000
+++ src/zorbatypes/binary.cpp 2012-02-24 04:03:18 +0000
@@ -306,6 +306,16 @@
306}306}
307307
308308
309Base64::Base64(const unsigned char *bin_data, size_t len)
310{
311 std::vector<char> tmp;
312 tmp.reserve(len);
313 tmp.insert(tmp.begin(), (const char*)bin_data, ((const char*)bin_data) + len);
314 theData.reserve(len);
315 encode(tmp, theData);
316}
317
318
309void Base64::serialize(::zorba::serialization::Archiver& ar)319void Base64::serialize(::zorba::serialization::Archiver& ar)
310{320{
311 ar & theData;321 ar & theData;
312322
=== added directory 'test/rbkt/ExpQueryResults/zorba/base64'
=== added file 'test/rbkt/ExpQueryResults/zorba/base64/binary_1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/base64/binary_1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/base64/binary_1.xml.res 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1true
02
=== added file 'test/rbkt/ExpQueryResults/zorba/base64/file_read_1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/base64/file_read_1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/base64/file_read_1.xml.res 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1true true f0VMRgEBAQAAAAAAAAAAAAMAAwABAAAAIPxDADQAAAD0JTMHAAAAADQAIAAHACgAKAAlAAEAAAAAAAAAAAAAAAAAAAAv22gBL9toAQUAAAAAEAAAAQAAAJTbaAGU62gBlOtoAehnBwAwpgcABgAAAAAQAAACAAAAvKBuAbywbgG8sG4BGAEAABgBAAAGAAAABAAAAAQAAAAUAQAAFAEAABQBAAAkAAAAJAAAAAQAAAAEAAAAUOV0ZKyHJwGshycBrIcnAfyBCAD8gQgABAAAAAQAAABR5XRkAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAABAAAAFLldGSU22gBlOtoAZTraAFs5AUAbOQFAAQAAAABAAAABAAAABQAAAADAAAAR05VANMOFlHRDhyfmkw9H3+lYuAncwGhG0AAAAYDAAAAIAAAEgAAABBkRVIkEIgUIwhRukiBHLCOBAAEAgggoSCCg0CkED5YAAAGFAIgABkACJAAiQAwAFCQEwAQIABBAIIFYAIACAASAAZARACAABkTpAQB5EQIYEF0IBIAIgAhciYEoEICZGgAAQAABCAAkBACZAJAAQQUEhGAIIAAKBULIJYAAABRAKFV4AIWgQAEIYgAAIAAQECAMgBGiCIGiRAEkAABAMAIgEQAAAQAACgIJYAAAEAAAAGAAgtCpFwEAAZRQACAABAICAASiBBFgRhIAkEBMAApJchACQZDAIAAgABIAKQEgKEACGE05FgCAAAgACEAgEAAQoxkUAEAiBAGAAkCFiBoISRFFCBEBMV3gARBgBAosUJBQQAEEDIAUUCBAABAEAhgAEAAAAAAACApACIBBgHKkAWBQAAEAAAAAACDURggAkEEEIlEgIEADQZwAAATC5AQNYxCABABAAAAAAEAlQD0WGD3gAAAIEDKCCAQQMGNIAAQAAAACECCAADAbMAWABABaRAAUFQCgAAAgxJmDAEIAiIZCmIAIAIEgAESCSAjETEQIws2A8AIgAEAAAAAkGkAiEAKDEYEBRGJhFEAIACICAIBKMAGAAAHIAQBqIgAUAECgAAAAhoEER4BASMBBhEIIQGCAFbg8IiBYAgCAQgAgEBwCAAAIAEAQATGAj+QQaAIIQAIAAShAgg2AKQAAAQBkCoASAAAFAAgAYFqAQDCcoOEg0sAIhKAABQAAgpAAghAAIQgIBAkAAQBDA4gRAACAAIgAPBAUgBDARCAggB0GQBaEAg1Mk8CABEAAAQgBBgAECIAvEIhFCRAIBgAAEALyBEQAhACQoIKwAABkBiAVM4QAQlFgBAS4AASAIIkAZEkEgAsBMCABSCAKACAIBMAD4JSLEyAAGQBBqATAUECQUgACQGBGA==
02
=== added file 'test/rbkt/ExpQueryResults/zorba/base64/file_read_2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/base64/file_read_2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/base64/file_read_2.xml.res 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1true true true
02
=== added directory 'test/rbkt/Queries/zorba/base64'
=== added file 'test/rbkt/Queries/zorba/base64/binary_1.xq'
--- test/rbkt/Queries/zorba/base64/binary_1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/binary_1.xq 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1xs:string(xs:base64Binary("Wm9yYmEgaXMgR3JlYXQhIMOkw7bDvA==")) eq "Wm9yYmEgaXMgR3JlYXQhIMOkw7bDvA=="
02
=== added file 'test/rbkt/Queries/zorba/base64/decoded'
1Binary files test/rbkt/Queries/zorba/base64/decoded 1970-01-01 00:00:00 +0000 and test/rbkt/Queries/zorba/base64/decoded 2012-02-24 04:03:18 +0000 differ3Binary files test/rbkt/Queries/zorba/base64/decoded 1970-01-01 00:00:00 +0000 and test/rbkt/Queries/zorba/base64/decoded 2012-02-24 04:03:18 +0000 differ
=== added file 'test/rbkt/Queries/zorba/base64/decoded-text'
--- test/rbkt/Queries/zorba/base64/decoded-text 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/decoded-text 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1Zorba is Great! äöü
0\ No newline at end of file2\ No newline at end of file
13
=== added file 'test/rbkt/Queries/zorba/base64/encoded'
--- test/rbkt/Queries/zorba/base64/encoded 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/encoded 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1f0VMRgEBAQAAAAAAAAAAAAMAAwABAAAAIPxDADQAAAD0JTMHAAAAADQAIAAHACgAKAAlAAEAAAAAAAAAAAAAAAAAAAAv22gBL9toAQUAAAAAEAAAAQAAAJTbaAGU62gBlOtoAehnBwAwpgcABgAAAAAQAAACAAAAvKBuAbywbgG8sG4BGAEAABgBAAAGAAAABAAAAAQAAAAUAQAAFAEAABQBAAAkAAAAJAAAAAQAAAAEAAAAUOV0ZKyHJwGshycBrIcnAfyBCAD8gQgABAAAAAQAAABR5XRkAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAABAAAAFLldGSU22gBlOtoAZTraAFs5AUAbOQFAAQAAAABAAAABAAAABQAAAADAAAAR05VANMOFlHRDhyfmkw9H3+lYuAncwGhG0AAAAYDAAAAIAAAEgAAABBkRVIkEIgUIwhRukiBHLCOBAAEAgggoSCCg0CkED5YAAAGFAIgABkACJAAiQAwAFCQEwAQIABBAIIFYAIACAASAAZARACAABkTpAQB5EQIYEF0IBIAIgAhciYEoEICZGgAAQAABCAAkBACZAJAAQQUEhGAIIAAKBULIJYAAABRAKFV4AIWgQAEIYgAAIAAQECAMgBGiCIGiRAEkAABAMAIgEQAAAQAACgIJYAAAEAAAAGAAgtCpFwEAAZRQACAABAICAASiBBFgRhIAkEBMAApJchACQZDAIAAgABIAKQEgKEACGE05FgCAAAgACEAgEAAQoxkUAEAiBAGAAkCFiBoISRFFCBEBMV3gARBgBAosUJBQQAEEDIAUUCBAABAEAhgAEAAAAAAACApACIBBgHKkAWBQAAEAAAAAACDURggAkEEEIlEgIEADQZwAAATC5AQNYxCABABAAAAAAEAlQD0WGD3gAAAIEDKCCAQQMGNIAAQAAAACECCAADAbMAWABABaRAAUFQCgAAAgxJmDAEIAiIZCmIAIAIEgAESCSAjETEQIws2A8AIgAEAAAAAkGkAiEAKDEYEBRGJhFEAIACICAIBKMAGAAAHIAQBqIgAUAECgAAAAhoEER4BASMBBhEIIQGCAFbg8IiBYAgCAQgAgEBwCAAAIAEAQATGAj+QQaAIIQAIAAShAgg2AKQAAAQBkCoASAAAFAAgAYFqAQDCcoOEg0sAIhKAABQAAgpAAghAAIQgIBAkAAQBDA4gRAACAAIgAPBAUgBDARCAggB0GQBaEAg1Mk8CABEAAAQgBBgAECIAvEIhFCRAIBgAAEALyBEQAhACQoIKwAABkBiAVM4QAQlFgBAS4AASAIIkAZEkEgAsBMCABSCAKACAIBMAD4JSLEyAAGQBBqATAUECQUgACQGBGA==
0\ No newline at end of file2\ No newline at end of file
13
=== added file 'test/rbkt/Queries/zorba/base64/encoded-text'
--- test/rbkt/Queries/zorba/base64/encoded-text 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/encoded-text 2012-02-24 04:03:18 +0000
@@ -0,0 +1,1 @@
1Wm9yYmEgaXMgR3JlYXQhIMOkw7bDvA==
0\ No newline at end of file2\ No newline at end of file
13
=== added file 'test/rbkt/Queries/zorba/base64/file_read_1.xq'
--- test/rbkt/Queries/zorba/base64/file_read_1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/file_read_1.xq 2012-02-24 04:03:18 +0000
@@ -0,0 +1,10 @@
1import module namespace f = "http://expath.org/ns/file";
2
3variable $enc-file-name := resolve-uri("encoded");
4variable $dec-file-name := resolve-uri("decoded");
5variable $base64-1 := f:read-binary($dec-file-name);
6variable $base64-2 := f:read-binary($dec-file-name);
7variable $ref-result := f:read-text($enc-file-name);
8
9xs:string($base64-1) eq $ref-result, $base64-1 eq $base64-2,
10fn:serialize($base64-1)
011
=== added file 'test/rbkt/Queries/zorba/base64/file_read_2.xq'
--- test/rbkt/Queries/zorba/base64/file_read_2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/base64/file_read_2.xq 2012-02-24 04:03:18 +0000
@@ -0,0 +1,11 @@
1import module namespace f = "http://expath.org/ns/file";
2import module namespace b = "http://www.zorba-xquery.com/modules/converters/base64";
3
4variable $enc-file-name := resolve-uri("encoded-text");
5variable $dec-file-name := resolve-uri("decoded-text");
6variable $encoded := f:read-text($enc-file-name);
7variable $decoded := f:read-text($dec-file-name);
8
9$encoded eq xs:string(b:encode($decoded)),
10xs:base64Binary($encoded) eq b:encode($decoded),
11b:decode(xs:base64Binary($encoded)) eq $decoded

Subscribers

People subscribed via source and target branches