1 #if !defined (ACE_LOCAL_LOCATOR_C)
2 #define ACE_LOCAL_LOCATOR_C
4 #include "Local_Locator.h"
6 #if !defined (__ACE_INLINE__)
7 #include "Local_Locator.inl"
8 #endif /* __ACE_INLINE__ */
11 ACE_URL_Local_Locator::url_query (const ACE_URL_Locator::ACE_Selection_Criteria how
,
12 const ACE_URL_Property_Seq
*pseq
,
13 const size_t how_many
,
15 ACE_URL_Offer_Seq
*offer
)
17 ACE_URL_Record
*item
= 0;
19 ACE_NEW_RETURN (offer
, ACE_URL_Offer_Seq (how_many
), -1);
21 if (how
>= ACE_URL_Locator::INVALID_SELECTION
)
23 errno
= ACE_URL_Locator::INVALID_ARGUMENT
;
28 for (ACE_Unbounded_Set_Iterator
<ACE_URL_Record
> iter (this->repository_
);
29 iter
.next (item
) != 0;
36 // Now this is a stupid implementation. Perhaps we can
37 // implement this using Hash_Map. Better yet, I think we should
38 // put this in a database and put SQL query here.
39 for (i_query
= 0; found
== 0 && i_query
< pseq
->size (); i_query
++)
40 for (i_db
= 0; i_db
< item
->offer_
->url_properties ().size (); i_db
++)
42 if ((*pseq
)[i_query
].name () == item
->offer_
->url_properties ()[i_db
].name ())
43 if (how
== ACE_URL_Locator::SOME
)
46 // if match and Some, copy to <offer>, inc <num_query>, advance iterator
48 // else if All, advance iterator
50 // else if None, check next property in <pseq>.
52 if (all properties checked
and found
and ALL
)
53 copy to
<offer
>; inc
<num_query
>;
54 else if (all properties checked
and not found
and NONE
)
55 copy to
<offer
>; inc
<num_query
>;
57 shouldn
't happen, internal error
59 if (num_query == how_many)
67 ACE_URL_Local_Locator::export_offer (ACE_URL_Offer *offer,
68 ACE_WString &offer_id)
70 ACE_URL_Record *item = 0;
72 // First check if we have registered this URL already.
73 for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
74 iter.next (item) != 0;
76 if (*item->offer_->url () == *offer->url ())
78 errno = ACE_URL_Locator::OFFER_EXIST;
82 ACE_URL_Record *new_offer;
84 // Offer is not in repository, we can add new one in safely.
85 ACE_NEW_RETURN (new_offer, ACE_URL_Record (offer),
86 ACE_URL_Locator::NOMEM);
88 this->repository_.push (*new_offer);
90 offer_id = *new_offer->id_;
95 ACE_URL_Local_Locator::withdraw_offer (const ACE_WString &offer_id)
97 ACE_URL_Record *item = 0;
99 // Iterate thru repository and remove offer with <offer_id>.
100 for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
101 iter.next (item) != 0;
103 if (offer_id == *item->id_)
105 if (this->repository_.remove (*item) == 0)
109 errno = ACE_URL_Locator::UNKNOWN;
114 errno = ACE_URL_Locator::NO_SUCH_OFFER;
119 ACE_URL_Local_Locator::describe_offer (const ACE_WString &offer_id,
120 ACE_URL_Offer *offer)
122 ACE_URL_Record *item = 0;
124 // Iterate thru the repository and produce a copy of offer's
126 for (ACE_Unbounded_Set_Iterator
<ACE_URL_Record
> iter (this->repository_
);
127 iter
.next (item
) != 0;
129 if (offer_id
== *item
->id_
)
131 ACE_NEW_RETURN (offer
, ACE_URL_Offer (*item
->offer_
), -1);
135 errno
= ACE_URL_Locator::NO_SUCH_OFFER
;
140 ACE_URL_Local_Locator::modify_offer (const ACE_WString
&offer_id
,
141 const ACE_WString
*url
,
142 const ACE_URL_Property_Seq
*del
,
143 const ACE_URL_Property_Seq
*modify
)
145 ACE_Unbounded_Set_Iterator
<ACE_URL_Record
> iter (this->repository_
);
146 ACE_URL_Record
*item
= 0;
147 ACE_URL_Record
*target
= 0;
151 for (; iter
.next (item
) != 0; iter
.advance ())
153 if (url
!= 0 && *url
== item
->offer_
->url ())
155 errno
= ACE_URL_Locator::OFFER_EXIST
;
158 if (offer_id
== *item
->id_
)
162 if (target
!= 0) // Aha, we found a target to work on
164 if (del
!= 0 && modify
!= 0)
166 // We need to make a copy of the original property sequence
167 // so if any error occurs, we can revert our change easily.
169 // First we need to calculate the maximum number of perperties.
170 int psize
= target
->offer_
->url_properties ().size ();
172 if ((psize
-= del
->size ()) < 0)
174 // If you try to delete more properties than we have,
175 // you are doomed. No need to proceed.
176 errno
= ACE_URL_Locator::INVALID_ARGUMENT
;
180 // In the worst case, all properties in <modify> will be added.
181 psize
+= modify
->size ();
183 // Now, create a temporary work space.
184 ACE_URL_Property_Seq
working (psize
);
186 for (; sz
< item
->offer_
->url_properties ().size ())
187 working
[sz
] = item
->offer_
->url_properties() [sz
];
191 // Argh, this is really a stupid design.
192 // Go thru every property we want to delete
193 for (size_t i
= 0; i
< del
->size () && sz
> 0; i
++)
194 // For earch, go thru our property sequence and
195 // search for the property.
196 for (size_t j
= 0; j
< sz
; j
++)
197 if ((*del
)[i
].name () == working
[j
].name ())
200 working
[j
] = working
[sz
]; // pack the array.
203 // Doesn't generate error when we want to delete an
204 // imaginary property. Is this appropriate?
209 // This is also stupid.
210 // Go thru every property we want to modify/add
211 for (size_t i
= 0; i
< modify
->size () && sz
> 0; i
++)
213 // For each property, go thru our property list
214 // and search for the matching property
215 for (size_t j
= 0; j
< sz
; j
++)
216 if ((*modify
)[i
].name () == working
[j
].name ())
219 working
[j
].value ((*modify
)[i
].value ().fast_rep ());
223 // No matching property name were found,
224 // We want to add this property into the list.
226 working
[sz
++] = (*modify
)[i
];
231 // Yes, all operations passed. We can now copy the working version back.
232 item
->offer_
->url_properties (ACE_URL_Property_Seq (sz
));
233 for (size_t i
= 0; i
< sz
; i
++)
234 item
->offer_
->url_properties ()[i
] = working
[i
];
237 item
->offer_
->url (url
->fast_rep ()); // replace URL location.
240 errno
= ACE_URL_Locator::NO_SUCH_OFFER
;
244 #endif /* ACE_LOCAL_LOCATOR_C */