// Find the next like-instance of the designated object . UtlContainable* UtlSListIterator::findNext(const UtlContainable* containableToMatch) { UtlContainable* match = NULL; UtlContainer::acquireIteratorConnectionLock(); OsLock takeContainer(mContainerRefLock); UtlSList* myList = static_cast<UtlSList*>(mpMyContainer); OsLock take(myList->mContainerLock); UtlContainer::releaseIteratorConnectionLock(); // advance the iterator UtlLink* nextLink = (mpCurrentNode == NULL ? myList->head() : mpCurrentNode->next() ); // search for the next match forward while (nextLink && !match) { UtlContainable *candidate = (UtlContainable*)nextLink->data; if (candidate && candidate->compareTo(containableToMatch) == 0) { mpCurrentNode = nextLink; match = candidate; } else { nextLink = nextLink->next(); } } return match; }
// Find the first occurrence of the designated object by equality. UtlContainable* UtlSList::find(const UtlContainable* containableToMatch) const { UtlLink* listNode; UtlContainable* matchElement = NULL; UtlContainable* visitNode; unsigned targetHash = containableToMatch->hash(); OsLock take(mContainerLock); LIST_SANITY_CHECK; for(listNode = head()->findNextHash(targetHash); listNode && matchElement == NULL; listNode = listNode->next()->findNextHash(targetHash) ) { visitNode = (UtlContainable*) listNode->data; if(visitNode && visitNode->compareTo(containableToMatch) == 0) { matchElement = visitNode; } } LIST_SANITY_CHECK; return(matchElement); }
// Return the list position of the designated object. ssize_t UtlSList::index(const UtlContainable* containableToMatch) const { ssize_t matchedIndex = UTL_NOT_FOUND; ssize_t currentIndex; UtlLink* listNode; UtlContainable* visitNode = NULL; OsLock take(mContainerLock); LIST_SANITY_CHECK; for(listNode = head(), currentIndex = 0; matchedIndex == UTL_NOT_FOUND && listNode; listNode = listNode->next() ) { visitNode = (UtlContainable*) listNode->data; if(visitNode && visitNode->compareTo(containableToMatch) == 0) { matchedIndex = currentIndex; } else { currentIndex++; } } LIST_SANITY_CHECK; return matchedIndex; }
void ProvisioningAttrList::deleteAttrElements(UtlContainable* pAttrElements) { UtlString* pMemberName; UtlContainable* pMemberValue; if (UtlString(pAttrElements->getContainableType()) == "UtlHashMap") { UtlHashMapIterator structureIterator(*dynamic_cast<UtlHashMap*>(pAttrElements)); while ((pMemberName = dynamic_cast<UtlString*>(structureIterator())) != NULL) { pMemberValue = dynamic_cast<UtlHashMap*>(pAttrElements)->findValue(pMemberName); if (UtlString(pMemberValue->getContainableType()) == "UtlHashMap" || UtlString(pMemberValue->getContainableType()) == "UtlSList") { deleteAttrElements(pMemberValue); } delete pMemberName; delete pMemberValue; } } else if (UtlString(pAttrElements->getContainableType()) == "UtlSList") { UtlSListIterator arrayIterator(*dynamic_cast<UtlSList*>(pAttrElements)); while ((pMemberValue = arrayIterator()) != NULL) { if (UtlString(pMemberValue->getContainableType()) == "UtlHashMap" || UtlString(pMemberValue->getContainableType()) == "UtlSList") { deleteAttrElements(pMemberValue); } delete pMemberValue; } } }
// Return the first UtlLink node to find. UtlLink* UtlSortedList::findNode(UtlLink* start, MatchType match, const UtlContainable* obj) const { UtlLink* listNode; UtlLink* foundNode; UtlContainable* listElement; int comparison = 0; // the caller already holds the mContainerLock for (listNode = start, foundNode = NULL; !foundNode && listNode; listNode = listNode->next() ) { listElement = (UtlContainable*)listNode->data; if (listElement) { // we can't use the hash as a shortcut here because we need the order too comparison = listElement->compareTo(obj); if ( comparison >= 0 ) { foundNode = listNode; } } } if (foundNode && match == EXACTLY && comparison != 0) // match not exact { foundNode = NULL; } return foundNode; }
// Remove the designated object by equality. UtlContainable* UtlSList::remove(const UtlContainable* object) { UtlLink* listNode; UtlLink* found; UtlContainable* foundObject = NULL; OsLock take(mContainerLock); LIST_SANITY_CHECK; for (listNode = head(), found = NULL; listNode && !found; listNode = listNode->next()) { UtlContainable* visitNode = (UtlContainable*) listNode->data; if(visitNode && visitNode->compareTo(object) == 0) { found = listNode; } } if (found) { foundObject = (UtlContainable*)found->data; removeLink(found); } LIST_SANITY_CHECK; return foundObject; }
void ProvisioningAttrList::validateAttribute(const char* pKey, eAttributeType type, bool ignoreMissing) { UtlContainable* attribute; UtlString utlKey(pKey); attribute = dynamic_cast<const UtlHashMap*>(mpData)->findValue(&utlKey); if (attribute == NULL) { if (ignoreMissing) { // If it is missing, just return return; } else { UtlString errorText("Missing attribute: '"); errorText += pKey; errorText += "'"; throw errorText; } } switch (type) { case ProvisioningAttrList::INT: if (UtlString(attribute->getContainableType()) != "UtlInt") { UtlString errorText("Attribute '"); errorText += pKey; errorText += "' must be of type: INT"; throw errorText; } break; case ProvisioningAttrList::BOOL: if (UtlString(attribute->getContainableType()) != "UtlBool") { UtlString errorText("Attribute: '"); errorText += pKey; errorText += "' must be of type: BOOL"; throw errorText; } break; case ProvisioningAttrList::STRING: if (UtlString(attribute->getContainableType()) != "UtlString") { UtlString errorText("Attribute: '"); errorText += pKey; errorText += "' must be of type: STRING"; throw errorText; } break; } }
// Dump the contents of a list of RegistrationBinding's. void dumpList(const UtlSList& list) { fprintf(stderr, "=== start\n"); UtlSListIterator list_iter(list); RegistrationBinding* item; int item_no = 0; while ((item = dynamic_cast <RegistrationBinding*> (list_iter()))) { fprintf(stderr, "--- item %d\n", item_no); UtlHashMap contents; item->copy(contents); UtlHashMapIterator iter(contents); UtlString* name; while ((name = dynamic_cast <UtlString*> (iter()))) { UtlContainable* value = iter.value(); UtlContainableType type = value->getContainableType(); if (type == UtlString::TYPE) { fprintf(stderr, "%s = '%s'\n", name->data(), (dynamic_cast <UtlString*> (iter.value()))->data()); } else if (type == UtlLongLongInt::TYPE) { Int64 value = (dynamic_cast <UtlLongLongInt*> (iter.value()))->getValue(); fprintf(stderr, "%s = 0x%" FORMAT_INTLL "x = %" FORMAT_INTLL "d\n", name->data(), value, value); } else if (type == UtlInt::TYPE) { fprintf(stderr, "%s = %" PRIdPTR "\n", name->data(), (dynamic_cast <UtlInt*> (iter.value()))->getValue()); } else { fprintf(stderr, "%s has unknown type %s\n", name->data(), type); } } item_no++; } fprintf(stderr, "=== end\n"); }
bool ProvisioningAttrList::getAttribute(const char* pKey, bool& rValue) { UtlString utlKey(pKey); UtlContainable* results; results = dynamic_cast<const UtlHashMap*>(mpData)->findValue(&utlKey); if (results == NULL) { return false; } if (UtlString(results->getContainableType()) != "UtlBool") { return false; } rValue = dynamic_cast<UtlBool*>(results)->getValue(); return true; }
bool ProvisioningAgentXmlRpcAction::execute(const HttpRequestContext& rContext, UtlSList& rParameters, void* pProvisioningAgentInstance, XmlRpcResponse& rResponse, XmlRpcMethod::ExecutionStatus& rStatus) { rStatus = XmlRpcMethod::OK; // Extract the request argument structure from the head of the SList. UtlContainable *pRequestArgs = rParameters.at(0); // Verify that a parameter list was given if (pRequestArgs != NULL) { // Verify that the parameter list is a structure ("UtlHashMap"). if (UtlString(pRequestArgs->getContainableType()) == "UtlHashMap") { // Now call the Provisioning Agent. ProvisioningAttrList requestAttributes(dynamic_cast<UtlHashMap*>(pRequestArgs)); ProvisioningAttrList* pResponseAttributes; pResponseAttributes = ((ProvisioningAgent*)pProvisioningAgentInstance)->Action(requestAttributes); if (pResponseAttributes == NULL) { // Method failure. Report error back to client rResponse.setFault(METHOD_DISPATCH_FAULT_CODE, METHOD_DISPATCH_FAULT_STRING); } else { // Encode the response rResponse.setResponse(dynamic_cast<UtlContainable*>(pResponseAttributes->getData())); // and clean up the responsettributes list. delete pResponseAttributes; } } else { // Missing parameter list. Report error back to client rResponse.setFault(EXPECTED_STRUCT_FAULT_CODE, EXPECTED_STRUCT_FAULT_STRING); } } else { // Bad parameter list. Report error back to client rResponse.setFault(EXPECTED_STRUCT_FAULT_CODE, EXPECTED_STRUCT_FAULT_STRING); } return true; }
// Return the number of occurrences of the designated object. size_t UtlSList::occurrencesOf(const UtlContainable* containableToMatch) const { int count = 0; UtlLink* listNode; UtlContainable* visitNode = NULL; OsLock take(mContainerLock); LIST_SANITY_CHECK; for(listNode = head(); listNode; listNode = listNode->next()) { visitNode = (UtlContainable*)listNode->data; if(visitNode && visitNode->compareTo(containableToMatch) == 0) { count++; } } LIST_SANITY_CHECK; return(count); }
// Return the number of occurrences of the designated object. size_t UtlSortedList::occurrencesOf(const UtlContainable* containableToMatch) const { int count = 0; UtlLink* listNode; UtlContainable* visitNode = NULL; int comparison; OsLock take(const_cast<OsBSem&>(mContainerLock)); for (listNode = head(), comparison = 0; comparison <= 0 && listNode; listNode = listNode->next() ) { visitNode = (UtlContainable*)listNode->data; if(visitNode && visitNode->compareTo(containableToMatch) == 0) { count++; } } return(count); }
bool AddExtension::execute(const HttpRequestContext& requestContext, UtlSList& params, void* userData, XmlRpcResponse& response, XmlRpcMethod::ExecutionStatus& status) { bool result = false; int totalParams = params.entries(); if (totalParams > 2) { response.setFault(TOO_MANY_PARAMS_FAULT_CODE, TOO_MANY_PARAMS_FAULT_STRING); result = false; } else { UtlString groupName; UtlString extension; for (int index = 0; index < totalParams; index++) { UtlContainable *value = params.at(index); if (index == 0 || index == 1) { UtlString paramType(value->getContainableType()); if (paramType.compareTo("UtlString") == 0) { if (index == 0) { groupName = *((UtlString *)value); } else { extension = *((UtlString *)value); } result = true; } else { response.setFault(ILLEGAL_PARAM_FAULT_CODE, ILLEGAL_PARAM_FAULT_STRING); result = false; } } } if (result) { SipDialogMonitor* dialogMonitor = (SipDialogMonitor *) userData; Url extensionUrl(extension); dialogMonitor->addExtension(groupName, extensionUrl); status = XmlRpcMethod::OK; // Construct the response UtlString responseText("method call \"addExtension\" successful"); response.setResponse(&responseText); } } return true; }
OsStatus SipRedirectorPresenceRouting::pingOpenfire( void ) { OsStatus rc = OS_FAILED; UtlString presenceMonitorUrlAsString = mLocalPresenceMonitorServerUrl.toString(); XmlRpcRequest pingRequest( mOpenFirePresenceServerUrl, PING_METHOD ); pingRequest.addParam( &mLogName ); XmlRpcResponse pingResponse; if( pingRequest.execute( pingResponse ) == true ) { UtlContainable* pValue = NULL; if ( !pingResponse.getResponse( pValue ) || !pValue ) { OsSysLog::add(FAC_NAT, PRI_CRIT, "SipRedirectorPresenceRouting::pingOpenfire response had no result."); } else { UtlString keyName; UtlHashMap* pMap = dynamic_cast<UtlHashMap*>( pValue ); if ( !pMap ) { OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::pingOpenfire response result had unexpected type: %s", pValue->getContainableType() ); } else { // extract status code and check it. keyName = STATUS_CODE; UtlString* pStatusCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); if( pStatusCode->compareTo( STATUS_CODE_VALUE_OK, UtlString::ignoreCase ) == 0 ) { keyName = INSTANCE_HANDLE; UtlString* pInstanceHandle = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); if( pInstanceHandle ) { if( mOpenfireInstanceHandle.compareTo( NIL_INSTANCE_HANDLE_VALUE ) == 0 ) { // This is the first instance handle we get from openfire, save it mOpenfireInstanceHandle = *pInstanceHandle; rc = OS_SUCCESS; } else { // check if the openfire handle we received matches the one we have on record if( mOpenfireInstanceHandle.compareTo( *pInstanceHandle ) == 0 ) { // there is a match; everything is fine. rc = OS_SUCCESS; } else { // mistmatch - likely caused by openfire resetting behind our back. // fail the ping to cause a re-register with openfire mOpenfireInstanceHandle = *pInstanceHandle; rc = OS_FAILED; // rc already set to OS_FAILED; added for readability } } } } } } } return rc; }
OsStatus SipRedirectorPresenceRouting::registerPresenceMonitorServerWithOpenfire( void ) { OsStatus rc = OS_FAILED; UtlString presenceMonitorUrlAsString = mLocalPresenceMonitorServerUrl.toString(); XmlRpcRequest registerPresenceMonitorRequest( mOpenFirePresenceServerUrl, REGISTER_PRESENCE_MONITOR_METHOD ); UtlString protocol = XML_RPC_PROTOCOL; registerPresenceMonitorRequest.addParam( &protocol ); registerPresenceMonitorRequest.addParam( &presenceMonitorUrlAsString ); XmlRpcResponse registerPresenceMonitorResponse; if( registerPresenceMonitorRequest.execute( registerPresenceMonitorResponse ) == true ) { UtlContainable* pValue = NULL; if ( !registerPresenceMonitorResponse.getResponse( pValue ) || !pValue ) { OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire response had no result."); } else { UtlString keyName; UtlHashMap* pMap = dynamic_cast<UtlHashMap*>( pValue ); if ( !pMap ) { OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire response result had unexpected type: %s", pValue->getContainableType() ); } else { // extract status code and check it. keyName = STATUS_CODE; UtlString* pStatusCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); if( pStatusCode->compareTo( STATUS_CODE_VALUE_OK, UtlString::ignoreCase ) != 0 ) { // status-code is not "OK", some error happened - extract error information. keyName = ERROR_CODE; UtlString* pErrorCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); keyName = ERROR_INFO; UtlString* pErrorInfo = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); if( pErrorCode && pErrorInfo ) { OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire request failed: %s:'%s'", pErrorCode->data(), pErrorInfo->data() ); } } else { keyName = INSTANCE_HANDLE; UtlString* pInstanceHandle = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) ); if( pInstanceHandle ) { // set openfire instance value mOpenfireInstanceHandle = *pInstanceHandle; } rc = OS_SUCCESS; } } } } else { // Check if the request failed because of a failed connection. // That error can sometimes happen when the server closed the TCP // connection we were using to communicate to it and can usually // be recovered by sending the request again. Try to send the // request once more to see if it will fly this time. int faultCode; UtlString faultString; registerPresenceMonitorResponse.getFault( &faultCode, faultString ); OsSysLog::add( FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire failed to execute() request: %d : %s", faultCode, faultString.data() ); } return rc; }
// Constructor SipPersistentSubscriptionMgr::SipPersistentSubscriptionMgr( const UtlString& component, const UtlString& domain, const UtlString& fileName) : mComponent(component), mDomain(domain), mSubscriptionDBInstance(SubscriptionDB::getInstance(fileName)), mPersistenceTimer(mPersistTask.getMessageQueue(), 0), mPersistTask(mSubscriptionDBInstance) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPersistentSubscriptionMgr:: " "mComponent = '%s', mDomain = '%s', fileName = '%s'", mComponent.data(), mDomain.data(), fileName.data()); // Start the persist task. mPersistTask.start(); // Read the subscription table and initialize the SipSubscriptionMgr. unsigned long now = OsDateTime::getSecsSinceEpoch(); ResultSet rs; mSubscriptionDBInstance->getAllRows(rs); UtlSListIterator itor(rs); UtlHashMap* rowp; while ((rowp = dynamic_cast <UtlHashMap*> (itor()))) { if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG)) { UtlString out; UtlHashMapIterator itor(*rowp); UtlString* key; UtlContainable* value; while ((key = dynamic_cast <UtlString*> (itor()))) { value = itor.value(); if (!out.isNull()) { out.append(", "); } out.append(*key); out.append(" = "); if (value->getContainableType() == UtlString::TYPE) { out.append("'"); out.append(*(dynamic_cast <UtlString*> (value))); out.append("'"); } else if (value->getContainableType() == UtlInt::TYPE) { out.appendNumber((int) (*(dynamic_cast <UtlInt*> (value)))); } else { out.append(value->getContainableType()); } } OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPersistentSubscriptionMgr:: " "table row: %s", out.data()); } // First, filter for rows that have the right component and have // not yet expired. UtlString* componentp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gComponentKey)); assert(componentp); int expires = *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gExpiresKey))); if (componentp->compareTo(mComponent) == 0 && expires - now >= 0) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPersistentSubscriptionMgr:: " "loading row"); // Extract the values from the row. const UtlString* top = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gToKey)); const UtlString* fromp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gFromKey)); const UtlString* callidp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gCallidKey)); const UtlString* eventtypep = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gEventtypeKey)); const UtlString* eventidp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gIdKey)); // Correct the null string if it is returned as // SPECIAL_IMDB_NULL_VALUE. if (eventidp->compareTo(special_imdb_null_value) == 0) { eventidp = &null_string; } int subcseq = *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gSubscribecseqKey))); const UtlString* urip = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gUriKey)); const UtlString* contactp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gContactKey)); const UtlString* routep = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gRecordrouteKey)); // Correct the null string if it is returned as // SPECIAL_IMDB_NULL_VALUE. if (routep->compareTo(special_imdb_null_value) == 0) { routep = &null_string; } int notifycseq = *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gNotifycseqKey))); const UtlString* acceptp = dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gAcceptKey)); int version = *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gVersionKey))); // Use SipSubscriptionMgr to update the in-memory data. // Construct a fake SUBSCRIBE request to carry most of the data // that updateDialogInfo needs. SipMessage subscribeRequest; subscribeRequest.setSubscribeData(urip->data(), fromp->data(), top->data(), callidp->data(), subcseq, eventtypep->data(), acceptp->data(), eventidp->data(), contactp->data(), routep->data(), expires - now); // Variables to hold the output of insertDialogInfo. UtlString subscribeDialogHandle; UtlBoolean isNew, isSubscriptionExpired; SipMessage subscribeResponse; UtlBoolean ret = SipSubscriptionMgr::insertDialogInfo(subscribeRequest, // *urip is the request-URI of // of the SUBSCRIBE. *urip, *eventtypep, subscribeDialogHandle, isNew, isSubscriptionExpired, subscribeResponse); if (!ret) { OsSysLog::add(FAC_SIP, PRI_ERR, "SipPersistentSubscriptionMgr:: " "insertDialogInfo failed urip = '%s', subscribeDialogHandle = '%s'", urip->data(), subscribeDialogHandle.data()); } else { // Set the next NOTIFY CSeq value. // (The data in IMDB has already been set.) SipSubscriptionMgr::setNextNotifyCSeq(subscribeDialogHandle, notifycseq, version); } } } }
void ProvisioningAttrList::dumpAttributes(const UtlContainable* pAttribute) { static UtlString* pMemberName; UtlContainable* pMemberValue; if (UtlString(pAttribute->getContainableType()) == "UtlHashMap") { UtlHashMapIterator structureIterator(*dynamic_cast<const UtlHashMap*>(pAttribute)); while ((pMemberName = dynamic_cast<UtlString*>(structureIterator())) != NULL) { pMemberValue = dynamic_cast<const UtlHashMap*>(pAttribute)->findValue(pMemberName); if (UtlString(pMemberValue->getContainableType()) == "UtlHashMap" || UtlString(pMemberValue->getContainableType()) == "UtlSList") { dumpAttributes(pMemberValue); } if (UtlString(pMemberValue->getContainableType()) == "UtlBool") { osPrintf("{%s} = (BOOL) %s\n", pMemberName->data(), (dynamic_cast<UtlBool*>(pMemberValue)->getValue() ? "TRUE" : "FALSE")); } else if (UtlString(pMemberValue->getContainableType()) == "UtlInt") { osPrintf("{%s} = (INT) %d\n", pMemberName->data(), dynamic_cast<UtlInt*>(pMemberValue)->getValue()); } else if (UtlString(pMemberValue->getContainableType()) == "UtlString") { osPrintf("{%s} = (STRING) \"%s\"\n", pMemberName->data(), dynamic_cast<UtlString*>(pMemberValue)->data()); } } } else if (UtlString(pAttribute->getContainableType()) == "UtlSList") { UtlSListIterator arrayIterator(*dynamic_cast<const UtlSList*>(pAttribute)); int arrayIndex = 0; while ((pMemberValue = arrayIterator()) != NULL) { if (UtlString(pMemberValue->getContainableType()) == "UtlHashMap" || UtlString(pMemberValue->getContainableType()) == "UtlSList") { dumpAttributes(pMemberValue); } if (UtlString(pMemberValue->getContainableType()) == "UtlBool") { osPrintf("{%s}[%d] = (BOOL) %s\n", pMemberName->data(), arrayIndex++, (dynamic_cast<UtlBool*>(pMemberValue)->getValue() ? "TRUE" : "FALSE")); } else if (UtlString(pMemberValue->getContainableType()) == "UtlInt") { osPrintf("{%s}[%d] = (INT) %d\n", pMemberName->data(), arrayIndex++, dynamic_cast<UtlInt*>(pMemberValue)->getValue()); } else if (UtlString(pMemberValue->getContainableType()) == "UtlString") { osPrintf("{%s}[%d] = (STRING) \"%s\"\n", pMemberName->data(), arrayIndex++, dynamic_cast<UtlString*>(pMemberValue)->data()); } } } }