Back to index

lightning-sunbird  0.9+nobinonly
ipcm.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla IPC.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Darin Fisher <darin@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <string.h>
00039 #include "ipcm.h"
00040 #include "pratom.h"
00041 
00042 const nsID IPCM_TARGET =
00043 { /* 753ca8ff-c8c2-4601-b115-8c2944da1150 */
00044     0x753ca8ff,
00045     0xc8c2,
00046     0x4601,
00047     {0xb1, 0x15, 0x8c, 0x29, 0x44, 0xda, 0x11, 0x50}
00048 };
00049 
00050 PRUint32
00051 IPCM_NewRequestIndex()
00052 {
00053     static PRInt32 sRequestIndex;
00054     return (PRUint32) PR_AtomicIncrement(&sRequestIndex);
00055 }
00056 
00057 #if 0
00058 
00059 //
00060 // MSG_TYPE values
00061 //
00062 const PRUint32 ipcmMessagePing::MSG_TYPE = IPCM_MSG_TYPE_PING;
00063 const PRUint32 ipcmMessageError::MSG_TYPE = IPCM_MSG_TYPE_ERROR;
00064 const PRUint32 ipcmMessageClientHello::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_HELLO;
00065 const PRUint32 ipcmMessageClientID::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ID;
00066 const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
00067 const PRUint32 ipcmMessageClientAddName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_NAME;
00068 const PRUint32 ipcmMessageClientDelName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_NAME;
00069 const PRUint32 ipcmMessageClientAddTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_TARGET;
00070 const PRUint32 ipcmMessageClientDelTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_TARGET;
00071 const PRUint32 ipcmMessageQueryClientByName::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME;
00072 const PRUint32 ipcmMessageQueryClientInfo::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_INFO;
00073 const PRUint32 ipcmMessageForward::MSG_TYPE = IPCM_MSG_TYPE_FORWARD;
00074 const PRUint32 ipcmMessageClientStatus::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_STATUS;
00075 
00076 //
00077 // CLIENT_INFO message
00078 //
00079 //  +-----------------------------------------+
00080 //  | DWORD : MSG_TYPE                        |
00081 //  +--------------------+--------------------+
00082 //  | DWORD : clientID                        |
00083 //  +--------------------+--------------------+
00084 //  | DWORD : requestIndex                    |
00085 //  +--------------------+--------------------+
00086 //  | WORD : nameStart   | WORD : nameCount   |
00087 //  +--------------------+--------------------+
00088 //  | WORD : targetStart | WORD : targetCount |
00089 //  +--------------------+--------------------+
00090 //  | name[0]            | (null byte)        |
00091 //  +--------------------+--------------------+
00092 //  .                    .                    .
00093 //  .                    .                    .
00094 //  +--------------------+--------------------+
00095 //  | name[count - 1]    | (null byte)        |
00096 //  +--------------------+--------------------+
00097 //  | target[0]                               |
00098 //  +-----------------------------------------+
00099 //  .                    .                    .
00100 //  .                    .                    .
00101 //  +-----------------------------------------+
00102 //  | target[count - 1]                       |
00103 //  +-----------------------------------------+
00104 //
00105 
00106 struct ipcmClientInfoHeader
00107 {
00108     PRUint32 mType;
00109     PRUint32 mID;
00110     PRUint32 mRequestIndex;
00111     PRUint16 mNameStart;
00112     PRUint16 mNameCount;
00113     PRUint16 mTargetStart;
00114     PRUint16 mTargetCount;
00115 };
00116 
00117 ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, PRUint32 rIdx, const char *names[], const nsID *targets[])
00118 {
00119     ipcmClientInfoHeader hdr = {0};
00120 
00121     hdr.mType = MSG_TYPE;
00122     hdr.mID = cID;
00123     hdr.mRequestIndex = rIdx;
00124     hdr.mNameStart = sizeof(hdr);
00125 
00126     PRUint32 i, namesLen = 0;
00127 
00128     i = 0;
00129     while (names[i]) {
00130         namesLen += (strlen(names[i]) + 1);
00131         ++hdr.mNameCount;
00132         ++i;
00133     }
00134 
00135     i = 0;
00136     while (targets[i]) {
00137         ++hdr.mTargetCount;
00138         ++i;
00139     }
00140 
00141     //
00142     // compute target array starting offset
00143     //
00144     hdr.mTargetStart = hdr.mNameStart + namesLen;
00145 
00146     //
00147     // compute message length
00148     //
00149     PRUint32 dataLen = sizeof(hdr) + namesLen + hdr.mTargetCount * sizeof(nsID);
00150 
00151     Init(IPCM_TARGET, NULL, dataLen);
00152     
00153     //
00154     // write message data
00155     //
00156     SetData(0, (const char *) &hdr, sizeof(hdr));
00157 
00158     PRUint32 offset = sizeof(hdr);
00159 
00160     for (i = 0; names[i]; ++i) {
00161         PRUint32 len = strlen(names[i]) + 1;
00162         SetData(offset, names[i], len);
00163         offset += len;
00164     }
00165 
00166     for (i = 0; targets[i]; ++i) {
00167         PRUint32 len = sizeof(nsID);
00168         SetData(offset, (const char *) targets[i], len);
00169         offset += len;
00170     }
00171 }
00172 
00173 PRUint32
00174 ipcmMessageClientInfo::ClientID() const
00175 {
00176     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00177     return hdr->mID;
00178 }
00179 
00180 PRUint32
00181 ipcmMessageClientInfo::RequestIndex() const
00182 {
00183     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00184     return hdr->mRequestIndex;
00185 }
00186 
00187 PRUint32
00188 ipcmMessageClientInfo::NameCount() const
00189 {
00190     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00191     return hdr->mNameCount;
00192 }
00193 
00194 PRUint32
00195 ipcmMessageClientInfo::TargetCount() const
00196 {
00197     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00198     return hdr->mTargetCount;
00199 }
00200 
00201 const char *
00202 ipcmMessageClientInfo::NextName(const char *name) const
00203 {
00204     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00205 
00206     if (!name)
00207         return (const char *) hdr + hdr->mNameStart;
00208 
00209     name += strlen(name) + 1;
00210     if (name == (const char *) hdr + hdr->mTargetStart)
00211         name = NULL;
00212     return name;
00213 }
00214 
00215 const nsID *
00216 ipcmMessageClientInfo::NextTarget(const nsID *target) const
00217 {
00218     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
00219 
00220     if (!target)
00221         return (const nsID *) (Data() + hdr->mTargetStart);
00222 
00223     if (++target == (const nsID *) (MsgBuf() + MsgLen()))
00224         target = NULL;
00225     return target;
00226 }
00227 #endif
00228 
00229 //
00230 // FORWARD message
00231 //
00232 //  +-------------------------+
00233 //  | DWORD : MSG_TYPE        |
00234 //  +-------------------------+
00235 //  | clientID                |
00236 //  +-------------------------+
00237 //  | innerMsgHeader          |
00238 //  +-------------------------+
00239 //  | innerMsgData            |
00240 //  +-------------------------+
00241 //
00242 
00243 ipcmMessageForward::ipcmMessageForward(PRUint32 type,
00244                                        PRUint32 cID,
00245                                        const nsID &target,
00246                                        const char *data,
00247                                        PRUint32 dataLen)
00248 {
00249     int len = sizeof(ipcmMessageHeader) +  // IPCM header
00250               sizeof(cID) +                // cID
00251               IPC_MSG_HEADER_SIZE +        // innerMsgHeader
00252               dataLen;                     // innerMsgData
00253 
00254     Init(IPCM_TARGET, NULL, len);
00255 
00256     ipcmMessageHeader ipcmHdr =
00257         { type, IPCM_NewRequestIndex() };
00258 
00259     SetData(0, (char *) &ipcmHdr, sizeof(ipcmHdr));
00260     SetData(sizeof(ipcmHdr), (char *) &cID, sizeof(cID));
00261 
00262     ipcMessageHeader hdr;
00263     hdr.mLen = IPC_MSG_HEADER_SIZE + dataLen;
00264     hdr.mVersion = IPC_MSG_VERSION;
00265     hdr.mFlags = 0;
00266     hdr.mTarget = target;
00267 
00268     SetData(sizeof(ipcmHdr) + sizeof(cID), (char *) &hdr, IPC_MSG_HEADER_SIZE);
00269     if (data)
00270         SetInnerData(0, data, dataLen);
00271 }
00272 
00273 void
00274 ipcmMessageForward::SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen)
00275 {
00276     SetData(sizeof(ipcmMessageHeader) + 4 + IPC_MSG_HEADER_SIZE + offset, data, dataLen);
00277 }
00278 
00279 PRUint32
00280 ipcmMessageForward::ClientID() const
00281 {
00282     return ((PRUint32 *) Data())[2];
00283 }
00284 
00285 const nsID &
00286 ipcmMessageForward::InnerTarget() const
00287 {
00288     ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);
00289     return hdr->mTarget;
00290 }
00291 
00292 const char *
00293 ipcmMessageForward::InnerData() const
00294 {
00295     return Data() + 12 + IPC_MSG_HEADER_SIZE;
00296 }
00297 
00298 PRUint32
00299 ipcmMessageForward::InnerDataLen() const
00300 {
00301     ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);
00302     return hdr->mLen - IPC_MSG_HEADER_SIZE;
00303 }