summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Trader/Offer_Iterator_Collection.cpp
blob: ec78e9f29215cd8e6256c715e0e7c0d4cc497d1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// $Id$

#include "Offer_Iterator_Collection.h"

TAO_Offer_Iterator_Collection::TAO_Offer_Iterator_Collection (void)
  : total_left_ (0)
{
}

void
TAO_Offer_Iterator_Collection::
add_offer_iterator (CosTrading::OfferIterator* offer_iter)
{
  Iter_Info iter_info;

  if (offer_iter != CosTrading::OfferIterator::_nil ())
    {  
      TAO_TRY
	{
	  iter_info.iter_ = offer_iter;
	  iter_info.num_left_ = offer_iter->max_left (TAO_TRY_ENV);
	  TAO_CHECK_ENV;
	}
      TAO_CATCHANY
	{
	  // I don't know what to do here if the offer_iterator throws
	  // an UnknownMaxLeft exception.
	}
      TAO_ENDTRY;

      this->total_left_ += iter_info.num_left_;
      this->iters_.push_back (iter_info);
    }
}

CORBA::Boolean
TAO_Offer_Iterator_Collection::next_n (CORBA::ULong n,
				       CosTrading::OfferSeq_out offers,
				       CORBA::Environment &env)
  TAO_THROW_SPEC ((CORBA::SystemException))
{
  CORBA::ULong offers_left = n;
  CORBA::Boolean return_value = CORBA::B_TRUE;
  CosTrading::OfferSeq_var out_offers;
  
  ACE_NEW_RETURN (offers, CosTrading::OfferSeq, return_value);
  while (offers_left > 0 && ! this->iters_.empty ())
    {
      Iter_Info& iter_info = this->iters_.front ();

      // Determine how many offers we should retrieve from this
      // iterator. 
      CORBA::ULong offers_to_retrieve =
	(offers_left > iter_info.num_left_)
	? iter_info.num_left_
	: offers_left;

      // Retrieve the set of offers.
      iter_info.iter_->next_n
	(offers_to_retrieve,
	 CosTrading::OfferSeq_out (out_offers.out ()),
	 env);

      // Merge it with the passed set.
      CORBA::ULong offset = offers->length ();
      offers->length (out_offers->length () + offset);
      for (int j = out_offers->length () - 1; j >= 0; j--)
	offers[j + offset] = out_offers[j];

      // Adjust the offer counters.
      offers_left -= offers_to_retrieve;
      iter_info.num_left_ -= offers_to_retrieve;
      this->total_left_ -= offers_to_retrieve;

      // If we've exhausted this iterator, destroy it.
      if (iter_info.num_left_ == 0)
	{
	  iter_info.iter_->destroy (env);
	  this->iters_.pop_front ();
	}
    }

  // Determine if we have anything left to offer.
  if (this->iters_.empty ())
    return_value = B_FALSE;

  return return_value;
}

void
TAO_Offer_Iterator_Collection::destroy (CORBA::Environment& _env)  
  TAO_THROW_SPEC ((CORBA::SystemException))
{
  // Destroy all iterators in the collection.
  for (OFFER_ITERS::iterator iters_iter = this->iters_.begin ();
       iters_iter != this->iters_.end ();
       iters_iter++)
    (*iters_iter).iter_->destroy (_env);

  this->total_left_ = 0;

  // Remove self from POA
  //
  // Note that there is no real error checking here as we can't do
  // much about errors here anyway
  //
  
  TAO_TRY
    {
      PortableServer::POA_var poa = this->_default_POA (TAO_TRY_ENV);
      TAO_CHECK_ENV;
      PortableServer::ObjectId_var id =
	poa->servant_to_id (this, TAO_TRY_ENV);
      TAO_CHECK_ENV;
      
      poa->deactivate_object (id.in (), TAO_TRY_ENV);
    }
  TAO_CATCHANY
    {      
    }
  TAO_ENDTRY;
  
  delete this;  
}

CORBA::ULong
TAO_Offer_Iterator_Collection::max_left (CORBA::Environment &env)
  TAO_THROW_SPEC ((CORBA::SystemException,
		   CosTrading::UnknownMaxLeft))
{
  return this->total_left_;
}