#!/usr/bin/env python
#############################################################################
# Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
# All Rights Reserved.
#
# The software contained on this media is the property of the DSTC Pty
# Ltd.  Use of this software is strictly in accordance with the
# license agreement in the accompanying LICENSE.HTML file.  If your
# distribution of this software does not contain a LICENSE.HTML file
# then you have no rights to use this software in any manner and
# should contact DSTC at the address below to determine an appropriate
# licensing arrangement.
# 
#      DSTC Pty Ltd
#      Level 7, GP South
#      Staff House Road
#      University of Queensland
#      St Lucia, 4072
#      Australia
#      Tel: +61 7 3365 4310
#      Fax: +61 7 3365 4311
#      Email: enquiries@dstc.edu.au
# 
# This software is being provided "AS IS" without warranty of any
# kind.  In no event shall DSTC Pty Ltd be liable for damage of any
# kind arising out of or in connection with the use or performance of
# this software.
#
# Project:      Fnorb
# File:         $Source: /projects/fnorb/Fnorb-1.1/cos/naming/RCS/BindingIterator.py,v $
# Version:      @(#)$RCSfile: BindingIterator.py,v $ $Revision: 1.7 $
#
#############################################################################
""" Cos Naming Service Binding Iterators. """


# Fnorb modules.
from Fnorb.orb import fnorb_thread, BOA

# Types.
import CosNaming

# Server skeleton.
import CosNaming_skel


def BindingIteratorFactory_init():
    """ Initialise the Binding Iterator Factory.

    This is a factory function for the BindingIteratorFactory class (the 
    factory is a singleton (ie. there can only be one instance per process)).

    """
    try:
	bif = BindingIteratorFactory()

    except BindingIteratorFactory, bif:
	pass

    return bif


class BindingIteratorFactory:
    """ Factory for binding iterators.

    The factory is a singleton (ie. there can only be one instance per
    process).

    """
    # Singleton instance.
    __instance = None

    def __init__(self):
	""" Constructor. """

	# The factory is a singleton (ie. there can only be one instance per
	# process).
	if BindingIteratorFactory.__instance is not None:
	    raise BindingIteratorFactory.__instance

	BindingIteratorFactory.__instance = self

	return

    def create_binding_iterator(self, bindings):
	""" Create a new binding iterator instance. """

	# Create the instance.
	impl = BindingIterator(bindings)

	# Create an object reference with a 'random' object key.
	boa = BOA.BOA_init()
	obj = boa.create(str(id(impl)), BindingIterator._FNORB_ID)

	# Activate the implementation (ie. connect the generated object
	# reference to the implementation).
	boa.obj_is_ready(obj, impl)

	return obj


class BindingIterator(CosNaming_skel.BindingIterator_skel):
    """ Binding Iterator. """

    def __init__(self, bindings):
	""" Constructor. """

	self.__bindings = bindings
	self.__index = 0

	# Mutex to make access to the list of bindings safe in threaded
	# environments.
	self.__lk = fnorb_thread.allocate_lock()

	return

    def __del__(self):
	pass

    def next_one(self):
	""" Return the next binding. """

	self.__lk.acquire()
	if self.__index >= len(self.__bindings):
	    result = 0
	    binding = self.__bindings[-1]

	else:
	    result = 1
	    binding = self.__bindings[self.__index]
	    self.__index = self.__index + 1
	self.__lk.release()

	return (result, binding)

    def next_n(self, how_many):
	""" Return the next 'how_many' bindings. """

	self.__lk.acquire()
	if self.__index >= len(self.__bindings):
	    result = 0
	    binding_list = []

	else:
	    result = 1
	    binding_list = self.__bindings[self.__index:self.__index+how_many]
	    self.__index = self.__index + how_many
	self.__lk.release()

	return (result, binding_list)

    def destroy(self):
	""" Destroy the iterator. """

	self.__lk.acquire()
	del self.__bindings
	self.__lk.release()

	# Disconnect the implementation from the BOA.
	boa = BOA.BOA_init()
	boa.deactivate_obj(self)

	return

#############################################################################
