From 0f73de423d074e846203ec51769df708c17f1953 Mon Sep 17 00:00:00 2001
Message-Id: <0f73de423d074e846203ec51769df708c17f1953.1348577193.git.ibell@...>
In-Reply-To: <c6056d16f347a98054cb70348d5fbcc988abbf60.1348577193.git.ibell@...>
References: <c6056d16f347a98054cb70348d5fbcc988abbf60.1348577193.git.ibell@...>
From: Ian Bell <ibell@...>
Date: Tue, 25 Sep 2012 13:39:48 +0100
Subject: [PATCH 3/5] Add getTempCopy API for msg
Added a new API which checks if the underlying buffer is 'owned'. If it is
a pointer to the msg is returned, if not a new copy of hte buffer is taken
and wrapped with a pointer to that msg returned. Once it is copied once
subsequent calls to the API will return the same copy
Signed-off-by: Ian Bell <ibell@...>
---
mama/c_cpp/src/c/mama/msg.h | 21 ++++++++++++++----
mama/c_cpp/src/c/msg.c | 43 +++++++++++++++++++++++++++++++++++--
mama/c_cpp/src/cpp/MamaMsg.cpp | 22 ++++++++++++++++---
mama/c_cpp/src/cpp/mama/MamaMsg.h | 14 +++++++++++-
4 files changed, 90 insertions(+), 10 deletions(-)
diff --git a/mama/c_cpp/src/c/mama/msg.h b/mama/c_cpp/src/c/mama/msg.h
index 6b1e86f..2790372 100644
--- a/mama/c_cpp/src/c/mama/msg.h
+++ b/mama/c_cpp/src/c/mama/msg.h
@@ -54,7 +54,8 @@ typedef enum mamaPayloadType_
* Convert a mamaPayloadType value to a string. Do no attempt to free the
* string result.
*
- * @param payloadType The payloadType to convert.*/
+ * @param payloadType The payloadType to convert.
+ */
MAMAExpDLL
extern const char*
mamaPayload_convertToString (mamaPayloadType payloadType);
@@ -110,6 +111,20 @@ mamaMsg_createForTemplate (mamaMsg* msg, mama_u32_t templateId);
MAMAExpDLL
extern mama_status
mamaMsg_copy (mamaMsg src, mamaMsg *copy);
+/**
+ * Get a temporary copy of the mamaMsg so to be able to modify the content.
+ * If the message can be modified directly, the message itself is returned.
+ * If the message cannot be modified then only one copy is performed the first time
+ * this function is called and then the same copy is returned when this function is
+ * called again.
+ * The copy is destroyed when the original message is destroyed.
+ *
+ * @param src The message to copy.
+ * @param copy A pointer to the destination message.
+ */
+MAMAExpDLL
+extern mama_status
+mamaMsg_getTempCopy (mamaMsg src, mamaMsg* copy);
/**
* Clear a msg. All fields are removed.
@@ -2057,9 +2072,7 @@ mamaMsg_getSeqNum(
/**
* Extract the type from the supplied message.
*
- *
* @param msg The message.
- * @param msg
* @return The type.
*/
MAMAExpDLL
@@ -2365,4 +2378,4 @@ mamaMsgIterator_destroy (mamaMsgIterator iterator);
}
#endif
-#endif /* MAMA_H__ */
+#endif /* MamaMsgH__ */
diff --git a/mama/c_cpp/src/c/msg.c b/mama/c_cpp/src/c/msg.c
index 2829fa4..3943a03 100644
--- a/mama/c_cpp/src/c/msg.c
+++ b/mama/c_cpp/src/c/msg.c
@@ -84,6 +84,7 @@ typedef struct mamaMsgImpl_
/*Reuseable field object for performance iteration*/
mamaMsgField mCurrentField;
mamaDateTime mCurrentDateTime;
+ mamaMsg mCopy;
/*Hold onto the bridge impl for later use*/
mamaBridgeImpl* mBridgeImpl;
@@ -161,11 +162,17 @@ mamaMsg_destroy (mamaMsg msg)
impl->mBridgeMessage = NULL;
}
- /*Destroy the reuseable field object*/
+ /*Destroy the reusable field object*/
if (impl->mCurrentField)
{
mamaMsgField_destroy (impl->mCurrentField);
}
+ /*Destroy the reusable field object*/
+ if (impl->mCopy)
+ {
+ mamaMsg_destroy (impl->mCopy);
+ impl->mCopy = NULL;
+ }
impl->mDqStrategyContext = NULL;
@@ -463,7 +470,7 @@ mamaMsgImpl_setMsgBuffer(mamaMsg msg,
mamaMsgImpl* impl = (mamaMsgImpl*)msg;
mama_status status = MAMA_STATUS_OK;
msgPayload payload = NULL;
- mamaPayloadBridgeImpl* newPayloadBridge = NULL;
+
if (impl == NULL)
{
mama_log (MAMA_LOG_LEVEL_WARN,
@@ -499,6 +506,12 @@ mamaMsgImpl_setMsgBuffer(mamaMsg msg,
impl->mBridgeMessage = NULL;
}
impl->mMessageOwner = 0;
+ /* If there is tempCopy of this message, destroy it */
+ if (impl->mCopy)
+ {
+ mamaMsg_destroy(impl->mCopy);
+ impl->mCopy = NULL;
+ }
if (id == '\0')
id = (char) ((const char*)data) [0];
@@ -702,6 +715,32 @@ mamaMsg_copy (mamaMsg src, mamaMsg* copy)
}
mama_status
+mamaMsg_getTempCopy (mamaMsg src, mamaMsg* copy)
+{
+ mama_status ret;
+ mamaMsgImpl* impl = (mamaMsgImpl*)src;
+
+ if (impl->mMessageOwner)
+ {
+ *copy = src;
+ return MAMA_STATUS_OK;
+ }
+
+ if (!impl->mCopy)
+ {
+ ret = mamaMsg_copy(src, &impl->mCopy);
+ if (ret != MAMA_STATUS_OK)
+ {
+ impl->mCopy = NULL;
+ return ret;
+ }
+ }
+ *copy = impl->mCopy;
+
+ return MAMA_STATUS_OK;
+}
+
+mama_status
mamaMsg_create (mamaMsg* msg)
{
mama_status status = MAMA_STATUS_OK;
diff --git a/mama/c_cpp/src/cpp/MamaMsg.cpp b/mama/c_cpp/src/cpp/MamaMsg.cpp
index 387a596..bbdb1c9 100644
--- a/mama/c_cpp/src/cpp/MamaMsg.cpp
+++ b/mama/c_cpp/src/cpp/MamaMsg.cpp
@@ -52,6 +52,7 @@ namespace Wombat
, mTmpMsg (NULL)
, mString (NULL)
, mMsgField (new MamaMsgField)
+ , mCopyMsg (NULL)
{
}
@@ -66,6 +67,7 @@ namespace Wombat
, mTmpMsg (NULL)
, mString (NULL)
, mMsgField (new MamaMsgField)
+ , mCopyMsg (NULL)
{
this->copy (copy);
}
@@ -124,12 +126,20 @@ namespace Wombat
mamaTry (mamaMsg_copy (rhs.mMsg, &mMsg));
}
+ MamaMsg* MamaMsg::getTempCopy()
+ {
+ if (!mCopyMsg)
+ {
+ mCopyMsg = new MamaMsg;
+ mCopyMsg->mDestroy = false;
+ }
+ if (mMsg) mamaTry(mamaMsg_getTempCopy(mMsg, &mCopyMsg->mMsg));
+ return mCopyMsg;
+ }
void MamaMsg::clear (void)
{
if (mMsg) mamaTry (mamaMsg_clear (mMsg));
- mDestroy = true;
-
if (mCvectorMsg)
{
for (size_t i = 0; i < mCvectorMsgAllocSize; ++i)
@@ -161,7 +171,7 @@ namespace Wombat
return mMsg;
}
- mamaPayloadType MamaMsg::getPayloadType (void)
+ mamaPayloadType MamaMsg::getPayloadType (void) const
{
mamaPayloadType result;
mamaTry (mamaMsg_getPayloadType (mMsg, &result));
@@ -2402,6 +2412,12 @@ void MamaMsg::method (const MamaFieldDescriptor* field, fType value) \
delete mTmpMsg;
mTmpMsg = NULL;
}
+
+ if (mCopyMsg)
+ {
+ delete mCopyMsg;
+ mCopyMsg = NULL;
+ }
}
void MamaMsg::applyMsg (const MamaMsg& delta)
diff --git a/mama/c_cpp/src/cpp/mama/MamaMsg.h b/mama/c_cpp/src/cpp/mama/MamaMsg.h
index 365f636..4c13163 100644
--- a/mama/c_cpp/src/cpp/mama/MamaMsg.h
+++ b/mama/c_cpp/src/cpp/mama/MamaMsg.h
@@ -194,6 +194,17 @@ namespace Wombat
*/
void copy (const MamaMsg& rhs);
+ /**
+ * Get a temporary copy of the mamaMsg so to be able to modify the content.
+ * If the message can be modified directly, the message itself is returned.
+ * If the message cannot be modified then only one copy is performed the first time
+ * this method is called and then the same copy is returned when this method is
+ * called again.
+ * The copy has the same life time of the original message.
+ *
+ * @return The message copy.
+ */
+ MamaMsg* getTempCopy();
void applyMsg (const MamaMsg& msg);
/**
@@ -2914,7 +2925,7 @@ namespace Wombat
*
* @return payloadType The payload type.
*/
- mamaPayloadType getPayloadType (void);
+ mamaPayloadType getPayloadType (void) const;
/**
* Get the native message structure for the underlying message
@@ -2955,6 +2966,7 @@ namespace Wombat
mutable MamaMsg* mTmpMsg;
mutable const char* mString;
mutable MamaMsgField* mMsgField;
+ mutable MamaMsg* mCopyMsg;
void setDestroyCMsg (bool destroy);
void cleanup ();
--
1.7.9.5