llsdrpcclient.cpp

Go to the documentation of this file.
00001 
00034 #include "linden_common.h"
00035 #include "llsdrpcclient.h"
00036 
00037 #include "llbufferstream.h"
00038 #include "llfiltersd2xmlrpc.h"
00039 #include "llmemtype.h"
00040 #include "llpumpio.h"
00041 #include "llsd.h"
00042 #include "llsdserialize.h"
00043 #include "llurlrequest.h"
00044 
00048 static std::string LLSDRPC_RESPONSE_NAME("response");
00049 static std::string LLSDRPC_FAULT_NAME("fault");
00050 
00054 LLSDRPCResponse::LLSDRPCResponse() :
00055         mIsError(false),
00056         mIsFault(false)
00057 {
00058         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00059 }
00060 
00061 // virtual
00062 LLSDRPCResponse::~LLSDRPCResponse()
00063 {
00064         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00065 }
00066 
00067 bool LLSDRPCResponse::extractResponse(const LLSD& sd)
00068 {
00069         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00070         bool rv = true;
00071         if(sd.has(LLSDRPC_RESPONSE_NAME))
00072         {
00073                 mReturnValue = sd[LLSDRPC_RESPONSE_NAME];
00074                 mIsFault = false;
00075         }
00076         else if(sd.has(LLSDRPC_FAULT_NAME))
00077         {
00078                 mReturnValue = sd[LLSDRPC_FAULT_NAME];
00079                 mIsFault = true;
00080         }
00081         else
00082         {
00083                 mReturnValue.clear();
00084                 mIsError = true;
00085                 rv = false;
00086         }
00087         return rv;
00088 }
00089 
00090 // virtual
00091 LLIOPipe::EStatus LLSDRPCResponse::process_impl(
00092         const LLChannelDescriptors& channels,
00093         buffer_ptr_t& buffer,
00094         bool& eos,
00095         LLSD& context,
00096         LLPumpIO* pump)
00097 {
00098         PUMP_DEBUG;
00099         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00100         if(mIsError)
00101         {
00102                 error(pump);
00103         }
00104         else if(mIsFault)
00105         {
00106                 fault(pump);
00107         }
00108         else
00109         {
00110                 response(pump);
00111         }
00112         PUMP_DEBUG;
00113         return STATUS_DONE;
00114 }
00115 
00120 LLSDRPCClient::LLSDRPCClient() :
00121         mState(STATE_NONE),
00122         mQueue(EPBQ_PROCESS)
00123 {
00124         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00125 }
00126 
00127 // virtual
00128 LLSDRPCClient::~LLSDRPCClient()
00129 {
00130         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00131 }
00132 
00133 bool LLSDRPCClient::call(
00134         const std::string& uri,
00135         const std::string& method,
00136         const LLSD& parameter,
00137         LLSDRPCResponse* response,
00138         EPassBackQueue queue)
00139 {
00140         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00141         //llinfos << "RPC: " << uri << "." << method << "(" << *parameter << ")"
00142         //              << llendl;
00143         if(method.empty() || !response)
00144         {
00145                 return false;
00146         }
00147         mState = STATE_READY;
00148         mURI.assign(uri);
00149         std::stringstream req;
00150         req << LLSDRPC_REQUEST_HEADER_1 << method
00151                 << LLSDRPC_REQUEST_HEADER_2;
00152         LLSDSerialize::toNotation(parameter, req);
00153         req << LLSDRPC_REQUEST_FOOTER;
00154         mRequest = req.str();
00155         mQueue = queue;
00156         mResponse = response;
00157         return true;
00158 }
00159 
00160 bool LLSDRPCClient::call(
00161         const std::string& uri,
00162         const std::string& method,
00163         const std::string& parameter,
00164         LLSDRPCResponse* response,
00165         EPassBackQueue queue)
00166 {
00167         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00168         //llinfos << "RPC: " << uri << "." << method << "(" << parameter << ")"
00169         //              << llendl;
00170         if(method.empty() || parameter.empty() || !response)
00171         {
00172                 return false;
00173         }
00174         mState = STATE_READY;
00175         mURI.assign(uri);
00176         std::stringstream req;
00177         req << LLSDRPC_REQUEST_HEADER_1 << method
00178                 << LLSDRPC_REQUEST_HEADER_2 << parameter
00179                 << LLSDRPC_REQUEST_FOOTER;
00180         mRequest = req.str();
00181         mQueue = queue;
00182         mResponse = response;
00183         return true;
00184 }
00185 
00186 // virtual
00187 LLIOPipe::EStatus LLSDRPCClient::process_impl(
00188         const LLChannelDescriptors& channels,
00189         buffer_ptr_t& buffer,
00190         bool& eos,
00191         LLSD& context,
00192         LLPumpIO* pump)
00193 {
00194         PUMP_DEBUG;
00195         LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00196         if((STATE_NONE == mState) || (!pump))
00197         {
00198                 // You should have called the call() method already.
00199                 return STATUS_PRECONDITION_NOT_MET;
00200         }
00201         EStatus rv = STATUS_DONE;
00202         switch(mState)
00203         {
00204         case STATE_READY:
00205         {
00206                 PUMP_DEBUG;
00207 //              lldebugs << "LLSDRPCClient::process_impl STATE_READY" << llendl;
00208                 buffer->append(
00209                         channels.out(),
00210                         (U8*)mRequest.c_str(),
00211                         mRequest.length());
00212                 context[CONTEXT_DEST_URI_SD_LABEL] = mURI;
00213                 mState = STATE_WAITING_FOR_RESPONSE;
00214                 break;
00215         }
00216         case STATE_WAITING_FOR_RESPONSE:
00217         {
00218                 PUMP_DEBUG;
00219                 // The input channel has the sd response in it.
00220                 //lldebugs << "LLSDRPCClient::process_impl STATE_WAITING_FOR_RESPONSE"
00221                 //               << llendl;
00222                 LLBufferStream resp(channels, buffer.get());
00223                 LLSD sd;
00224                 LLSDSerialize::fromNotation(sd, resp);
00225                 LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get();
00226                 if (!response)
00227                 {
00228                         mState = STATE_DONE;
00229                         break;
00230                 }
00231                 response->extractResponse(sd);
00232                 if(EPBQ_PROCESS == mQueue)
00233                 {
00234                         LLPumpIO::chain_t chain;
00235                         chain.push_back(mResponse);
00236                         pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
00237                 }
00238                 else
00239                 {
00240                         pump->respond(mResponse.get());
00241                 }
00242                 mState = STATE_DONE;
00243                 break;
00244         }
00245         case STATE_DONE:
00246         default:
00247                 PUMP_DEBUG;
00248                 llinfos << "invalid state to process" << llendl;
00249                 rv = STATUS_ERROR;
00250                 break;
00251         }
00252         return rv;
00253 }

Generated on Thu Jul 1 06:09:08 2010 for Second Life Viewer by  doxygen 1.4.7