summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp')
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp
new file mode 100644
index 00000000..bfdc7efe
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp
@@ -0,0 +1,280 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <string.h>
+#include "prlog.h"
+#include "ipcMessage.h"
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+# include <iprt/mem.h>
+#endif
+
+ipcMessage::~ipcMessage()
+{
+ if (mMsgHdr)
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(mMsgHdr);
+#else
+ free(mMsgHdr);
+#endif
+}
+
+void
+ipcMessage::Reset()
+{
+ if (mMsgHdr) {
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(mMsgHdr);
+#else
+ free(mMsgHdr);
+#endif
+ mMsgHdr = NULL;
+ }
+
+ mMsgOffset = 0;
+ mMsgComplete = PR_FALSE;
+}
+
+ipcMessage *
+ipcMessage::Clone() const
+{
+ ipcMessage *clone = new ipcMessage();
+ if (!clone)
+ return NULL;
+
+ // copy buf if non-null
+ if (mMsgHdr) {
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ clone->mMsgHdr = (ipcMessageHeader *) RTMemDup(mMsgHdr, mMsgHdr->mLen);
+#else
+ clone->mMsgHdr = (ipcMessageHeader *) malloc(mMsgHdr->mLen);
+ memcpy(clone->mMsgHdr, mMsgHdr, mMsgHdr->mLen);
+#endif
+ }
+ else
+ clone->mMsgHdr = NULL;
+
+ clone->mMsgOffset = mMsgOffset;
+ clone->mMsgComplete = mMsgComplete;
+
+ return clone;
+}
+
+PRStatus
+ipcMessage::Init(const nsID &target, const char *data, PRUint32 dataLen)
+{
+ if (mMsgHdr)
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(mMsgHdr);
+#else
+ free(mMsgHdr);
+#endif
+ mMsgComplete = PR_FALSE;
+
+ // allocate message data
+ PRUint32 msgLen = IPC_MSG_HEADER_SIZE + dataLen;
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen);
+#else
+ mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
+#endif
+ if (!mMsgHdr) {
+ mMsgHdr = NULL;
+ return PR_FAILURE;
+ }
+
+ // fill in message data
+ mMsgHdr->mLen = msgLen;
+ mMsgHdr->mVersion = IPC_MSG_VERSION;
+ mMsgHdr->mFlags = 0;
+ mMsgHdr->mTarget = target;
+
+ if (data)
+ SetData(0, data, dataLen);
+
+ mMsgComplete = PR_TRUE;
+ return PR_SUCCESS;
+}
+
+PRStatus
+ipcMessage::SetData(PRUint32 offset, const char *data, PRUint32 dataLen)
+{
+ PR_ASSERT(mMsgHdr != NULL);
+
+ if (offset + dataLen > DataLen())
+ return PR_FAILURE;
+
+ memcpy((char *) Data() + offset, data, dataLen);
+ return PR_SUCCESS;
+}
+
+PRBool
+ipcMessage::Equals(const nsID &target, const char *data, PRUint32 dataLen) const
+{
+ return mMsgComplete &&
+ mMsgHdr->mTarget.Equals(target) &&
+ DataLen() == dataLen &&
+ memcmp(Data(), data, dataLen) == 0;
+}
+
+PRBool
+ipcMessage::Equals(const ipcMessage *msg) const
+{
+ PRUint32 msgLen = MsgLen();
+ return mMsgComplete && msg->mMsgComplete &&
+ msgLen == msg->MsgLen() &&
+ memcmp(MsgBuf(), msg->MsgBuf(), msgLen) == 0;
+}
+
+PRStatus
+ipcMessage::WriteTo(char *buf,
+ PRUint32 bufLen,
+ PRUint32 *bytesWritten,
+ PRBool *complete)
+{
+ if (!mMsgComplete)
+ return PR_FAILURE;
+
+ if (mMsgOffset == MsgLen()) {
+ *bytesWritten = 0;
+ *complete = PR_TRUE;
+ return PR_SUCCESS;
+ }
+
+ PRUint32 count = MsgLen() - mMsgOffset;
+ if (count > bufLen)
+ count = bufLen;
+
+ memcpy(buf, MsgBuf() + mMsgOffset, count);
+ mMsgOffset += count;
+
+ *bytesWritten = count;
+ *complete = (mMsgOffset == MsgLen());
+
+ return PR_SUCCESS;
+}
+
+PRStatus
+ipcMessage::ReadFrom(const char *buf,
+ PRUint32 bufLen,
+ PRUint32 *bytesRead,
+ PRBool *complete)
+{
+ *bytesRead = 0;
+
+ if (mMsgComplete) {
+ *complete = PR_TRUE;
+ return PR_SUCCESS;
+ }
+
+ if (mMsgHdr) {
+ // appending data to buffer
+ if (mMsgOffset < sizeof(PRUint32)) {
+ // we haven't learned the message length yet
+ if (mMsgOffset + bufLen < sizeof(PRUint32)) {
+ // we still don't know the length of the message!
+ memcpy((char *) mMsgHdr + mMsgOffset, buf, bufLen);
+ mMsgOffset += bufLen;
+ *bytesRead = bufLen;
+ *complete = PR_FALSE;
+ return PR_SUCCESS;
+ }
+ else {
+ // we now have enough data to determine the message length
+ PRUint32 count = sizeof(PRUint32) - mMsgOffset;
+ memcpy((char *) MsgBuf() + mMsgOffset, buf, count);
+ mMsgOffset += count;
+ buf += count;
+ bufLen -= count;
+ *bytesRead = count;
+
+ if (MsgLen() > IPC_MSG_GUESSED_SIZE) {
+ // realloc message buffer to the correct size
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ mMsgHdr = (ipcMessageHeader *) RTMemRealloc(mMsgHdr, MsgLen());
+#else
+ mMsgHdr = (ipcMessageHeader *) realloc(mMsgHdr, MsgLen());
+#endif
+ }
+ }
+ }
+ }
+ else {
+ if (bufLen < sizeof(PRUint32)) {
+ // not enough data available in buffer to determine allocation size
+ // allocate a partial buffer
+ PRUint32 msgLen = IPC_MSG_GUESSED_SIZE;
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen);
+#else
+ mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
+#endif
+ if (!mMsgHdr)
+ return PR_FAILURE;
+ memcpy(mMsgHdr, buf, bufLen);
+ mMsgOffset = bufLen;
+ *bytesRead = bufLen;
+ *complete = PR_FALSE;
+ return PR_SUCCESS;
+ }
+ else {
+ PRUint32 msgLen = *(PRUint32 *) buf;
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen);
+#else
+ mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
+#endif
+ if (!mMsgHdr)
+ return PR_FAILURE;
+ mMsgHdr->mLen = msgLen;
+ mMsgOffset = 0;
+ }
+ }
+
+ // have mMsgHdr at this point
+
+ PRUint32 count = MsgLen() - mMsgOffset;
+ if (count > bufLen)
+ count = bufLen;
+
+ memcpy((char *) mMsgHdr + mMsgOffset, buf, count);
+ mMsgOffset += count;
+ *bytesRead += count;
+
+ *complete = mMsgComplete = (mMsgOffset == MsgLen());
+ return PR_SUCCESS;
+}