From 51b79cafaa57b231f3fd87e29fe190a442bd8a81 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 13 Jan 2011 19:10:07 +0000 Subject: In qmfengine, if a method call or method response requires a buffer larger than the static buffer used for communication, allocate a large-enough buffer temporarily from the heap. A test is included to verify large-buffer behavior. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1058709 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/src/qmf/engine/Agent.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/src/qmf/engine/Agent.cpp') diff --git a/qpid/cpp/src/qmf/engine/Agent.cpp b/qpid/cpp/src/qmf/engine/Agent.cpp index 067f53471f..1f08dded94 100644 --- a/qpid/cpp/src/qmf/engine/Agent.cpp +++ b/qpid/cpp/src/qmf/engine/Agent.cpp @@ -356,8 +356,7 @@ void AgentImpl::heartbeat() QPID_LOG(trace, "SENT HeartbeatIndication"); } -void AgentImpl::methodResponse(uint32_t sequence, uint32_t status, char* text, - const Value& argMap) +void AgentImpl::methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& argMap) { Mutex::ScopedLock _lock(lock); map::iterator iter = contextMap.find(sequence); @@ -366,7 +365,32 @@ void AgentImpl::methodResponse(uint32_t sequence, uint32_t status, char* text, AgentQueryContext::Ptr context = iter->second; contextMap.erase(iter); - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); + char* buf(outputBuffer); + uint32_t bufLen(114 + strlen(text)); // header(8) + status(4) + mstring(2 + size) + margin(100) + bool allocated(false); + + if (status == 0) { + for (vector::const_iterator aIter = context->schemaMethod->impl->arguments.begin(); + aIter != context->schemaMethod->impl->arguments.end(); aIter++) { + const SchemaArgument* schemaArg = *aIter; + if (schemaArg->getDirection() == DIR_OUT || schemaArg->getDirection() == DIR_IN_OUT) { + if (argMap.keyInMap(schemaArg->getName())) { + const Value* val = argMap.byKey(schemaArg->getName()); + bufLen += val->impl->encodedSize(); + } else { + Value val(schemaArg->getType()); + bufLen += val.impl->encodedSize(); + } + } + } + } + + if (bufLen > MA_BUFFER_SIZE) { + buf = (char*) malloc(bufLen); + allocated = true; + } + + Buffer buffer(buf, bufLen); Protocol::encodeHeader(buffer, Protocol::OP_METHOD_RESPONSE, context->sequence); buffer.putLong(status); buffer.putMediumString(text); @@ -386,6 +410,8 @@ void AgentImpl::methodResponse(uint32_t sequence, uint32_t status, char* text, } } sendBufferLH(buffer, context->exchange, context->key); + if (allocated) + free(buf); QPID_LOG(trace, "SENT MethodResponse seq=" << context->sequence << " status=" << status << " text=" << text); } -- cgit v1.2.1