00001
00032 #include "linden_common.h"
00033
00034 #include "llcachename.h"
00035
00036
00037 #include "message.h"
00038 #include "llrand.h"
00039 #include "lldbstrings.h"
00040 #include "llframetimer.h"
00041 #include "llhost.h"
00042 #include "lluuid.h"
00043
00044
00045 const char* CN_WAITING = "(waiting)";
00046 const char* CN_NOBODY = "(nobody)";
00047 const char* CN_NONE = "(none)";
00048 const char* CN_HIPPOS = "(hippos)";
00049 const F32 HIPPO_PROBABILITY = 0.01f;
00050
00051
00052
00053 const U32 PENDING_TIMEOUT_SECS = 5 * 60;
00054
00055
00056 const S32 CN_FILE_VERSION = 2;
00057
00058
00059 LLCacheName* gCacheName = NULL;
00060
00064
00065 class LLCacheNameEntry
00066 {
00067 public:
00068 LLCacheNameEntry();
00069
00070 public:
00071 bool mIsGroup;
00072 U32 mCreateTime;
00073 char mFirstName[DB_FIRST_NAME_BUF_SIZE];
00074 char mLastName[DB_LAST_NAME_BUF_SIZE];
00075 char mGroupName[DB_GROUP_NAME_BUF_SIZE];
00076 };
00077
00078 LLCacheNameEntry::LLCacheNameEntry()
00079 {
00080 mFirstName[0] = '\0';
00081 mLastName[0] = '\0';
00082 mGroupName[0] = '\0';
00083 }
00084
00085
00086 class PendingReply
00087 {
00088 public:
00089 LLUUID mID;
00090 LLCacheNameCallback mCallback;
00091 LLHost mHost;
00092 void* mData;
00093 PendingReply(const LLUUID& id, LLCacheNameCallback callback, void* data = NULL)
00094 : mID(id), mCallback(callback), mData(data)
00095 { }
00096
00097 PendingReply(const LLUUID& id, const LLHost& host)
00098 : mID(id), mCallback(0), mHost(host)
00099 { }
00100
00101 void done() { mID.setNull(); }
00102 bool isDone() const { return mID.isNull() != FALSE; }
00103 };
00104
00105 class ReplySender
00106 {
00107 public:
00108 ReplySender(LLMessageSystem* msg);
00109 ~ReplySender();
00110
00111 void send(const LLUUID& id,
00112 const LLCacheNameEntry& entry, const LLHost& host);
00113
00114 private:
00115 void flush();
00116
00117 LLMessageSystem* mMsg;
00118 bool mPending;
00119 bool mCurrIsGroup;
00120 LLHost mCurrHost;
00121 };
00122
00123 ReplySender::ReplySender(LLMessageSystem* msg)
00124 : mMsg(msg), mPending(false)
00125 { }
00126
00127 ReplySender::~ReplySender()
00128 {
00129 flush();
00130 }
00131
00132 void ReplySender::send(const LLUUID& id,
00133 const LLCacheNameEntry& entry, const LLHost& host)
00134 {
00135 if (mPending)
00136 {
00137 if (mCurrIsGroup != entry.mIsGroup
00138 || mCurrHost != host)
00139 {
00140 flush();
00141 }
00142 }
00143
00144 if (!mPending)
00145 {
00146 mPending = true;
00147 mCurrIsGroup = entry.mIsGroup;
00148 mCurrHost = host;
00149
00150 if(mCurrIsGroup)
00151 mMsg->newMessageFast(_PREHASH_UUIDGroupNameReply);
00152 else
00153 mMsg->newMessageFast(_PREHASH_UUIDNameReply);
00154 }
00155
00156 mMsg->nextBlockFast(_PREHASH_UUIDNameBlock);
00157 mMsg->addUUIDFast(_PREHASH_ID, id);
00158 if(mCurrIsGroup)
00159 {
00160 mMsg->addStringFast(_PREHASH_GroupName, entry.mGroupName);
00161 }
00162 else
00163 {
00164 mMsg->addStringFast(_PREHASH_FirstName, entry.mFirstName);
00165 mMsg->addStringFast(_PREHASH_LastName, entry.mLastName);
00166 }
00167
00168 if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock))
00169 {
00170 flush();
00171 }
00172 }
00173
00174 void ReplySender::flush()
00175 {
00176 if (mPending)
00177 {
00178 mMsg->sendReliable(mCurrHost);
00179 mPending = false;
00180 }
00181 }
00182
00183
00184 typedef std::set<LLUUID> AskQueue;
00185 typedef std::vector<PendingReply> ReplyQueue;
00186 typedef std::map<LLUUID,U32> PendingQueue;
00187 typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
00188 typedef std::vector<LLCacheNameCallback> Observers;
00189
00190 class LLCacheName::Impl
00191 {
00192 public:
00193 LLMessageSystem* mMsg;
00194 LLHost mUpstreamHost;
00195
00196 Cache mCache;
00197
00198
00199 AskQueue mAskNameQueue;
00200 AskQueue mAskGroupQueue;
00201
00202
00203 PendingQueue mPendingQueue;
00204
00205
00206 ReplyQueue mReplyQueue;
00207
00208
00209 Observers mObservers;
00210
00211 LLFrameTimer mProcessTimer;
00212
00213 Impl(LLMessageSystem* msg);
00214 ~Impl();
00215
00216 void processPendingAsks();
00217 void processPendingReplies();
00218 void sendRequest(const char* msg_name, const AskQueue& queue);
00219 bool isRequestPending(const LLUUID& id);
00220
00221
00222 void processUUIDRequest(LLMessageSystem* msg, bool isGroup);
00223 void processUUIDReply(LLMessageSystem* msg, bool isGroup);
00224
00225 static void handleUUIDNameRequest(LLMessageSystem* msg, void** userdata);
00226 static void handleUUIDNameReply(LLMessageSystem* msg, void** userdata);
00227 static void handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userdata);
00228 static void handleUUIDGroupNameReply(LLMessageSystem* msg, void** userdata);
00229
00230 void notifyObservers(const LLUUID& id, const char* first, const char* last, BOOL group);
00231 };
00232
00233
00237
00238 LLCacheName::LLCacheName(LLMessageSystem* msg)
00239 : impl(* new Impl(msg))
00240 { }
00241
00242 LLCacheName::LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host)
00243 : impl(* new Impl(msg))
00244 {
00245 setUpstream(upstream_host);
00246 }
00247
00248 LLCacheName::~LLCacheName()
00249 {
00250 delete &impl;
00251 }
00252
00253 LLCacheName::Impl::Impl(LLMessageSystem* msg)
00254 : mMsg(msg), mUpstreamHost(LLHost::invalid)
00255 {
00256 mMsg->setHandlerFuncFast(
00257 _PREHASH_UUIDNameRequest, handleUUIDNameRequest, (void**)this);
00258 mMsg->setHandlerFuncFast(
00259 _PREHASH_UUIDNameReply, handleUUIDNameReply, (void**)this);
00260 mMsg->setHandlerFuncFast(
00261 _PREHASH_UUIDGroupNameRequest, handleUUIDGroupNameRequest, (void**)this);
00262 mMsg->setHandlerFuncFast(
00263 _PREHASH_UUIDGroupNameReply, handleUUIDGroupNameReply, (void**)this);
00264 }
00265
00266
00267 LLCacheName::Impl::~Impl()
00268 {
00269 for_each(mCache.begin(), mCache.end(), DeletePairedPointer());
00270 }
00271
00272
00273 void LLCacheName::setUpstream(const LLHost& upstream_host)
00274 {
00275 impl.mUpstreamHost = upstream_host;
00276 }
00277
00278 void LLCacheName::addObserver(LLCacheNameCallback callback)
00279 {
00280 impl.mObservers.push_back(callback);
00281 }
00282
00283 void LLCacheName::removeObserver(LLCacheNameCallback callback)
00284 {
00285 Observers::iterator it = impl.mObservers.begin();
00286 Observers::iterator end = impl.mObservers.end();
00287
00288 for ( ; it != end; ++it)
00289 {
00290 const LLCacheNameCallback& cb = (*it);
00291 if (cb == callback)
00292 {
00293 impl.mObservers.erase(it);
00294 return;
00295 }
00296 }
00297 }
00298
00299 void LLCacheName::cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data)
00300 {
00301 ReplyQueue::iterator it = impl.mReplyQueue.begin();
00302 ReplyQueue::iterator end = impl.mReplyQueue.end();
00303
00304 for(; it != end; ++it)
00305 {
00306 const PendingReply& reply = (*it);
00307
00308 if ((callback == reply.mCallback)
00309 && (id == reply.mID)
00310 && (user_data == reply.mData) )
00311 {
00312 impl.mReplyQueue.erase(it);
00313 return;
00314 }
00315 }
00316 }
00317
00318 void LLCacheName::importFile(FILE* fp)
00319 {
00320 S32 count = 0;
00321
00322 const S32 BUFFER_SIZE = 1024;
00323 char buffer[BUFFER_SIZE];
00324
00325
00326 char id_string[MAX_STRING];
00327 char firstname[MAX_STRING];
00328 char lastname[MAX_STRING];
00329 U32 create_time;
00330
00331
00332 char* valid = fgets(buffer, BUFFER_SIZE, fp);
00333 if (!valid) return;
00334
00335
00336 char version_string[BUFFER_SIZE];
00337 S32 version = 0;
00338 S32 match = sscanf(
00339 buffer,
00340 "%1023s %d",
00341 version_string, &version);
00342 if ( match != 2
00343 || strcmp(version_string, "version")
00344 || version != CN_FILE_VERSION)
00345 {
00346 llwarns << "Ignoring old cache name file format" << llendl;
00347 return;
00348 }
00349
00350
00351 U32 now = (U32)time(NULL);
00352 const U32 SECS_PER_DAY = 60 * 60 * 24;
00353 U32 delete_before_time = now - (7 * SECS_PER_DAY);
00354
00355 while(!feof(fp))
00356 {
00357 valid = fgets(buffer, BUFFER_SIZE, fp);
00358 if (!valid) break;
00359
00360 match = sscanf(
00361 buffer,
00362 "%254s %u %254s %254s",
00363 id_string,
00364 &create_time,
00365 firstname,
00366 lastname);
00367 if (4 != match) continue;
00368
00369 LLUUID id(id_string);
00370 if (id.isNull()) continue;
00371
00372
00373 S32 i;
00374 for (i = 0; i < UUID_BYTES; i++)
00375 {
00376 id.mData[i] ^= 0x33;
00377 }
00378
00379
00380 if (create_time < delete_before_time) continue;
00381
00382 LLCacheNameEntry* entry = new LLCacheNameEntry();
00383 entry->mIsGroup = false;
00384 entry->mCreateTime = create_time;
00385 LLString::copy(entry->mFirstName, firstname, DB_FIRST_NAME_BUF_SIZE);
00386 LLString::copy(entry->mLastName, lastname, DB_LAST_NAME_BUF_SIZE);
00387 impl.mCache[id] = entry;
00388
00389 count++;
00390 }
00391
00392 llinfos << "LLCacheName loaded " << count << " names" << llendl;
00393 }
00394
00395
00396 void LLCacheName::exportFile(FILE* fp)
00397 {
00398 fprintf(fp, "version\t%d\n", CN_FILE_VERSION);
00399
00400 for (Cache::iterator iter = impl.mCache.begin(),
00401 end = impl.mCache.end();
00402 iter != end; iter++)
00403 {
00404 LLCacheNameEntry* entry = iter->second;
00405
00406
00407 if ( entry->mFirstName[0]
00408 && entry->mLastName[0])
00409 {
00410 LLUUID id = iter->first;
00411
00412
00413 S32 i;
00414 for (i = 0; i < UUID_BYTES; i++)
00415 {
00416 id.mData[i] ^= 0x33;
00417 }
00418
00419 char id_string[UUID_STR_SIZE];
00420 id.toString(id_string);
00421
00422
00423 fprintf(fp, "%s\t%u\t%s\t%s\n",
00424 id_string,
00425 entry->mCreateTime,
00426 entry->mFirstName,
00427 entry->mLastName);
00428 }
00429 }
00430 }
00431
00432
00433 BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last)
00434 {
00435 if(id.isNull())
00436 {
00437
00438
00439 strcpy(first, CN_NOBODY);
00440 last[0] = '\0';
00441 return FALSE;
00442 }
00443
00444 LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
00445 if (entry)
00446 {
00447
00448
00449 strcpy(first, entry->mFirstName);
00450 strcpy(last, entry->mLastName);
00451 return TRUE;
00452 }
00453 else
00454 {
00455
00456
00457 strcpy(first,(ll_frand() < HIPPO_PROBABILITY)
00458 ? CN_HIPPOS
00459 : CN_WAITING);
00460 strcpy(last, "");
00461
00462 if (!impl.isRequestPending(id))
00463 {
00464 impl.mAskNameQueue.insert(id);
00465 }
00466 return FALSE;
00467 }
00468
00469 }
00470
00471
00472
00473 BOOL LLCacheName::getGroupName(const LLUUID& id, char* group)
00474 {
00475 if(id.isNull())
00476 {
00477
00478
00479 strcpy(group, CN_NONE);
00480 return FALSE;
00481 }
00482
00483 LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache,id);
00484 if (entry && !entry->mGroupName[0])
00485 {
00486
00487
00488
00489 lldebugs << "LLCacheName queuing HACK group request: " << id << llendl;
00490 entry = NULL;
00491 }
00492
00493 if (entry)
00494 {
00495
00496
00497 strcpy(group, entry->mGroupName);
00498 return TRUE;
00499 }
00500 else
00501 {
00502
00503
00504 strcpy(group, CN_WAITING);
00505 if (!impl.isRequestPending(id))
00506 {
00507 impl.mAskGroupQueue.insert(id);
00508 }
00509 return FALSE;
00510 }
00511 }
00512
00513
00514
00515 void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data)
00516 {
00517 if(id.isNull())
00518 {
00519 callback(id, CN_NOBODY, "", is_group, user_data);
00520 }
00521
00522 LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
00523 if (entry)
00524 {
00525
00526 if (entry->mIsGroup)
00527 {
00528 callback(id, entry->mGroupName, "", entry->mIsGroup, user_data);
00529 }
00530 else
00531 {
00532 callback(id, entry->mFirstName, entry->mLastName, entry->mIsGroup, user_data);
00533 }
00534 }
00535 else
00536 {
00537
00538 if (!impl.isRequestPending(id))
00539 {
00540 if (is_group)
00541 {
00542 impl.mAskGroupQueue.insert(id);
00543 }
00544 else
00545 {
00546 impl.mAskNameQueue.insert(id);
00547 }
00548 }
00549 impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));
00550 }
00551 }
00552
00553 void LLCacheName::processPending()
00554 {
00555 const F32 SECS_BETWEEN_PROCESS = 0.1f;
00556 if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS))
00557 {
00558 return;
00559 }
00560
00561 if(!impl.mUpstreamHost.isOk())
00562 {
00563 lldebugs << "LLCacheName::processPending() - bad upstream host."
00564 << llendl;
00565 return;
00566 }
00567
00568 impl.processPendingAsks();
00569 impl.processPendingReplies();
00570 }
00571
00572 void LLCacheName::deleteEntriesOlderThan(S32 secs)
00573 {
00574 U32 now = (U32)time(NULL);
00575 U32 expire_time = now - secs;
00576 for(Cache::iterator iter = impl.mCache.begin(); iter != impl.mCache.end(); )
00577 {
00578 Cache::iterator curiter = iter++;
00579 LLCacheNameEntry* entry = curiter->second;
00580 if (entry->mCreateTime < expire_time)
00581 {
00582 delete entry;
00583 impl.mCache.erase(curiter);
00584 }
00585 }
00586
00587
00588 U32 pending_expire_time = now - PENDING_TIMEOUT_SECS;
00589 for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin();
00590 p_iter != impl.mPendingQueue.end(); )
00591 {
00592 PendingQueue::iterator p_curitor = p_iter++;
00593
00594 if (p_curitor->second < pending_expire_time)
00595 {
00596 impl.mPendingQueue.erase(p_curitor);
00597 }
00598 }
00599 }
00600
00601
00602 void LLCacheName::dump()
00603 {
00604 for (Cache::iterator iter = impl.mCache.begin(),
00605 end = impl.mCache.end();
00606 iter != end; iter++)
00607 {
00608 LLCacheNameEntry* entry = iter->second;
00609 if (entry->mIsGroup)
00610 {
00611 llinfos
00612 << iter->first << " = (group) "
00613 << entry->mGroupName
00614 << " @ " << entry->mCreateTime
00615 << llendl;
00616 }
00617 else
00618 {
00619 llinfos
00620 << iter->first << " = "
00621 << entry->mFirstName << " " << entry->mLastName
00622 << " @ " << entry->mCreateTime
00623 << llendl;
00624 }
00625 }
00626 }
00627
00628 void LLCacheName::dumpStats()
00629 {
00630 llinfos << "Queue sizes: "
00631 << " Cache=" << impl.mCache.size()
00632 << " AskName=" << impl.mAskNameQueue.size()
00633 << " AskGroup=" << impl.mAskGroupQueue.size()
00634 << " Pending=" << impl.mPendingQueue.size()
00635 << " Reply=" << impl.mReplyQueue.size()
00636 << " Observers=" << impl.mObservers.size()
00637 << llendl;
00638 }
00639
00640
00641 LLString LLCacheName::getDefaultName()
00642 {
00643 return LLString(CN_WAITING);
00644 }
00645
00646 void LLCacheName::Impl::processPendingAsks()
00647 {
00648 sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
00649 sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue);
00650 mAskNameQueue.clear();
00651 mAskGroupQueue.clear();
00652 }
00653
00654 void LLCacheName::Impl::processPendingReplies()
00655 {
00656 ReplyQueue::iterator it = mReplyQueue.begin();
00657 ReplyQueue::iterator end = mReplyQueue.end();
00658
00659
00660 for(; it != end; ++it)
00661 {
00662 LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
00663 if(!entry) continue;
00664
00665 if (it->mCallback)
00666 {
00667 if (!entry->mIsGroup)
00668 {
00669 (it->mCallback)(it->mID,
00670 entry->mFirstName, entry->mLastName,
00671 FALSE, it->mData);
00672 }
00673 else {
00674 (it->mCallback)(it->mID,
00675 entry->mGroupName, "",
00676 TRUE, it->mData);
00677 }
00678 }
00679 }
00680
00681
00682 ReplySender sender(mMsg);
00683 for (it = mReplyQueue.begin(); it != end; ++it)
00684 {
00685 LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
00686 if(!entry) continue;
00687
00688 if (it->mHost.isOk())
00689 {
00690 sender.send(it->mID, *entry, it->mHost);
00691 }
00692
00693 it->done();
00694 }
00695
00696 mReplyQueue.erase(
00697 remove_if(mReplyQueue.begin(), mReplyQueue.end(),
00698 std::mem_fun_ref(&PendingReply::isDone)),
00699 mReplyQueue.end());
00700 }
00701
00702
00703 void LLCacheName::Impl::sendRequest(
00704 const char* msg_name,
00705 const AskQueue& queue)
00706 {
00707 if(queue.empty())
00708 {
00709 return;
00710 }
00711
00712 bool start_new_message = true;
00713 AskQueue::const_iterator it = queue.begin();
00714 AskQueue::const_iterator end = queue.end();
00715 for(; it != end; ++it)
00716 {
00717 if(start_new_message)
00718 {
00719 start_new_message = false;
00720 mMsg->newMessageFast(msg_name);
00721 }
00722 mMsg->nextBlockFast(_PREHASH_UUIDNameBlock);
00723 mMsg->addUUIDFast(_PREHASH_ID, (*it));
00724
00725 if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock))
00726 {
00727 start_new_message = true;
00728 mMsg->sendReliable(mUpstreamHost);
00729 }
00730 }
00731 if(!start_new_message)
00732 {
00733 mMsg->sendReliable(mUpstreamHost);
00734 }
00735 }
00736
00737 void LLCacheName::Impl::notifyObservers(const LLUUID& id,
00738 const char* first, const char* last, BOOL is_group)
00739 {
00740 for (Observers::const_iterator i = mObservers.begin(),
00741 end = mObservers.end();
00742 i != end;
00743 ++i)
00744 {
00745 (**i)(id, first, last, is_group, NULL);
00746 }
00747 }
00748
00749 bool LLCacheName::Impl::isRequestPending(const LLUUID& id)
00750 {
00751 U32 now = (U32)time(NULL);
00752 U32 expire_time = now - PENDING_TIMEOUT_SECS;
00753
00754 PendingQueue::iterator iter = mPendingQueue.find(id);
00755
00756 if (iter == mPendingQueue.end()
00757 || (iter->second < expire_time) )
00758 {
00759 mPendingQueue[id] = now;
00760 return false;
00761 }
00762
00763 return true;
00764 }
00765
00766 void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
00767 {
00768
00769
00770 if (!mUpstreamHost.isOk())
00771 {
00772 llwarns << "LLCacheName - got UUID name/group request, but no upstream provider!" << llendl;
00773 return;
00774 }
00775
00776 LLHost fromHost = msg->getSender();
00777 ReplySender sender(msg);
00778
00779 S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock);
00780 for(S32 i = 0; i < count; ++i)
00781 {
00782 LLUUID id;
00783 msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i);
00784 LLCacheNameEntry* entry = get_ptr_in_map(mCache, id);
00785 if(entry)
00786 {
00787 if (isGroup != entry->mIsGroup)
00788 {
00789 llwarns << "LLCacheName - Asked for "
00790 << (isGroup ? "group" : "user") << " name, "
00791 << "but found "
00792 << (entry->mIsGroup ? "group" : "user")
00793 << ": " << id << llendl;
00794 }
00795 else
00796 {
00797
00798 sender.send(id, *entry, fromHost);
00799 }
00800 }
00801 else
00802 {
00803 if (!isRequestPending(id))
00804 {
00805 if (isGroup)
00806 {
00807 mAskGroupQueue.insert(id);
00808 }
00809 else
00810 {
00811 mAskNameQueue.insert(id);
00812 }
00813 }
00814
00815 mReplyQueue.push_back(PendingReply(id, fromHost));
00816 }
00817 }
00818 }
00819
00820
00821
00822 void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
00823 {
00824 S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock);
00825 for(S32 i = 0; i < count; ++i)
00826 {
00827 LLUUID id;
00828 msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i);
00829 LLCacheNameEntry* entry = get_ptr_in_map(mCache, id);
00830 if (!entry)
00831 {
00832 entry = new LLCacheNameEntry;
00833 mCache[id] = entry;
00834 }
00835
00836 mPendingQueue.erase(id);
00837
00838 entry->mIsGroup = isGroup;
00839 entry->mCreateTime = (U32)time(NULL);
00840 if (!isGroup)
00841 {
00842 msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, entry->mFirstName, i);
00843 msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_LastName, DB_LAST_NAME_BUF_SIZE, entry->mLastName, i);
00844 }
00845 else
00846 {
00847 msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_GroupName, DB_GROUP_NAME_BUF_SIZE, entry->mGroupName, i);
00848 }
00849
00850 if (!isGroup)
00851 {
00852 notifyObservers(id,
00853 entry->mFirstName, entry->mLastName,
00854 FALSE);
00855 }
00856 else
00857 {
00858 notifyObservers(id, entry->mGroupName, "", TRUE);
00859 }
00860 }
00861 }
00862
00863
00864
00865
00866
00867 void LLCacheName::Impl::handleUUIDNameReply(LLMessageSystem* msg, void** userData)
00868 {
00869 ((LLCacheName::Impl*)userData)->processUUIDReply(msg, false);
00870 }
00871
00872 void LLCacheName::Impl::handleUUIDNameRequest(LLMessageSystem* msg, void** userData)
00873 {
00874 ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, false);
00875 }
00876
00877 void LLCacheName::Impl::handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userData)
00878 {
00879 ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, true);
00880 }
00881
00882 void LLCacheName::Impl::handleUUIDGroupNameReply(LLMessageSystem* msg, void** userData)
00883 {
00884 ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true);
00885 }
00886
00887
00888
00889