diff options
| author | Rider Linden <rider@lindenlab.com> | 2015-08-12 16:32:49 -0700 | 
|---|---|---|
| committer | Rider Linden <rider@lindenlab.com> | 2015-08-12 16:32:49 -0700 | 
| commit | 248d61fe0eadd128c7704e37922ba7fdef35d630 (patch) | |
| tree | 47597f9a1d4a1a3dc774c9f10f3d6d74338c5322 | |
| parent | 14a8c70867252926fdfc42728c1de38c8ef68706 (diff) | |
MAINT-5500: Finish converting the AIS responders to the new coroutine model, Cleaned up dead an unused code.
MAINT-4952: Added COPY and MOVE methods to Core:Http adapter
| -rwxr-xr-x | indra/llcorehttp/_httpoprequest.cpp | 18 | ||||
| -rwxr-xr-x | indra/llcorehttp/_httpoprequest.h | 9 | ||||
| -rwxr-xr-x | indra/llcorehttp/httprequest.cpp | 31 | ||||
| -rwxr-xr-x | indra/llcorehttp/httprequest.h | 27 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 94 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.h | 52 | ||||
| -rwxr-xr-x | indra/newview/llaisapi.cpp | 659 | ||||
| -rwxr-xr-x | indra/newview/llaisapi.h | 146 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 24 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 84 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 2 | 
11 files changed, 441 insertions, 705 deletions
| diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index e588ed8a9b..86110f5b46 100755 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -380,6 +380,19 @@ HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,  } +HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id, +    HttpRequest::priority_t priority, +    const std::string & url, +    const HttpOptions::ptr_t & options, +    const HttpHeaders::ptr_t &headers) +{ +    setupCommon(policy_id, priority, url, NULL, options, headers); +    mReqMethod = HOR_MOVE; + +    return HttpStatus(); +} + +  void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,  								HttpRequest::priority_t priority,  								const std::string & url, @@ -626,6 +639,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)          check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);          break; +    case HOR_MOVE: +        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE"); +        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST); +        break; +  	default:  		LL_ERRS(LOG_CORE) << "Invalid HTTP method in request:  "  						  << int(mReqMethod)  << ".  Can't recover." diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h index a9083be02b..1b449a5abc 100755 --- a/indra/llcorehttp/_httpoprequest.h +++ b/indra/llcorehttp/_httpoprequest.h @@ -83,7 +83,8 @@ public:  		HOR_PUT,          HOR_DELETE,          HOR_PATCH, -        HOR_COPY +        HOR_COPY, +        HOR_MOVE  	};  	virtual void stageFromRequest(HttpService *); @@ -148,6 +149,12 @@ public:                          const HttpOptions::ptr_t & options,                          const HttpHeaders::ptr_t & headers); +    HttpStatus setupMove(HttpRequest::policy_t policy_id, +                        HttpRequest::priority_t priority, +                        const std::string & url, +                        const HttpOptions::ptr_t & options, +                        const HttpHeaders::ptr_t & headers); +      // Internal method used to setup the libcurl options for a request.  	// Does all the libcurl handle setup in one place.  	// diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp index f0dfde6153..63233259fb 100755 --- a/indra/llcorehttp/httprequest.cpp +++ b/indra/llcorehttp/httprequest.cpp @@ -419,6 +419,37 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,      return handle;  } +HttpHandle HttpRequest::requestMove(policy_t policy_id, +    priority_t priority, +    const std::string & url, +    const HttpOptions::ptr_t & options, +    const HttpHeaders::ptr_t & headers, +    HttpHandler * user_handler) +{ +    HttpStatus status; +    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + +    HttpOpRequest * op = new HttpOpRequest(); +    if (!(status = op->setupMove(policy_id, priority, url, options, headers))) +    { +        op->release(); +        mLastReqStatus = status; +        return handle; +    } +    op->setReplyPath(mReplyQueue, user_handler); +    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount +    { +        op->release(); +        mLastReqStatus = status; +        return handle; +    } + +    mLastReqStatus = status; +    handle = static_cast<HttpHandle>(op); + +    return handle; +} +  HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)  { diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h index 20a223c482..6c2449266f 100755 --- a/indra/llcorehttp/httprequest.h +++ b/indra/llcorehttp/httprequest.h @@ -478,7 +478,7 @@ public:  						  HttpHandler * handler); -    /// Queue a full HTTP PUT.  Query arguments and body may +    /// Queue a full HTTP DELETE.  Query arguments and body may      /// be provided.  Caller is responsible for escaping and      /// encoding and communicating the content types.      /// @@ -497,7 +497,7 @@ public:              const HttpHeaders::ptr_t & headers,              HttpHandler * user_handler); -    /// Queue a full HTTP PUT.  Query arguments and body may +    /// Queue a full HTTP PATCH.  Query arguments and body may      /// be provided.  Caller is responsible for escaping and      /// encoding and communicating the content types.      /// @@ -520,7 +520,7 @@ public:              const HttpHeaders::ptr_t & headers,              HttpHandler * user_handler); -    /// Queue a full HTTP PUT.  Query arguments and body may +    /// Queue a full HTTP COPY.  Query arguments and body may      /// be provided.  Caller is responsible for escaping and      /// encoding and communicating the content types.      /// @@ -538,7 +538,26 @@ public:              const HttpOptions::ptr_t & options,              const HttpHeaders::ptr_t & headers,              HttpHandler * user_handler); -        + +    /// Queue a full HTTP MOVE.  Query arguments and body may +    /// be provided.  Caller is responsible for escaping and +    /// encoding and communicating the content types. +    /// +    /// @param	policy_id		@see requestGet() +    /// @param	priority		" +    /// @param	url				" +    /// @param	options			@see requestGet()K(optional) +    /// @param	headers			" +    /// @param	handler			" +    /// @return					" +    /// +    HttpHandle requestMove(policy_t policy_id, +            priority_t priority, +            const std::string & url, +            const HttpOptions::ptr_t & options, +            const HttpHeaders::ptr_t & headers, +            HttpHandler * user_handler); +      /// Queue a NoOp request.  	/// The request is queued and serviced by the working thread which  	/// immediately processes it and returns the request to the reply diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 50c866f370..d342888255 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -700,7 +700,6 @@ LLSD HttpCoroutineAdapter::postAndYield_(LLCore::HttpRequest::ptr_t &request,      LLSD results = llcoro::waitForEventOn(handler->getReplyPump());      cleanState(); -    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;      return results;  } @@ -737,7 +736,7 @@ LLSD HttpCoroutineAdapter::putAndYield_(LLCore::HttpRequest::ptr_t &request,      saveState(hhandle, request, handler);      LLSD results = llcoro::waitForEventOn(handler->getReplyPump());      cleanState(); -    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; +      return results;  } @@ -792,7 +791,7 @@ LLSD HttpCoroutineAdapter::getAndYield_(LLCore::HttpRequest::ptr_t &request,      saveState(hhandle, request, handler);      LLSD results = llcoro::waitForEventOn(handler->getReplyPump());      cleanState(); -    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; +      return results;  } @@ -827,7 +826,7 @@ LLSD HttpCoroutineAdapter::deleteAndYield_(LLCore::HttpRequest::ptr_t &request,      saveState(hhandle, request, handler);      LLSD results = llcoro::waitForEventOn(handler->getReplyPump());      cleanState(); -    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; +      return results;  } @@ -865,10 +864,95 @@ LLSD HttpCoroutineAdapter::patchAndYield_(LLCore::HttpRequest::ptr_t &request,      saveState(hhandle, request, handler);      LLSD results = llcoro::waitForEventOn(handler->getReplyPump());      cleanState(); -    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; + +    return results; +} + +LLSD HttpCoroutineAdapter::copyAndYield(LLCore::HttpRequest::ptr_t request, +    const std::string & url, const std::string dest, +    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ +    LLEventStream  replyPump(mAdapterName + "Reply", true); +    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump)); + +    if (!headers) +        headers.reset(new LLCore::HttpHeaders); +    headers->append(HTTP_OUT_HEADER_DESTINATION, dest); + +    return copyAndYield_(request, url, options, headers, httpHandler); +} + + +LLSD HttpCoroutineAdapter::copyAndYield_(LLCore::HttpRequest::ptr_t &request, +    const std::string & url,  +    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, +    HttpCoroHandler::ptr_t &handler) +{ +    HttpRequestPumper pumper(request); + +    checkDefaultHeaders(headers); + +    // The HTTPCoroHandler does not self delete, so retrieval of a the contained  +    // pointer from the smart pointer is safe in this case. +    //  +    LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url, +        options, headers, handler.get()); + +    if (hhandle == LLCORE_HTTP_HANDLE_INVALID) +    { +        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url); +    } + +    saveState(hhandle, request, handler); +    LLSD results = llcoro::waitForEventOn(handler->getReplyPump()); +    cleanState(); + +    return results; +} + +LLSD HttpCoroutineAdapter::moveAndYield(LLCore::HttpRequest::ptr_t request, +    const std::string & url, const std::string dest, +    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ +    LLEventStream  replyPump(mAdapterName + "Reply", true); +    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump)); + +    if (!headers) +        headers.reset(new LLCore::HttpHeaders); +    headers->append(HTTP_OUT_HEADER_DESTINATION, dest); + +    return moveAndYield_(request, url, options, headers, httpHandler); +} + + +LLSD HttpCoroutineAdapter::moveAndYield_(LLCore::HttpRequest::ptr_t &request, +    const std::string & url, +    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, +    HttpCoroHandler::ptr_t &handler) +{ +    HttpRequestPumper pumper(request); + +    checkDefaultHeaders(headers); + +    // The HTTPCoroHandler does not self delete, so retrieval of a the contained  +    // pointer from the smart pointer is safe in this case. +    //  +    LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url, +        options, headers, handler.get()); + +    if (hhandle == LLCORE_HTTP_HANDLE_INVALID) +    { +        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url); +    } + +    saveState(hhandle, request, handler); +    LLSD results = llcoro::waitForEventOn(handler->getReplyPump()); +    cleanState(); +      return results;  } +  void HttpCoroutineAdapter::checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers)  {      if (!headers) diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 8fe2354d6b..31a73bb900 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -457,7 +457,7 @@ public:          LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders())); -    /// Execute a Post transaction on the supplied URL and yield execution of  +    /// Execute a PATCH transaction on the supplied URL and yield execution of       /// the coroutine until a result is available.       ///       /// @Note: the request's smart pointer is passed by value so that it will @@ -474,6 +474,46 @@ public:              LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);      } +    /// Execute a COPY transaction on the supplied URL and yield execution of  +    /// the coroutine until a result is available.  +    ///  +    /// @Note: The destination is passed through the HTTP pipe as a header +    /// The header used is defined as: HTTP_OUT_HEADER_DESTINATION("Destination"); +    ///  +    /// @Note: the request's smart pointer is passed by value so that it will +    /// not be deallocated during the yield. +    LLSD copyAndYield(LLCore::HttpRequest::ptr_t request, +        const std::string & url, const std::string dest, +        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), +        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders())); +    LLSD copyAndYield(LLCore::HttpRequest::ptr_t &request, +        const std::string & url, const std::string & dest, +        LLCore::HttpHeaders::ptr_t &headers) +    { +        return copyAndYield(request, url, dest, +            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); +    } + +    /// Execute a MOVE transaction on the supplied URL and yield execution of  +    /// the coroutine until a result is available.  +    ///  +    /// @Note: The destination is passed through the HTTP pipe in the headers. +    /// The header used is defined as: HTTP_OUT_HEADER_DESTINATION("Destination"); +    ///  +    /// @Note: the request's smart pointer is passed by value so that it will +    /// not be deallocated during the yield. +    LLSD moveAndYield(LLCore::HttpRequest::ptr_t request, +        const std::string & url, const std::string dest, +        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), +        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders())); +    LLSD moveAndYield(LLCore::HttpRequest::ptr_t &request, +        const std::string & url, const std::string & dest, +        LLCore::HttpHeaders::ptr_t &headers) +    { +        return moveAndYield(request, url, dest, +            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); +    } +      ///      void cancelYieldingOperation(); @@ -541,6 +581,16 @@ private:          LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,          HttpCoroHandler::ptr_t &handler); +    LLSD copyAndYield_(LLCore::HttpRequest::ptr_t &request, +        const std::string & url,  +        LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, +        HttpCoroHandler::ptr_t &handler); + +    LLSD moveAndYield_(LLCore::HttpRequest::ptr_t &request, +        const std::string & url, +        LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, +        HttpCoroHandler::ptr_t &handler); +      static void trivialGetCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure);      static void trivialPostCoro(std::string url, LLCore::HttpRequest::policy_t policyId, LLSD postData, completionCallback_t success, completionCallback_t failure); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 3565c04609..23ea692a16 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -37,11 +37,54 @@  #include "llviewercontrol.h"  ///---------------------------------------------------------------------------- -#if 1 +/// Classes for AISv3 support. +///---------------------------------------------------------------------------- + +//========================================================================= +const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3"); +const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3"); + +//------------------------------------------------------------------------- +/*static*/ +bool AISAPI::isAvailable() +{ +    if (gAgent.getRegion()) +    { +        return gAgent.getRegion()->isCapabilityAvailable(INVENTORY_CAP_NAME); +    } +    return false; +} + +/*static*/ +void AISAPI::getCapNames(LLSD& capNames) +{ +    capNames.append(INVENTORY_CAP_NAME); +    capNames.append(LIBRARY_CAP_NAME); +} + +/*static*/ +std::string AISAPI::getInvCap() +{ +    if (gAgent.getRegion()) +    { +        return gAgent.getRegion()->getCapability(INVENTORY_CAP_NAME); +    } +    return std::string(); +} + +/*static*/ +std::string AISAPI::getLibCap() +{ +    if (gAgent.getRegion()) +    { +        return gAgent.getRegion()->getCapability(LIBRARY_CAP_NAME); +    } +    return std::string(); +} +  /*static*/  -void AISAPI::CreateInventoryCommand(const LLUUID& parentId, const LLSD& newInventory, completion_t callback) +void AISAPI::CreateInventory(const LLUUID& parentId, const LLSD& newInventory, completion_t callback)  { -#if 1      std::string cap = getInvCap();      if (cap.empty())      { @@ -68,23 +111,22 @@ void AISAPI::CreateInventoryCommand(const LLUUID& parentId, const LLSD& newInven          // Humans ignore next line.  It is just a cast.          static_cast<LLSD (LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::postAndYield), _1, _2, _3, _4, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, postFn, url, parentId, newInventory, callback)); -#else -    LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::CreateInventoryCommandCoro,  -        _1, parentId, newInventory, callback)); - -#endif +        _1, postFn, url, parentId, newInventory, callback, COPYINVENTORY));      EnqueueAISCommand("CreateInventory", proc); -  }  /*static*/  -void AISAPI::SlamFolderCommand(const LLUUID& folderId, const LLSD& newInventory, completion_t callback) +void AISAPI::SlamFolder(const LLUUID& folderId, const LLSD& newInventory, completion_t callback)  { -#if 1      std::string cap = getInvCap();      if (cap.empty())      { @@ -99,23 +141,24 @@ void AISAPI::SlamFolderCommand(const LLUUID& folderId, const LLSD& newInventory,      // see comment above in CreateInventoryCommand      invokationFn_t putFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::putAndYield), _1, _2, _3, _4, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, putFn, url, folderId, newInventory, callback)); - -#else -    LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::SlamFolderCommandCoro, -        _1, folderId, newInventory, callback)); -#endif +        _1, putFn, url, folderId, newInventory, callback, SLAMFOLDER));      EnqueueAISCommand("SlamFolder", proc);  } -void AISAPI::RemoveCategoryCommand(const LLUUID &categoryId, completion_t callback) +void AISAPI::RemoveCategory(const LLUUID &categoryId, completion_t callback)  {      std::string cap; @@ -130,21 +173,26 @@ void AISAPI::RemoveCategoryCommand(const LLUUID &categoryId, completion_t callba      LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;      invokationFn_t delFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, delFn, url, categoryId, LLSD(), callback)); +        _1, delFn, url, categoryId, LLSD(), callback, REMOVECATEGORY));      EnqueueAISCommand("RemoveCategory", proc);  }  /*static*/  -void AISAPI::RemoveItemCommand(const LLUUID &itemId, completion_t callback) +void AISAPI::RemoveItem(const LLUUID &itemId, completion_t callback)  { -#if 1      std::string cap;      cap = getInvCap(); @@ -158,25 +206,64 @@ void AISAPI::RemoveItemCommand(const LLUUID &itemId, completion_t callback)      LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;      invokationFn_t delFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, delFn, url, itemId, LLSD(), callback)); - -#else -    LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::RemoveItemCommandCoro, -        _1, itemId, callback)); -#endif +        _1, delFn, url, itemId, LLSD(), callback, REMOVEITEM));      EnqueueAISCommand("RemoveItem", proc);  } +void AISAPI::CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, completion_t callback) +{ +    std::string cap; + +    cap = getLibCap(); +    if (cap.empty()) +    { +        LL_WARNS("Inventory") << "Library cap not found!" << LL_ENDL; +        return; +    } + +    LL_DEBUGS("Inventory") << "Copying library category: " << sourceId << " => " << destId << LL_ENDL; + +    LLUUID tid; +    tid.generate(); + +    std::string url = cap + std::string("/category/") + sourceId.asString() + "?tid=" + tid.asString(); +    LL_INFOS() << url << LL_ENDL; + +    std::string destination = destId.asString(); + +    invokationFn_t copyFn = boost::bind( +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. +        static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const std::string, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> +        //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders +        (&LLCoreHttpUtil::HttpCoroutineAdapter::copyAndYield), _1, _2, _3, destination, _5, _6); +          +    LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, +        _1, copyFn, url, destId, LLSD(), callback, COPYLIBRARYCATEGORY)); + +    EnqueueAISCommand("CopyLibraryCategory", proc); +}  /*static*/  -void AISAPI::PurgeDescendentsCommand(const LLUUID &categoryId, completion_t callback) +void AISAPI::PurgeDescendents(const LLUUID &categoryId, completion_t callback)  {      std::string cap; @@ -191,20 +278,26 @@ void AISAPI::PurgeDescendentsCommand(const LLUUID &categoryId, completion_t call      LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;      invokationFn_t delFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, delFn, url, categoryId, LLSD(), callback)); +        _1, delFn, url, categoryId, LLSD(), callback, PURGEDESCENDENTS));      EnqueueAISCommand("PurgeDescendents", proc);  }  /*static*/ -void AISAPI::UpdateCategoryCommand(const LLUUID &categoryId, const LLSD &updates, completion_t callback) +void AISAPI::UpdateCategory(const LLUUID &categoryId, const LLSD &updates, completion_t callback)  {      std::string cap; @@ -217,19 +310,25 @@ void AISAPI::UpdateCategoryCommand(const LLUUID &categoryId, const LLSD &updates      std::string url = cap + std::string("/category/") + categoryId.asString();      invokationFn_t patchFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::patchAndYield), _1, _2, _3, _4, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, patchFn, url, categoryId, updates, callback)); +        _1, patchFn, url, categoryId, updates, callback, UPDATECATEGORY));      EnqueueAISCommand("UpdateCategory", proc);  }  /*static*/ -void AISAPI::UpdateItemCommand(const LLUUID &itemId, const LLSD &updates, completion_t callback) +void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t callback)  {      std::string cap; @@ -243,13 +342,19 @@ void AISAPI::UpdateItemCommand(const LLUUID &itemId, const LLSD &updates, comple      std::string url = cap + std::string("/item/") + itemId.asString();      invokationFn_t patchFn = boost::bind( -        // Humans ignore next line.  It is just a cast. +        // Humans ignore next line.  It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload.          static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>          //---- +        // _1 -> httpAdapter +        // _2 -> httpRequest +        // _3 -> url +        // _4 -> body  +        // _5 -> httpOptions +        // _6 -> httpHeaders          (&LLCoreHttpUtil::HttpCoroutineAdapter::patchAndYield), _1, _2, _3, _4, _5, _6);      LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, -        _1, patchFn, url, itemId, updates, callback)); +        _1, patchFn, url, itemId, updates, callback, UPDATEITEM));      EnqueueAISCommand("UpdateItem", proc);  } @@ -262,31 +367,10 @@ void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager  } -/*static*/  -std::string AISAPI::getInvCap() -{ -    if (gAgent.getRegion()) -    { -        return gAgent.getRegion()->getCapability("InventoryAPIv3"); -    } - -    return std::string(); -} - -/*static*/  -std::string AISAPI::getLibCap() -{ -    if (gAgent.getRegion()) -    { -        return gAgent.getRegion()->getCapability("LibraryAPIv3"); -    } -    return std::string(); -} -  /*static*/  void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter,           invokationFn_t invoke, std::string url,  -        LLUUID targetId, LLSD body, completion_t callback) +        LLUUID targetId, LLSD body, completion_t callback, COMMAND_TYPE type)  {      LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions);      LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); @@ -313,455 +397,20 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht      gInventory.onAISUpdateReceived("AISCommand", result);      if (callback) -    {   // UUID always null -        callback(LLUUID::null); -    } - -} - -#if 0 -/*static*/ -void AISAPI::CreateInventoryCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID parentId, LLSD newInventory, completion_t callback) -{ -    std::string cap; -    LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); -    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); - -    httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); - -    cap = getInvCap(); -    if (cap.empty()) -    { -        LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; -        return; -    } - -    LLUUID tid; -    tid.generate(); +    {    +        LLUUID id(LLUUID::null); -    std::string url = cap + std::string("/category/") + parentId.asString() + "?tid=" + tid.asString(); -    LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +        if (result.has("category_id") && (type == COPYLIBRARYCATEGORY)) +	    { +		    id = result["category_id"]; +	    } -    LLSD result = httpAdapter->postAndYield(httpRequest, url, newInventory, httpOptions); -    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; -    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - -    if (!status || !result.isMap()) -    { -        if (!result.isMap()) -        { -            status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); -        } -        LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; -        LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; +        callback(id);      } -    gInventory.onAISUpdateReceived("AISCommand", result); - -    if (callback) -    {   // UUID always null -        callback(LLUUID::null); -    } - -} - -/*static*/ -void AISAPI::SlamFolderCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID folderId, LLSD newInventory, completion_t callback) -{ -    std::string cap; -    LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); -    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); - -    httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); - -    cap = getInvCap(); -    if (cap.empty()) -    { -        LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; -        return; -    } - -    LLUUID tid; -    tid.generate(); - -    std::string url = cap + std::string("/category/") + folderId.asString() + "/links?tid=" + tid.asString(); - -    LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - -    LLSD result = httpAdapter->putAndYield(httpRequest, url, newInventory, httpOptions); -    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; -    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - -    if (!status || !result.isMap()) -    { -        if (!result.isMap()) -        { -            status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); -        } -        LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; -        LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; -    } - -    gInventory.onAISUpdateReceived("AISCommand", result); - -    if (callback) -    {   // UUID always null -        callback(LLUUID::null); -    } - -} - -void AISAPI::RemoveItemCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID itemId, completion_t callback) -{ -    std::string cap; -    LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); -    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); - -    httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); - -    cap = getInvCap(); -    if (cap.empty()) -    { -        LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; -        return; -    } - -    std::string url = cap + std::string("/item/") + itemId.asString(); -    LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - -    LLSD result = httpAdapter->deleteAndYield(httpRequest, url, httpOptions); -    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; -    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - -    if (!status || !result.isMap()) -    { -        if (!result.isMap()) -        { -            status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); -        } -        LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; -        LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; -    } - -    gInventory.onAISUpdateReceived("AISCommand", result); - -    if (callback) -    {   // UUID always null -        callback(LLUUID::null); -    } -} -#endif -#endif -///---------------------------------------------------------------------------- -/// Classes for AISv3 support. -///---------------------------------------------------------------------------- - -// AISCommand - base class for retry-able HTTP requests using the AISv3 cap. -AISCommand::AISCommand(LLPointer<LLInventoryCallback> callback): -	mCommandFunc(NULL), -	mCallback(callback) -{ -	mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10); -} - -bool AISCommand::run_command() -{ -	if (NULL == mCommandFunc) -	{ -		// This may happen if a command failed to initiate itself. -		LL_WARNS("Inventory") << "AIS command attempted with null command function" << LL_ENDL; -		return false; -	} -	else -	{ -		mCommandFunc(); -		return true; -	} -} - -void AISCommand::setCommandFunc(command_func_type command_func) -{ -	mCommandFunc = command_func; -} -	 -// virtual -bool AISCommand::getResponseUUID(const LLSD& content, LLUUID& id) -{ -	return false; -} -	 -/* virtual */ -void AISCommand::httpSuccess() -{ -	// Command func holds a reference to self, need to release it -	// after a success or final failure. -	setCommandFunc(no_op); -		 -	const LLSD& content = getContent(); -	if (!content.isMap()) -	{ -		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content); -		return; -	} -	mRetryPolicy->onSuccess(); -		 -	gInventory.onAISUpdateReceived("AISCommand", content); - -	if (mCallback) -	{ -		LLUUID id; // will default to null if parse fails. -		getResponseUUID(content,id); -		mCallback->fire(id); -	} -} - -/*virtual*/ -void AISCommand::httpFailure() -{ -	LL_WARNS("Inventory") << dumpResponse() << LL_ENDL; -	S32 status = getStatus(); -	const LLSD& headers = getResponseHeaders(); -	mRetryPolicy->onFailure(status, headers); -	F32 seconds_to_wait; -	if (mRetryPolicy->shouldRetry(seconds_to_wait)) -	{ -		doAfterInterval(boost::bind(&AISCommand::run_command,this),seconds_to_wait); -	} -	else -	{ -		// Command func holds a reference to self, need to release it -		// after a success or final failure. -		// *TODO: Notify user?  This seems bad. -		setCommandFunc(no_op); -	} -} - -//static -bool AISCommand::isAPIAvailable() -{ -	if (gAgent.getRegion()) -	{ -		return gAgent.getRegion()->isCapabilityAvailable("InventoryAPIv3"); -	} -	return false; -} - -//static -bool AISCommand::getInvCap(std::string& cap) -{ -	if (gAgent.getRegion()) -	{ -		cap = gAgent.getRegion()->getCapability("InventoryAPIv3"); -	} -	if (!cap.empty()) -	{ -		return true; -	} -	return false; -} - -//static -bool AISCommand::getLibCap(std::string& cap) -{ -	if (gAgent.getRegion()) -	{ -		cap = gAgent.getRegion()->getCapability("LibraryAPIv3"); -	} -	if (!cap.empty()) -	{ -		return true; -	} -	return false; -} - -//static -void AISCommand::getCapabilityNames(LLSD& capabilityNames) -{ -	capabilityNames.append("InventoryAPIv3"); -	capabilityNames.append("LibraryAPIv3"); -} - -// RemoveItemCommand::RemoveItemCommand(const LLUUID& item_id, -// 									 LLPointer<LLInventoryCallback> callback): -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	std::string url = cap + std::string("/item/") + item_id.asString(); -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LLHTTPClient::ResponderPtr responder = this; -// 	LLSD headers; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// RemoveCategoryCommand::RemoveCategoryCommand(const LLUUID& item_id, -// 											 LLPointer<LLInventoryCallback> callback): -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	std::string url = cap + std::string("/category/") + item_id.asString(); -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LLHTTPClient::ResponderPtr responder = this; -// 	LLSD headers; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// PurgeDescendentsCommand::PurgeDescendentsCommand(const LLUUID& item_id, -// 												 LLPointer<LLInventoryCallback> callback): -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	std::string url = cap + std::string("/category/") + item_id.asString() + "/children"; -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LLCurl::ResponderPtr responder = this; -// 	LLSD headers; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// UpdateItemCommand::UpdateItemCommand(const LLUUID& item_id, -// 									 const LLSD& updates, -// 									 LLPointer<LLInventoryCallback> callback): -// 	mUpdates(updates), -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	std::string url = cap + std::string("/item/") + item_id.asString(); -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LL_DEBUGS("Inventory") << "request: " << ll_pretty_print_sd(mUpdates) << LL_ENDL; -// 	LLCurl::ResponderPtr responder = this; -// 	LLSD headers; -// 	headers["Content-Type"] = "application/llsd+xml"; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& cat_id, -// 											 const LLSD& updates, -// 											 LLPointer<LLInventoryCallback> callback): -// 	mUpdates(updates), -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	std::string url = cap + std::string("/category/") + cat_id.asString(); -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LLCurl::ResponderPtr responder = this; -// 	LLSD headers; -// 	headers["Content-Type"] = "application/llsd+xml"; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// CreateInventoryCommand::CreateInventoryCommand(const LLUUID& parent_id, -// 							 				   const LLSD& new_inventory, -// 							 				   LLPointer<LLInventoryCallback> callback): -// 	mNewInventory(new_inventory), -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	LLUUID tid; -// 	tid.generate(); -// 	std::string url = cap + std::string("/category/") + parent_id.asString() + "?tid=" + tid.asString(); -// 	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; -// 	LLCurl::ResponderPtr responder = this; -// 	LLSD headers; -// 	headers["Content-Type"] = "application/llsd+xml"; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::post, url, mNewInventory, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -// SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback): -// 	mContents(contents), -// 	AISCommand(callback) -// { -// 	std::string cap; -// 	if (!getInvCap(cap)) -// 	{ -// 		LL_WARNS() << "No cap found" << LL_ENDL; -// 		return; -// 	} -// 	LLUUID tid; -// 	tid.generate(); -// 	std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString(); -// 	LL_INFOS() << url << LL_ENDL; -// 	LLCurl::ResponderPtr responder = this; -// 	LLSD headers; -// 	headers["Content-Type"] = "application/llsd+xml"; -// 	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -// 	command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers, timeout); -// 	setCommandFunc(cmd); -// } - -CopyLibraryCategoryCommand::CopyLibraryCategoryCommand(const LLUUID& source_id, -													   const LLUUID& dest_id, -													   LLPointer<LLInventoryCallback> callback): -	AISCommand(callback) -{ -	std::string cap; -	if (!getLibCap(cap)) -	{ -		LL_WARNS() << "No cap found" << LL_ENDL; -		return; -	} -	LL_DEBUGS("Inventory") << "Copying library category: " << source_id << " => " << dest_id << LL_ENDL; -	LLUUID tid; -	tid.generate(); -	std::string url = cap + std::string("/category/") + source_id.asString() + "?tid=" + tid.asString(); -	LL_INFOS() << url << LL_ENDL; -	LLCurl::ResponderPtr responder = this; -	LLSD headers; -	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; -	command_func_type cmd = boost::bind(&LLHTTPClient::copy, url, dest_id.asString(), responder, headers, timeout); -	setCommandFunc(cmd); -} - -bool CopyLibraryCategoryCommand::getResponseUUID(const LLSD& content, LLUUID& id) -{ -	if (content.has("category_id")) -	{ -		id = content["category_id"]; -		return true; -	} -	return false;  } +//-------------------------------------------------------------------------  AISUpdate::AISUpdate(const LLSD& update)  {  	parseUpdate(update); diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index ebb952a3ec..fc2bedc9ec 100755 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -38,21 +38,38 @@  #include "llcorehttputil.h"  #include "llcoproceduremanager.h" -#if 1  class AISAPI  {  public:      typedef boost::function<void(const LLUUID &invItem)>    completion_t; -    static void CreateInventoryCommand(const LLUUID& parentId, const LLSD& newInventory, completion_t callback); -    static void SlamFolderCommand(const LLUUID& folderId, const LLSD& newInventory, completion_t callback); -    static void RemoveCategoryCommand(const LLUUID &categoryId, completion_t callback); -    static void RemoveItemCommand(const LLUUID &itemId, completion_t callback); -    static void PurgeDescendentsCommand(const LLUUID &categoryId, completion_t callback); -    static void UpdateCategoryCommand(const LLUUID &categoryId, const LLSD &updates, completion_t callback); -    static void UpdateItemCommand(const LLUUID &itemId, const LLSD &updates, completion_t callback); +    static bool isAvailable(); +    static void getCapNames(LLSD& capNames); + +    static void CreateInventory(const LLUUID& parentId, const LLSD& newInventory, completion_t callback); +    static void SlamFolder(const LLUUID& folderId, const LLSD& newInventory, completion_t callback); +    static void RemoveCategory(const LLUUID &categoryId, completion_t callback); +    static void RemoveItem(const LLUUID &itemId, completion_t callback); +    static void PurgeDescendents(const LLUUID &categoryId, completion_t callback); +    static void UpdateCategory(const LLUUID &categoryId, const LLSD &updates, completion_t callback); +    static void UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t callback); +    static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, completion_t callback);  private: +    typedef enum { +        COPYINVENTORY, +        SLAMFOLDER, +        REMOVECATEGORY, +        REMOVEITEM, +        PURGEDESCENDENTS, +        UPDATECATEGORY, +        UPDATEITEM, +        COPYLIBRARYCATEGORY +    } COMMAND_TYPE; + +    static const std::string INVENTORY_CAP_NAME; +    static const std::string LIBRARY_CAP_NAME; +      typedef boost::function < LLSD (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t, LLCore::HttpRequest::ptr_t,          const std::string, LLSD, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) > invokationFn_t; @@ -61,118 +78,11 @@ private:      static std::string getInvCap();      static std::string getLibCap(); -    static void InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body, completion_t callback); +    static void InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter,  +        invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body,  +        completion_t callback, COMMAND_TYPE type); -#if 0 -    static void CreateInventoryCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLUUID parentId, LLSD newInventory, completion_t callback); -    static void SlamFolderCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID folderId, LLSD newInventory, completion_t callback); -    static void RemoveItemCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID itemId, completion_t callback); -#endif  }; -#endif  - -class AISCommand: public LLHTTPClient::Responder -{ -public: -	typedef boost::function<void()> command_func_type; - -	AISCommand(LLPointer<LLInventoryCallback> callback); - -	virtual ~AISCommand() {} - -	bool run_command(); - -	void setCommandFunc(command_func_type command_func); -	 -	// Need to do command-specific parsing to get an id here, for -	// LLInventoryCallback::fire().  May or may not need to bother, -	// since most LLInventoryCallbacks do their work in the -	// destructor. -	 -	/* virtual */ void httpSuccess(); -	/* virtual */ void httpFailure(); - -	static bool isAPIAvailable(); -	static bool getInvCap(std::string& cap); -	static bool getLibCap(std::string& cap); -	static void getCapabilityNames(LLSD& capabilityNames); - -protected: -	virtual bool getResponseUUID(const LLSD& content, LLUUID& id); - -private: -	command_func_type mCommandFunc; -	LLPointer<LLHTTPRetryPolicy> mRetryPolicy; -	LLPointer<LLInventoryCallback> mCallback; -}; - -// class RemoveItemCommand: public AISCommand -// { -// public: -// 	RemoveItemCommand(const LLUUID& item_id, -// 					  LLPointer<LLInventoryCallback> callback); -// }; - -// class RemoveCategoryCommand: public AISCommand -// { -// public: -// 	RemoveCategoryCommand(const LLUUID& item_id, -// 						  LLPointer<LLInventoryCallback> callback); -// }; - -// class PurgeDescendentsCommand: public AISCommand -// { -// public: -// 	PurgeDescendentsCommand(const LLUUID& item_id, -// 							LLPointer<LLInventoryCallback> callback); -// }; - -// class UpdateItemCommand: public AISCommand -// { -// public: -// 	UpdateItemCommand(const LLUUID& item_id, -// 					  const LLSD& updates, -// 					  LLPointer<LLInventoryCallback> callback); -// private: -// 	LLSD mUpdates; -// }; - -// class UpdateCategoryCommand: public AISCommand -// { -// public: -// 	UpdateCategoryCommand(const LLUUID& cat_id, -// 						  const LLSD& updates, -// 						  LLPointer<LLInventoryCallback> callback); -// private: -// 	LLSD mUpdates; -// }; - -// class SlamFolderCommand: public AISCommand -// { -// public: -// 	SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback); -// 	 -// private: -// 	LLSD mContents; -// }; - -class CopyLibraryCategoryCommand: public AISCommand -{ -public: -	CopyLibraryCategoryCommand(const LLUUID& source_id, const LLUUID& dest_id, LLPointer<LLInventoryCallback> callback); - -protected: -	/* virtual */ bool getResponseUUID(const LLSD& content, LLUUID& id); -}; - -// class CreateInventoryCommand: public AISCommand -// { -// public: -// 	CreateInventoryCommand(const LLUUID& parent_id, const LLSD& new_inventory, LLPointer<LLInventoryCallback> callback); -//  -// private: -// 	LLSD mNewInventory; -// };  class AISUpdate  { diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index ff420a3600..2883886fa1 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -63,6 +63,17 @@  #pragma warning (disable:4702)  #endif +#if 1 +// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model. +// temp code in transition +void doAppearanceCb(LLPointer<LLInventoryCallback> cb, LLUUID id) +{ +    if (cb.notNull()) +        cb->fire(id); +} +#endif + +  std::string self_av_string()  {  	// On logout gAgentAvatarp can already be invalid @@ -2457,8 +2468,7 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  			 << " )" << LL_ENDL;  	// If we are copying from library, attempt to use AIS to copy the category. -	bool ais_ran=false; -	if (copy && AISCommand::isAPIAvailable()) +    if (copy && AISAPI::isAvailable())  	{  		LLUUID parent_id;  		parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING); @@ -2470,11 +2480,11 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  		LLPointer<LLInventoryCallback> copy_cb = new LLWearCategoryAfterCopy(append);  		LLPointer<LLInventoryCallback> track_cb = new LLTrackPhaseWrapper(  													std::string("wear_inventory_category_callback"), copy_cb); -		LLPointer<AISCommand> cmd_ptr = new CopyLibraryCategoryCommand(category->getUUID(), parent_id, track_cb); -		ais_ran=cmd_ptr->run_command(); -	} -	if (!ais_ran) +        AISAPI::completion_t cr = boost::bind(&doAppearanceCb, track_cb, _1); +        AISAPI::CopyLibraryCategory(category->getUUID(), parent_id, cr); +	} +    else  	{  		selfStartPhase("wear_inventory_category_fetch");  		callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, @@ -3602,7 +3612,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo  	// First, make a folder in the My Outfits directory.  	const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); -	if (AISCommand::isAPIAvailable()) +    if (AISAPI::isAvailable())  	{  		// cap-based category creation was buggy until recently. use  		// existence of AIS as an indicator the fix is present. Does diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 729af3c8ed..ac19d84a5e 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -80,6 +80,7 @@ static const char * const LOG_LOCAL("InventoryLocalize");  static const char * const LOG_NOTECARD("copy_inventory_from_notecard");  #if 1 +// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model.  // temp code in transition  void doInventoryCb(LLPointer<LLInventoryCallback> cb, LLUUID id)  { @@ -1289,21 +1290,14 @@ void link_inventory_array(const LLUUID& category,  #endif  	} -	bool ais_ran = false; -	if (AISCommand::isAPIAvailable()) +    if (AISAPI::isAvailable())  	{  		LLSD new_inventory = LLSD::emptyMap();  		new_inventory["links"] = links; -#if 1          AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -        AISAPI::CreateInventoryCommand(category, new_inventory, cr); -#else - 		LLPointer<AISCommand> cmd_ptr = new CreateInventoryCommand(category, new_inventory, cb); - 		ais_ran = cmd_ptr->run_command(); -#endif +        AISAPI::CreateInventory(category, new_inventory, cr);  	} - -	if (!ais_ran) +    else  	{  		LLMessageSystem* msg = gMessageSystem;  		for (LLSD::array_iterator iter = links.beginArray(); iter != links.endArray(); ++iter ) @@ -1360,8 +1354,7 @@ void update_inventory_item(  	LLPointer<LLInventoryCallback> cb)  {  	const LLUUID& item_id = update_item->getUUID(); -	bool ais_ran = false; -	if (AISCommand::isAPIAvailable()) +    if (AISAPI::isAvailable())  	{  		LLSD updates = update_item->asLLSD();  		// Replace asset_id and/or shadow_id with transaction_id (hash_id) @@ -1375,15 +1368,10 @@ void update_inventory_item(  			updates.erase("shadow_id");  			updates["hash_id"] = update_item->getTransactionID();  		} -#if 1          AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -        AISAPI::UpdateItemCommand(item_id, updates, cr); -#else -		LLPointer<AISCommand> cmd_ptr = new UpdateItemCommand(item_id, updates, cb); -		ais_ran = cmd_ptr->run_command(); -#endif +        AISAPI::UpdateItem(item_id, updates, cr);  	} -	if (!ais_ran) +    else  	{  		LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id);  		LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (update_item ? update_item->getName() : "(NOT FOUND)") << LL_ENDL; @@ -1419,18 +1407,12 @@ void update_inventory_item(  	const LLSD& updates,  	LLPointer<LLInventoryCallback> cb)  { -	bool ais_ran = false; -	if (AISCommand::isAPIAvailable()) +    if (AISAPI::isAvailable())  	{ -#if 1          AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -        AISAPI::UpdateItemCommand(item_id, updates, cr); -#else -		LLPointer<AISCommand> cmd_ptr = new UpdateItemCommand(item_id, updates, cb); -		ais_ran = cmd_ptr->run_command(); -#endif +        AISAPI::UpdateItem(item_id, updates, cr);  	} -	if (!ais_ran) +    else  	{  		LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id);  		LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; @@ -1480,16 +1462,11 @@ void update_inventory_category(  		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(obj);  		new_cat->fromLLSD(updates);  		// FIXME - restore this once the back-end work has been done. -		if (AISCommand::isAPIAvailable()) +        if (AISAPI::isAvailable())  		{  			LLSD new_llsd = new_cat->asLLSD(); -#if 1              AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -            AISAPI::UpdateCategoryCommand(cat_id, new_llsd, cr); -#else -			LLPointer<AISCommand> cmd_ptr = new UpdateCategoryCommand(cat_id, new_llsd, cb); -			cmd_ptr->run_command(); -#endif +            AISAPI::UpdateCategory(cat_id, new_llsd, cr);  		}  		else // no cap  		{ @@ -1551,15 +1528,10 @@ void remove_inventory_item(  	{  		const LLUUID item_id(obj->getUUID());  		LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << obj->getName() << LL_ENDL; -		if (AISCommand::isAPIAvailable()) +        if (AISAPI::isAvailable())  		{ -#if 1              AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -            AISAPI::RemoveItemCommand(item_id, cr); -#else -			LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb); -			cmd_ptr->run_command(); -#endif +            AISAPI::RemoveItem(item_id, cr);  			if (immediate_delete)  			{ @@ -1632,15 +1604,10 @@ void remove_inventory_category(  			LLNotificationsUtil::add("CannotRemoveProtectedCategories");  			return;  		} -		if (AISCommand::isAPIAvailable()) +        if (AISAPI::isAvailable())  		{ -#if 1              AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -            AISAPI::RemoveCategoryCommand(cat_id, cr); -#else -			LLPointer<AISCommand> cmd_ptr = new RemoveCategoryCommand(cat_id, cb); -			cmd_ptr->run_command(); -#endif +            AISAPI::RemoveCategory(cat_id, cr);  		}  		else // no cap  		{ @@ -1740,15 +1707,10 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb)  		}  		else  		{ -			if (AISCommand::isAPIAvailable()) +            if (AISAPI::isAvailable())  			{ -#if 1                  AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -                AISAPI::PurgeDescendentsCommand(id, cr); -#else -                LLPointer<AISCommand> cmd_ptr = new PurgeDescendentsCommand(id, cb); -				cmd_ptr->run_command(); -#endif +                AISAPI::PurgeDescendents(id, cr);  			}  			else // no cap  			{ @@ -1895,17 +1857,13 @@ void slam_inventory_folder(const LLUUID& folder_id,  						   const LLSD& contents,  						   LLPointer<LLInventoryCallback> cb)  { -	if (AISCommand::isAPIAvailable()) +    if (AISAPI::isAvailable())  	{  		LL_DEBUGS(LOG_INV) << "using AISv3 to slam folder, id " << folder_id  						   << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; -#if 1 +          AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); -        AISAPI::SlamFolderCommand(folder_id, contents, cr); -#else -		LLPointer<AISCommand> cmd_ptr = new SlamFolderCommand(folder_id, contents, cb); -		cmd_ptr->run_command(); -#endif +        AISAPI::SlamFolder(folder_id, contents, cr);  	}  	else // no cap  	{ diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5c7071c63d..32b57dae25 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2822,7 +2822,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("FetchInventory2");  	capabilityNames.append("FetchInventoryDescendents2");  	capabilityNames.append("IncrementCOFVersion"); -	AISCommand::getCapabilityNames(capabilityNames); +	AISAPI::getCapNames(capabilityNames);  	capabilityNames.append("GetDisplayNames");  	capabilityNames.append("GetExperiences"); | 
