Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/pub_iter_imp into lp:zorba.
Commit message: Added count() & skip() to public Iterator API. Requested reviews: Paul J. Lucas (paul-lucas) For more details, see: https://code.launchpad.net/~zorba-coders/zorba/pub_iter_imp/+merge/201708 Added count() & skip() to public Iterator API. -- https://code.launchpad.net/~zorba-coders/zorba/pub_iter_imp/+merge/201708 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'NOTICE.txt' --- NOTICE.txt 2014-01-10 02:36:58 +0000 +++ NOTICE.txt 2014-01-15 03:04:02 +0000 @@ -482,7 +482,8 @@ Copyright: 2000 D. J. Bernstein Website: http://cr.yp.to/ftpparse.html - Commercial use is fine, if you let me know what programs you're using this in. + Commercial use is fine, if you let me know what programs you're + using this in. External libraries used by this project: === modified file 'include/zorba/function.h' --- include/zorba/function.h 2013-08-23 11:15:04 +0000 +++ include/zorba/function.h 2014-01-15 03:04:02 +0000 @@ -4,7 +4,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software @@ -30,10 +30,10 @@ /**************************************************************************//** The Function class represents a function that is callable from XQuery code, - and it gives access to the various properties that are specified in the + and it gives access to the various properties that are specified in the declaration of the function within a Prolog. - Instances of Function are returned by the StaticContext::findFunctions() + Instances of Function are returned by the StaticContext::findFunctions() method. To be mopre precise, StaticContext::findFunctions() returns smart pointers to Function objects. These smart pointers must be destroyed before the StaticContext object they were obtained from is destroyed. @@ -45,31 +45,27 @@ class ZORBA_DLL_PUBLIC Function : public SmartObject { public: - /** \brief Destructor - */ - virtual ~Function() {} - /** * @return True if the function is sequential; false otherwise. - */ + */ virtual bool isSequential() const = 0; /** * @return True if the function is updating; false otherwise. - */ + */ virtual bool isUpdating() const = 0; /** * @return True if the function is private; false otherwise. - */ + */ virtual bool isPrivate() const = 0; /** * @return True if the function is deterministic; false otherwise. - */ + */ virtual bool isDeterministic() const = 0; @@ -99,7 +95,7 @@ /** * @return The arity of the function. If the function is variadic (which is - * possible only for builtin functions), the result of this method + * possible only for builtin functions), the result of this method * is non-deterministic. */ virtual size_t @@ -119,7 +115,7 @@ /** * @return True if the function implementation is written in XQuery (or - * equivalently, it is a non-external function with a Prolog + * equivalently, it is a non-external function with a Prolog * declaration); false otherwise */ virtual bool @@ -138,10 +134,10 @@ The ExternalFunction class serves as the base of subclasses that represent the implementation/body of external functions. - Instances of ExternalFunction must provide an evaluate method that serves - as the implementation of the function. During its evaluation, an external - function may or may not need to access the static and/or dynamic context of - the invoking XQuery module. If the function implementation does need to + Instances of ExternalFunction must provide an evaluate method that serves + as the implementation of the function. During its evaluation, an external + function may or may not need to access the static and/or dynamic context of + the invoking XQuery module. If the function implementation does need to access either context, the function is referred to as "contextual"; otherwise, it is "non-contextual". *******************************************************************************/ @@ -150,8 +146,7 @@ public: typedef std::vector<ItemSequence*> Arguments_t; - public: - virtual ~ExternalFunction() {} + virtual ~ExternalFunction(); /** * @return The namespace URI of the function QName @@ -189,8 +184,6 @@ class ZORBA_DLL_PUBLIC NonContextualExternalFunction : public ExternalFunction { public: - virtual ~NonContextualExternalFunction() {} - virtual ItemSequence_t evaluate(const Arguments_t&) const = 0; @@ -201,7 +194,7 @@ /**************************************************************************//** The ContextualExternalFunction class serves as the base of subclasses that - represent the implementation of contextual external functions. + represent the implementation of contextual external functions. For each external function, an application must provide a concrete subclass of this class and "store" an instance of the subclass inside an ExternalModule @@ -211,14 +204,12 @@ class ZORBA_DLL_PUBLIC ContextualExternalFunction : public ExternalFunction { public: - virtual ~ContextualExternalFunction() {} - virtual ItemSequence_t evaluate( const Arguments_t&, const StaticContext*, const DynamicContext*) const = 0; - + bool isContextual() const { return true; } }; === modified file 'include/zorba/iterator.h' --- include/zorba/iterator.h 2013-08-01 09:52:25 +0000 +++ include/zorba/iterator.h 2014-01-15 03:04:02 +0000 @@ -34,13 +34,10 @@ class ZORBA_DLL_PUBLIC Iterator : virtual public SmartObject { public: - /** \brief Destructor - */ - virtual ~Iterator() {} - /** \brief Start iterating. * - * This function needs to be called before calling next() or close(). + * This function needs to be called before calling next(), count(), skip() or + * close(). * Its purpose is to create and initialize any resources that may be * needed during the iteration. It should not be called again until * after close() has been called. @@ -73,10 +70,30 @@ close() = 0; /** - * brief Check whether the iterator is open or not + * \brief Check whether the iterator is open or not */ virtual bool isOpen() const = 0; + + /** + * Counts the number of items this iterator would have returned. + * + * @throw ZorbaException if an error occurs or the iterator has not been + * opened. + */ + virtual int64_t + count(); + + /** + * Skips a number of items. + * + * @param count The number of items to skip. + * @return \c true only if there are more items. + * @throw ZorbaException if an error occurs or the iterator has not been + * opened. + */ + virtual bool + skip(int64_t count); }; === modified file 'modules/ftp-client/ftp-client.xq.src/ftp_functions.cpp' --- modules/ftp-client/ftp-client.xq.src/ftp_functions.cpp 2014-01-11 01:27:47 +0000 +++ modules/ftp-client/ftp-client.xq.src/ftp_functions.cpp 2014-01-15 03:04:02 +0000 @@ -612,14 +612,18 @@ // inherited from Iterator void close(); + int64_t count(); bool isOpen() const; bool next( Item& ); void open(); + bool skip( int64_t ); private: ItemFactory *const factory_; istream is_; bool open_; + + bool get_line( string* ); }; list_iterator::list_iterator( curl::streambuf *cbuf, ItemFactory *factory ) : @@ -633,10 +637,32 @@ open_ = false; } +int64_t list_iterator::count() { + int64_t count = 0; + string line; + while ( get_line( &line ) ) { + struct ftpparse ftp_file; + if ( ftpparse( &ftp_file, line.data(), line.size() ) ) + ++count; + } // while + return count; +} + Iterator_t list_iterator::getIterator() { return this; } +bool list_iterator::get_line( string *line ) { + while ( getline( is_, *line ) ) { + if ( !line->empty() ) { + if ( (*line)[ line->size() - 1 ] == '\r' ) + line->erase( line->size() - 1 ); + return true; + } + } // while + return false; +} + bool list_iterator::isOpen() const { return open_; } @@ -647,11 +673,7 @@ static Item const size_key( factory_->createString( "size" ) ); string line; - while ( getline( is_, line ) ) { - if ( line.empty() ) - continue; - if ( line[ line.size() - 1 ] == '\r' ) - line.erase( line.size() - 1 ); + while ( get_line( &line ) ) { struct ftpparse ftp_file; if ( ftpparse( &ftp_file, line.data(), line.size() ) ) { vector<pair<Item,Item> > kv; @@ -709,6 +731,17 @@ open_ = true; } +bool list_iterator::skip( int64_t count ) { + string line; + bool more_items = true; + while ( count > 0 && (more_items = get_line( &line )) ) { + struct ftpparse ftp_file; + if ( ftpparse( &ftp_file, line.data(), line.size() ) ) + --count; + } // while + return more_items; +} + list_function::list_function( module const *m ) : function( m, "list" ) { === modified file 'src/api/CMakeLists.txt' --- src/api/CMakeLists.txt 2014-01-03 17:31:44 +0000 +++ src/api/CMakeLists.txt 2014-01-15 03:04:02 +0000 @@ -16,8 +16,10 @@ SET(API_SRCS base64_util.cpp + external_function.cpp smart_ptr.cpp diagnostic_handler.cpp + iterator.cpp zorba.cpp zorbaimpl.cpp xqueryimpl.cpp === added file 'src/api/external_function.cpp' --- src/api/external_function.cpp 1970-01-01 00:00:00 +0000 +++ src/api/external_function.cpp 2014-01-15 03:04:02 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright 2006-2013 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <zorba/function.h> + +namespace zorba { + +/////////////////////////////////////////////////////////////////////////////// + +ExternalFunction::~ExternalFunction() { + // out-of-line since it's virtual +} + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace zorba +/* vim:set et sw=2 ts=2: */ === added file 'src/api/iterator.cpp' --- src/api/iterator.cpp 1970-01-01 00:00:00 +0000 +++ src/api/iterator.cpp 2014-01-15 03:04:02 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright 2006-2013 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <zorba/item.h> +#include <zorba/iterator.h> + +namespace zorba { + +/////////////////////////////////////////////////////////////////////////////// + +int64_t Iterator::count() { + int64_t count = 0; + Item item; + while ( next( item ) ) + ++count; + return count; +} + +bool Iterator::skip( int64_t count ) { + Item item; + bool more_items = true; + while ( count > 0 && (more_items = next( item )) ) + --count; + return more_items; +} + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace zorba +/* vim:set et sw=2 ts=2: */ === modified file 'src/runtime/base/plan_iterator.cpp' --- src/runtime/base/plan_iterator.cpp 2013-08-05 11:54:06 +0000 +++ src/runtime/base/plan_iterator.cpp 2014-01-15 03:04:02 +0000 @@ -186,7 +186,7 @@ ++count; } - STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, Integer(count)), state); + STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, xs_integer(count)), state); STACK_END(state); } === modified file 'src/runtime/core/fncall_iterator.cpp' --- src/runtime/core/fncall_iterator.cpp 2014-01-10 22:33:46 +0000 +++ src/runtime/core/fncall_iterator.cpp 2014-01-15 03:04:02 +0000 @@ -49,8 +49,9 @@ #include "util/string_util.h" #include "store/api/index.h" +#include "store/api/item_factory.h" +#include "store/api/iterator_factory.h" #include "store/api/store.h" -#include "store/api/iterator_factory.h" #include "store/api/temp_seq.h" @@ -859,6 +860,93 @@ } } +bool ExtFunctionCallIterator::count( store::Item_t &result, + PlanState &planState ) const { + ItemSequence_t api_seq; + + ExtFunctionCallIteratorState *state; + DEFAULT_STACK_INIT( ExtFunctionCallIteratorState, state, planState ); + + try { + if ( theFunction->isContextual() ) { + ContextualExternalFunction const *const f = + dynamic_cast<ContextualExternalFunction const*>( theFunction ); + ZORBA_ASSERT( f ); + StaticContextImpl sctx( + theModuleSctx, + planState.theQuery ? + planState.theQuery->getRegisteredDiagnosticHandlerNoSync() : + nullptr + ); + DynamicContextImpl dctx( + nullptr, planState.theGlobalDynCtx, theModuleSctx + ); + api_seq = f->evaluate( state->m_extArgs, &sctx, &dctx ); + } else { + NonContextualExternalFunction const *const f = + dynamic_cast<NonContextualExternalFunction const*>( theFunction ); + ZORBA_ASSERT( f ); + api_seq = f->evaluate( state->m_extArgs ); + } + if ( !!api_seq ) { + Iterator_t api_iter( api_seq->getIterator() ); + api_iter->open(); + int64_t const count = api_iter->count(); + api_iter->close(); + GENV_ITEMFACTORY->createInteger( result, xs_integer( count ) ); + } + } + catch ( ZorbaException &e ) { + set_source( e, loc ); + throw; + } + STACK_PUSH( true, state ); + STACK_END( state ); +} + +bool ExtFunctionCallIterator::skip( int64_t count, + PlanState &planState ) const { + ItemSequence_t api_seq; + bool more_items; + + ExtFunctionCallIteratorState *state; + DEFAULT_STACK_INIT( ExtFunctionCallIteratorState, state, planState ); + + try { + if ( theFunction->isContextual() ) { + ContextualExternalFunction const *const f = + dynamic_cast<ContextualExternalFunction const*>( theFunction ); + ZORBA_ASSERT( f ); + StaticContextImpl sctx( + theModuleSctx, + planState.theQuery ? + planState.theQuery->getRegisteredDiagnosticHandlerNoSync() : + nullptr + ); + DynamicContextImpl dctx( + nullptr, planState.theGlobalDynCtx, theModuleSctx + ); + api_seq = f->evaluate( state->m_extArgs, &sctx, &dctx ); + } else { + NonContextualExternalFunction const *const f = + dynamic_cast<NonContextualExternalFunction const*>( theFunction ); + ZORBA_ASSERT( f ); + api_seq = f->evaluate( state->m_extArgs ); + } + if ( !!api_seq ) { + Iterator_t api_iter( api_seq->getIterator() ); + api_iter->open(); + more_items = api_iter->skip( count ); + api_iter->close(); + } + } + catch ( ZorbaException &e ) { + set_source( e, loc ); + throw; + } + STACK_PUSH( more_items, state ); + STACK_END( state ); +} bool ExtFunctionCallIterator::nextImpl( store::Item_t& result, @@ -906,17 +994,12 @@ state->theResultIter = state->theResult->getIterator(); } // if (!theFunction->isContextual()) } - catch (XQueryException& e) - { - set_source( e, loc ); - throw; - } catch (ZorbaException& e) { set_source( e, loc ); throw; } - catch (std::exception& e) + catch (std::exception const& e) { throw XQUERY_EXCEPTION( zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR, === modified file 'src/runtime/core/fncall_iterator.h' --- src/runtime/core/fncall_iterator.h 2013-09-26 09:37:30 +0000 +++ src/runtime/core/fncall_iterator.h 2014-01-15 03:04:02 +0000 @@ -259,6 +259,9 @@ void openImpl(PlanState& planState, uint32_t& offset); bool nextImpl(store::Item_t& result, PlanState& planState) const; + + bool count(store::Item_t& result, PlanState& planState) const; + bool skip(int64_t count, PlanState &planState) const; }; }
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp