[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Handle_Set.cpp
blob8eb5186cc21c32f5a7ae5f33ffab3578a599cd71
1 // Handle_Set.cpp
2 // $Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $
4 #include "ace/Handle_Set.h"
6 #if !defined (__ACE_INLINE__)
7 #include "ace/Handle_Set.inl"
8 #endif /* __ACE_INLINE__ */
10 #include "ace/OS_NS_string.h"
12 ACE_RCSID(ace, Handle_Set, "$Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $")
14 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
16 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set)
18 // ACE_MSB_MASK is only used here.
19 // This needs to go here to avoid overflow problems on some compilers.
20 #if defined (ACE_WIN32)
21 // Does ACE_WIN32 have an fd_mask?
22 # define ACE_MSB_MASK (~(1 << (NFDBITS - 1)))
23 #else /* ! ACE_WIN32 */
24 # define ACE_MSB_MASK (~((fd_mask) 1 << (NFDBITS - 1)))
25 #endif /* ! ACE_WIN32 */
27 #if defined (__BORLANDC__) && !defined (ACE_WIN32)
28 // The Borland C++ compiler on Linux also doesn't have fds_bits, but has __fds_bits.
29 #define fds_bits __fds_bits
30 #endif
32 #if defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !defined (_XOPEN_SOURCE)
33 // XPG4.2 requires the fds_bits member name, so it is not enabled by
34 // default on Linux/glibc-2.1.x systems. Instead use "__fds_bits."
35 // Ugly, but "what are you going to do?" 8-)
36 #define fds_bits __fds_bits
37 #endif /* linux && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !_XOPEN_SOURCE */
39 void
40 ACE_Handle_Set::dump (void) const
42 #if defined (ACE_HAS_DUMP)
43 ACE_TRACE ("ACE_Handle_Set::dump");
45 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
47 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), this->size_));
48 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmax_handle_ = %d"), this->max_handle_));
49 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n[ ")));
51 #if defined (ACE_WIN32)
52 for (size_t i = 0; i < (size_t) this->mask_.fd_count + 1; i++)
53 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %x "), this->mask_.fd_array[i]));
54 #else /* !ACE_WIN32 */
55 for (ACE_HANDLE i = 0; i < this->max_handle_ + 1; i++)
56 if (this->is_set (i))
57 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %d "), i));
58 #endif /* ACE_WIN32 */
60 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" ]\n")));
61 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
62 #endif /* ACE_HAS_DUMP */
65 // Table that maps bytes to counts of the enabled bits in each value
66 // from 0 to 255,
68 // nbits_[0] == 0
70 // because there are no bits enabled for the value 0.
72 // nbits_[5] == 2
74 // because there are 2 bits enabled in the value 5, i.e., it's
75 // 101 in binary.
77 const char ACE_Handle_Set::nbits_[256] =
79 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
80 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
81 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
82 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
83 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
84 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
85 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
86 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
87 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
88 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
89 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
90 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
91 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
92 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
93 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
94 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
96 // Constructor, initializes the bitmask to all 0s.
98 ACE_Handle_Set::ACE_Handle_Set (void)
100 ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
101 this->reset ();
104 ACE_Handle_Set::ACE_Handle_Set (const fd_set &fd_mask)
106 ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
107 this->reset ();
108 ACE_OS::memcpy ((void *) &this->mask_,
109 (void *) &fd_mask,
110 sizeof this->mask_);
111 #if !defined (ACE_WIN32)
112 this->sync (ACE_Handle_Set::MAXSIZE);
113 #if defined (ACE_HAS_BIG_FD_SET)
114 this->min_handle_ = 0;
115 #endif /* ACE_HAS_BIG_FD_SET */
116 #endif /* !ACE_WIN32 */
119 // Counts the number of bits enabled in N. Uses a table lookup to
120 // speed up the count.
123 ACE_Handle_Set::count_bits (u_long n)
126 ACE_TRACE ("ACE_Handle_Set::count_bits");
127 #if defined (ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT)
128 register int rval = 0;
130 // Count the number of enabled bits in <n>. This algorithm is very
131 // fast, i.e., O(enabled bits in n).
133 for (register u_long m = n;
134 m != 0;
135 m &= m - 1)
136 rval++;
138 return rval;
139 #else
140 return (ACE_Handle_Set::nbits_[n & 0xff]
141 + ACE_Handle_Set::nbits_[(n >> 8) & 0xff]
142 + ACE_Handle_Set::nbits_[(n >> 16) & 0xff]
143 + ACE_Handle_Set::nbits_[(n >> 24) & 0xff]);
144 #endif /* ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT */
147 #if defined (ACE_HAS_BIG_FD_SET)
148 // Find the bit position counting from right to left worst case
149 // (1<<31) is 8.
152 ACE_Handle_Set::bitpos (u_long bit)
154 register int l = 0;
155 register u_long n = bit - 1;
157 // This is a fast count method when have the most significative bit.
159 while (n >> 8)
161 n >>= 8;
162 l += 8;
165 // Is greater than 15?
166 if (n & 16)
168 n >>= 4;
169 l += 4;
172 // Count number remaining bits.
173 while (n != 0)
175 n &= n - 1;
176 l++;
178 return l;
180 #endif /* ACE_HAS_BIG_FD_SET */
182 // Synchronize the underlying FD_SET with the MAX_FD and the SIZE.
184 #if defined (ACE_USE_SHIFT_FOR_EFFICIENCY)
185 // These don't work because shifting right 3 bits is not the same as
186 // dividing by 3, e.g., dividing by 8 requires shifting right 3 bits.
187 // In order to do the shift, we need to calculate the number of bits
188 // at some point.
189 #define ACE_DIV_BY_WORDSIZE(x) ((x) >> ((int) ACE_Handle_Set::WORDSIZE))
190 #define ACE_MULT_BY_WORDSIZE(x) ((x) << ((int) ACE_Handle_Set::WORDSIZE))
191 #else
192 #define ACE_DIV_BY_WORDSIZE(x) ((x) / ((int) ACE_Handle_Set::WORDSIZE))
193 #define ACE_MULT_BY_WORDSIZE(x) ((x) * ((int) ACE_Handle_Set::WORDSIZE))
194 #endif /* ACE_USE_SHIFT_FOR_EFFICIENCY */
196 void
197 ACE_Handle_Set::sync (ACE_HANDLE max)
199 ACE_TRACE ("ACE_Handle_Set::sync");
200 #if !defined (ACE_WIN32)
201 fd_mask *maskp = (fd_mask *)(this->mask_.fds_bits);
202 this->size_ = 0;
204 for (int i = ACE_DIV_BY_WORDSIZE (max - 1);
205 i >= 0;
206 i--)
207 this->size_ += ACE_Handle_Set::count_bits (maskp[i]);
209 this->set_max (max);
210 #else
211 ACE_UNUSED_ARG (max);
212 #endif /* !ACE_WIN32 */
215 // Resets the MAX_FD after a clear of the original MAX_FD.
217 void
218 ACE_Handle_Set::set_max (ACE_HANDLE current_max)
220 ACE_TRACE ("ACE_Handle_Set::set_max");
221 #if !defined(ACE_WIN32)
222 fd_mask * maskp = (fd_mask *)(this->mask_.fds_bits);
224 if (this->size_ == 0)
225 this->max_handle_ = ACE_INVALID_HANDLE;
226 else
228 int i;
230 for (i = ACE_DIV_BY_WORDSIZE (current_max - 1);
231 maskp[i] == 0;
232 i--)
233 continue;
234 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
235 // bits are in reverse order, MSB (sign bit) = bit 0.
236 this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
237 for (fd_mask val = maskp[i];
238 (val & ACE_MSB_MASK) != 0;
239 val = (val << 1))
240 ++this->max_handle_;
241 #elif 1 /* !defined(ACE_HAS_BIG_FD_SET) */
242 this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
243 for (fd_mask val = maskp[i];
244 (val & ~1) != 0; // This obscure code is needed since "bit 0" is in location 1...
245 val = (val >> 1) & ACE_MSB_MASK)
246 ++this->max_handle_;
247 #else
248 register u_long val = this->mask_.fds_bits[i];
249 this->max_handle_ = ACE_MULT_BY_WORDSIZE (i)
250 + ACE_Handle_Set::bitpos(val & ~(val - 1));
251 #endif /* 1 */
254 // Do some sanity checking...
255 if (this->max_handle_ >= ACE_Handle_Set::MAXSIZE)
256 this->max_handle_ = ACE_Handle_Set::MAXSIZE - 1;
257 #else
258 ACE_UNUSED_ARG (current_max);
259 #endif /* !ACE_WIN32 */
262 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator)
264 void
265 ACE_Handle_Set_Iterator::dump (void) const
267 #if defined (ACE_HAS_DUMP)
268 ACE_TRACE ("ACE_Handle_Set_Iterator::dump");
270 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
271 #if defined(ACE_WIN32) || !defined(ACE_HAS_BIG_FD_SET)
272 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhandle_index_ = %d"), this->handle_index_));
273 #elif defined(ACE_HAS_BIG_FD_SET)
274 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_max_ = %d"), this->word_max_));
275 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_val_ = %d"), this->word_val_));
276 #endif
277 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_num_ = %d"), this->word_num_));
278 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
279 #endif /* ACE_HAS_DUMP */
282 ACE_HANDLE
283 ACE_Handle_Set_Iterator::operator () (void)
285 ACE_TRACE ("ACE_Handle_Set_Iterator::operator");
286 #if defined (ACE_WIN32)
287 if (this->handle_index_ < this->handles_.mask_.fd_count)
288 // Return the handle and advance the iterator.
289 return (ACE_HANDLE) this->handles_.mask_.fd_array[this->handle_index_++];
290 else
291 return ACE_INVALID_HANDLE;
293 #elif !defined (ACE_HAS_BIG_FD_SET) /* !ACE_WIN32 */
294 // No sense searching further than the max_handle_ + 1;
295 ACE_HANDLE maxhandlep1 = this->handles_.max_handle_ + 1;
297 // HP-UX 11 plays some games with the fd_mask type - fd_mask is
298 // defined as an int_32t, but the fds_bits is an array of longs.
299 // This makes plainly indexing through the array by hand tricky,
300 // since the FD_* macros treat the array as int32_t. So the bits
301 // are in the right place for int32_t, even though the array is
302 // long. This, they say, is to preserve the same in-memory layout
303 // for 32-bit and 64-bit processes. So, we play the same game as
304 // the FD_* macros to get the bits right. On all other systems,
305 // this amounts to practically a NOP, since this is what would have
306 // been done anyway, without all this type jazz.
307 fd_mask * maskp = (fd_mask *)(this->handles_.mask_.fds_bits);
309 if (this->handle_index_ >= maxhandlep1)
310 // We've seen all the handles we're interested in seeing for this
311 // iterator.
312 return ACE_INVALID_HANDLE;
313 else
315 ACE_HANDLE result = this->handle_index_;
317 // Increment the iterator and advance to the next bit in this
318 // word.
319 this->handle_index_++;
320 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
321 // bits are in reverse order, MSB (sign bit) = bit 0.
322 this->word_val_ = (this->word_val_ << 1);
323 # else
324 this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
325 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
327 // If we've examined all the bits in this word, we'll go onto
328 // the next word.
330 if (this->word_val_ == 0)
332 // Start the handle_index_ at the beginning of the next word
333 // and then loop until we've found the first non-zero bit or
334 // we run past the <maxhandlep1> of the bitset.
336 for (this->handle_index_ = ACE_MULT_BY_WORDSIZE(++this->word_num_);
337 this->handle_index_ < maxhandlep1
338 && maskp[this->word_num_] == 0;
339 this->word_num_++)
340 this->handle_index_ += ACE_Handle_Set::WORDSIZE;
342 // If the bit index becomes >= the maxhandlep1 that means
343 // there weren't any more bits set that we want to consider.
344 // Therefore, we'll just store the maxhandlep1, which will
345 // cause <operator()> to return <ACE_INVALID_HANDLE>
346 // immediately next time it's called.
347 if (this->handle_index_ >= maxhandlep1)
349 this->handle_index_ = maxhandlep1;
350 return result;
352 else
353 // Load the bits of the next word.
354 this->word_val_ = maskp[this->word_num_];
357 // Loop until we get <word_val_> to have its least significant
358 // bit enabled, keeping track of which <handle_index> this
359 // represents (this information is used by subsequent calls to
360 // <operator()>).
362 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
363 // bits are in reverse order, MSB (sign bit) = bit 0.
364 for (;
365 this->word_val_ > 0;
366 this->word_val_ = (this->word_val_ << 1))
367 this->handle_index_++;
368 # else
369 for (;
370 ACE_BIT_DISABLED (this->word_val_, 1);
371 this->handle_index_++)
372 this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
373 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
375 return result;
377 #else /* !ACE_HAS_BIG_FD_SET */
378 // Find the first word in fds_bits with bit on
379 register u_long lsb = this->word_val_;
381 if (lsb == 0)
385 // We have exceeded the word count in Handle_Set?
386 if (++this->word_num_ >= this->word_max_)
387 return ACE_INVALID_HANDLE;
389 lsb = this->handles_.mask_.fds_bits[this->word_num_];
391 while (lsb == 0);
393 // Set index to word boundary.
394 this->handle_index_ = ACE_MULT_BY_WORDSIZE (this->word_num_);
396 // Put new word_val.
397 this->word_val_ = lsb;
399 // Find the least significative bit.
400 lsb &= ~(lsb - 1);
402 // Remove least significative bit.
403 this->word_val_ ^= lsb;
405 // Save to calculate bit distance.
406 this->oldlsb_ = lsb;
408 // Move index to least significative bit.
409 while (lsb >>= 1)
410 this->handle_index_++;
412 else
414 // Find the least significative bit.
415 lsb &= ~(lsb - 1);
417 // Remove least significative bit.
418 this->word_val_ ^= lsb;
420 register u_long n = lsb - this->oldlsb_;
422 // Move index to bit distance between new lsb and old lsb.
425 this->handle_index_++;
426 n &= n >> 1;
428 while (n != 0);
430 this->oldlsb_ = lsb;
433 return this->handle_index_;
434 #endif /* ACE_WIN32 */
437 ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs)
438 : handles_ (hs),
439 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
440 handle_index_ (0),
441 word_num_ (-1)
442 #elif defined (ACE_HAS_BIG_FD_SET)
443 oldlsb_ (0),
444 word_max_ (hs.max_handle_ == ACE_INVALID_HANDLE
446 : ((ACE_DIV_BY_WORDSIZE (hs.max_handle_)) + 1))
447 #endif /* ACE_HAS_BIG_FD_SET */
449 ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator");
450 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
451 // No sense searching further than the max_handle_ + 1;
452 ACE_HANDLE maxhandlep1 =
453 this->handles_.max_handle_ + 1;
455 fd_mask *maskp =
456 (fd_mask *)(this->handles_.mask_.fds_bits);
458 // Loop until we've found the first non-zero bit or we run past the
459 // <maxhandlep1> of the bitset.
460 while (this->handle_index_ < maxhandlep1
461 && maskp[++this->word_num_] == 0)
462 this->handle_index_ += ACE_Handle_Set::WORDSIZE;
464 // If the bit index becomes >= the maxhandlep1 that means there
465 // weren't any bits set. Therefore, we'll just store the
466 // maxhandlep1, which will cause <operator()> to return
467 // <ACE_INVALID_HANDLE> immediately.
468 if (this->handle_index_ >= maxhandlep1)
469 this->handle_index_ = maxhandlep1;
470 else
471 // Loop until we get <word_val_> to have its least significant bit
472 // enabled, keeping track of which <handle_index> this represents
473 // (this information is used by <operator()>).
474 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
475 // bits are in reverse order, MSB (sign bit) = bit 0.
476 for (this->word_val_ = maskp[this->word_num_];
477 this->word_val_ > 0;
478 this->word_val_ = (this->word_val_ << 1))
479 this->handle_index_++;
480 # else
481 for (this->word_val_ = maskp[this->word_num_];
482 ACE_BIT_DISABLED (this->word_val_, 1)
483 && this->handle_index_ < maxhandlep1;
484 this->handle_index_++)
485 this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
486 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
487 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
488 if (this->word_max_==0)
490 this->word_num_ = -1;
491 this->word_val_ = 0;
493 else
495 this->word_num_ =
496 ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
497 this->word_val_ = 0;
499 #endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
503 void
504 ACE_Handle_Set_Iterator::reset_state (void)
506 ACE_TRACE ("ACE_Handle_Set_Iterator::reset_state");
508 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
509 this->handle_index_ = 0;
510 this->word_num_ = -1;
511 #elif defined (ACE_HAS_BIG_FD_SET)
512 this->oldlsb_ = 0;
513 this->word_max_ =
514 this->handles_.max_handle_ == ACE_INVALID_HANDLE ? 0
515 : ((ACE_DIV_BY_WORDSIZE (this->handles_.max_handle_)) + 1);
516 #endif /* ACE_HAS_BIG_FD_SET */
518 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
519 // No sense searching further than the max_handle_ + 1;
520 ACE_HANDLE maxhandlep1 =
521 this->handles_.max_handle_ + 1;
523 fd_mask *maskp =
524 (fd_mask *)(this->handles_.mask_.fds_bits);
526 // Loop until we've found the first non-zero bit or we run past the
527 // <maxhandlep1> of the bitset.
528 while (this->handle_index_ < maxhandlep1
529 && maskp[++this->word_num_] == 0)
530 this->handle_index_ += ACE_Handle_Set::WORDSIZE;
532 // If the bit index becomes >= the maxhandlep1 that means there
533 // weren't any bits set. Therefore, we'll just store the
534 // maxhandlep1, which will cause <operator()> to return
535 // <ACE_INVALID_HANDLE> immediately.
536 if (this->handle_index_ >= maxhandlep1)
537 this->handle_index_ = maxhandlep1;
538 else
539 // Loop until we get <word_val_> to have its least significant bit
540 // enabled, keeping track of which <handle_index> this represents
541 // (this information is used by <operator()>).
542 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
543 // bits are in reverse order, MSB (sign bit) = bit 0.
544 for (this->word_val_ = maskp[this->word_num_];
545 this->word_val_ > 0;
546 this->word_val_ = (this->word_val_ << 1))
547 this->handle_index_++;
548 # else
549 for (this->word_val_ = maskp[this->word_num_];
550 ACE_BIT_DISABLED (this->word_val_, 1)
551 && this->handle_index_ < maxhandlep1;
552 this->handle_index_++)
553 this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
554 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
555 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
556 if (this->word_max_==0)
558 this->word_num_ = -1;
559 this->word_val_ = 0;
561 else
563 this->word_num_ =
564 ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
565 this->word_val_ = 0;
567 #endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
570 ACE_END_VERSIONED_NAMESPACE_DECL