BUG#: 8171
authormike <mike>
Tue, 25 Nov 2008 19:27:23 +0000 (19:27 +0000)
committermike <mike>
Tue, 25 Nov 2008 19:27:23 +0000 (19:27 +0000)
TITLE: Binary Protocol

DESCRIPTION: Initial commit of binary protocol feature.

39 files changed:
doc/BuildAndReleaseOptions.html
mak/config.mak
readme.binary_protocol_faq [new file with mode: 0644]
src/Pegasus/Client/CIMClientRep.cpp
src/Pegasus/Client/CIMClientRep.h
src/Pegasus/Client/CIMOperationRequestEncoder.cpp
src/Pegasus/Client/CIMOperationRequestEncoder.h
src/Pegasus/Client/CIMOperationResponseDecoder.cpp
src/Pegasus/Client/CIMOperationResponseDecoder.h
src/Pegasus/Client/tests/BinaryClient/BinaryClient.cpp [new file with mode: 0644]
src/Pegasus/Client/tests/BinaryClient/Makefile [new file with mode: 0644]
src/Pegasus/Client/tests/Makefile
src/Pegasus/Client/tests/Print/Makefile [new file with mode: 0644]
src/Pegasus/Client/tests/Print/TestPrint.cpp [new file with mode: 0644]
src/Pegasus/Common/AnonymousPipe.cpp
src/Pegasus/Common/BinaryCodec.cpp [new file with mode: 0644]
src/Pegasus/Common/BinaryCodec.h [new file with mode: 0644]
src/Pegasus/Common/BinaryStreamer.cpp
src/Pegasus/Common/CIMBinMsgDeserializer.cpp
src/Pegasus/Common/CIMBinMsgDeserializer.h
src/Pegasus/Common/CIMBinMsgSerializer.cpp
src/Pegasus/Common/CIMBuffer.cpp
src/Pegasus/Common/CIMBuffer.h
src/Pegasus/Common/CIMMessage.cpp
src/Pegasus/Common/CIMMessage.h
src/Pegasus/Common/CIMQualifierDeclRep.h
src/Pegasus/Common/Makefile
src/Pegasus/Common/Once.h
src/Pegasus/Common/Print.cpp [new file with mode: 0644]
src/Pegasus/Common/Print.h [new file with mode: 0644]
src/Pegasus/Common/XmlWriter.cpp
src/Pegasus/Common/XmlWriter.h
src/Pegasus/Common/tests/CIMBuffer/TestCIMBuffer.cpp
src/Pegasus/Common/tests/Makefile
src/Pegasus/Common/tests/MessageSerializer/MessageSerializer.cpp
src/Pegasus/Common/tests/Tracer/Tracer.cpp
src/Pegasus/Server/CIMOperationRequestDecoder.cpp
src/Pegasus/Server/CIMOperationRequestDecoder.h
src/Pegasus/Server/CIMOperationResponseEncoder.cpp

index 591b22fd90232a85a56657840eca88e8ecc4fa70..ce3d20ed4e40c0734fdc756bebefff23ca370757 100644 (file)
@@ -639,31 +639,6 @@ additional information.</p>
      to false), a build error will be generated.
 </ul>
 
-<h5>PEGASUS_ENABLE_ENCAPSULATED_XML</h5>
-<ul>
-  <b>Description:&nbsp;</b>
-     This option enables the "encapsulated XML" feature. It is used in
-     conjunction with the "internal binary protocol" feature (see 
-     PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL). When enabled, the out-of-process
-     provider agent serializes CIM instances (contained in get-instance and
-     enumerate-instances responses) as XML (embedded in a binary message
-     envelope). This improves performance since the server may pass the
-     XML instaces through to the requesting client without deserializing them
-     from binary and then reserializing them as XML.
-     <br>
-  <b>Default Value:&nbsp;</b>false<br>
-  <b>Recommended Value (Development Build): </b>
-     No Specific Recommendation<br>
-  <b>Recommended Value (Release Build):&nbsp;</b>
-     No Specific Recommendation<br>
-  <b>Required:&nbsp;</b>No<br>
-  <b>Considerations:&nbsp;</b>This feature has no effect unless the "internal
-     binary protocol" feature is enabled (see 
-     PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL). Deciding whether to enable or
-     disable this feature is left to the user. Every environment is different
-     and some users may prefer lower bandwidth rather than higher performance.
-</ul>
-
 <h5>PEGASUS_ENABLE_EXECQUERY</h5>
 <ul>
   <b>Description:&nbsp;</b>When this environment variable is set,
@@ -755,7 +730,7 @@ additional information.</p>
      indication provider.<br>  
 </ul>
 
-<h5>PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL</h5>
+<h5>PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY</h5>
 <ul>
   <b>Description: </b>If true, OpenPegasus uses a faster binary
      protocol between the CIM server and provider manager. If false,
@@ -767,9 +742,23 @@ additional information.</p>
   <b>Required: </b>No<br>
   <b>Considerations: </b>This option improves performance by optimizing the
      serialization and deserialization of messages between the server and 
-     out-of-process providers. The binary protocol also supports an optional
-     "encapsulated XML" feature (see PEGASUS_ENABLE_ENCAPSULATED_XML) for 
-     details.
+     out-of-process providers.
+     <br>
+</ul>
+
+<h5>PEGASUS_ENABLE_PROTOCOL_BINARY</h5>
+<ul>
+  <b>Description: </b>If true, OpenPegasus uses a faster binary
+     protocol between local clients (including the provider agent) and the 
+     CIM server. If false, OpenPegasus uses the conventional XML-based protocol 
+     instead. See PEP#340 for more details.
+     <br>
+  <b>Default Value: </b>false<br>
+  <b>Recommended Value (Development Build): </b>false<br>
+  <b>Recommended Value (Release Build): </b>false<br>
+  <b>Required: </b>No<br>
+  <b>Considerations: </b>This option improves performance by using a faster
+     binary protocol between local clients and the CIM server.
      <br>
 </ul>
 
index cd12318f3d411bb1e94ff343278471bd3b0ba360..8debf5d3d4b1b76a11b5166a17848e492e7448a3 100644 (file)
@@ -1424,44 +1424,45 @@ endif
 
 ##==============================================================================
 ##
-## PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL
+## PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY
 ##
 ##     Enable binary protocol between cimserver and out-of-process providers.
 ##     By default this feature is enabled.
 ##
 ##==============================================================================
 
-ifndef PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL
-  PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL=true
+ifndef PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY
+  PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY=true
 endif
 
-ifeq ($(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL),true)
-  DEFINES += -DPEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL
+ifeq ($(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY),true)
+  DEFINES += -DPEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY
 else
-  ifneq ($(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL),false)
-    $(error "PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL must be true or false")
+  ifneq ($(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY),false)
+    $(error "PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY must be true or false")
   endif
 endif
 
 ##==============================================================================
 ##
-## PEGASUS_ENABLE_ENCAPSULATED_XML
+## PEGASUS_ENABLE_PROTOCOL_BINARY
 ##
-##     Enable encapsulated XML within binary protocol messages. This improves
-##     performance by allowing provider to format XML which the server can
-##     pass through to client without converting to CIMInstances.
+##     Enables the binary protocol between clients and cimserver. With provider
+##     agent, both requests and responses are binary. For "ordinary" clients,
+##     requests are XML and responses are binary. By default, this only affects
+##     the protocol used over local domain sockets.
 ##
 ##==============================================================================
 
-ifndef PEGASUS_ENABLE_ENCAPSULATED_XML
-  PEGASUS_ENABLE_ENCAPSULATED_XML=false
+ifndef PEGASUS_ENABLE_PROTOCOL_BINARY
+  PEGASUS_ENABLE_PROTOCOL_BINARY=false
 endif
 
-ifeq ($(PEGASUS_ENABLE_ENCAPSULATED_XML),true)
-  DEFINES += -DPEGASUS_ENABLE_ENCAPSULATED_XML
+ifeq ($(PEGASUS_ENABLE_PROTOCOL_BINARY),true)
+  DEFINES += -DPEGASUS_ENABLE_PROTOCOL_BINARY
 else
-  ifneq ($(PEGASUS_ENABLE_ENCAPSULATED_XML),false)
-    $(error "PEGASUS_ENABLE_ENCAPSULATED_XML must be true or false")
+  ifneq ($(PEGASUS_ENABLE_PROTOCOL_BINARY),false)
+    $(error "PEGASUS_ENABLE_PROTOCOL_BINARY must be true or false")
   endif
 endif
 
diff --git a/readme.binary_protocol_faq b/readme.binary_protocol_faq
new file mode 100644 (file)
index 0000000..c83e0f7
--- /dev/null
@@ -0,0 +1,300 @@
+                    The OpenPegasus Binary Protocol FAQ
+                    ===================================
+
+This FAQ (Frequently Asked Questions) hopefully addresses questions you might
+have about the the OpenPegasus Binary Protocol. If you find your question was
+not addressed, please ask your question on the OpenPegasus mailing list and
+request that the answer be included in this document.
+
+What is the Binary Protocol?
+============================
+
+The binary protocol is a fast protocol for client-server communication. It
+allows local clients to send binary messages to the OpenPegasus server and
+receive binary responses. This protocol is much faster than the default
+XML protocol. When the binary protocol is enabled, local clients use it to
+communicate with the OpenPegasus server. Examples of local clients include:
+(1) out-of-process providers making up-calls, (2) any provider making a local
+connection with the CIMClient class, (2) any local process making a local
+connection with the CIMClient class.
+
+Why use the Binary Protocol?
+============================
+
+The main reason to use the binary protocol is to improve performance of the
+server and clients. Some operations execute as much as 4 times faster with
+the binary protocol.
+
+How big are binary messages?
+============================
+
+Binary messages are slightly larger than XML messages for two reasons: 
+(1) Strings are transmitted using 2-byte characters and (2) Objects are
+aligned on 8-byte boundaries.
+
+What are the basic rules for encoding messages?
+===============================================
+
+The encoding rules were designed for speed rather than size. The basic rules
+are:
+
+    (1) All basic types are aligned on 8-byte boundaries. For example, a uint32
+        starts on an 8-byte boundary and is followed by 4 padding bytes so that
+        the next type is aligned on an 8-byte boundary. This alignment has 2
+        advantages: (1) it allows any basic type to be dereferenced directly in 
+        the buffer without having to relocate it and (2) it is inexpensive to
+        calculate the alignment of the next type.
+
+        There are 2 other data alignment techniques we could have chosen:
+
+            (*) Don't align at all. Just pack types into the buffer end-to-end. 
+                This technique yields smaller messages but sacrifices 
+                performance since types cannot be assigned directly to or 
+                from the data buffer (some operating systems generate data 
+                alignment errors).
+
+            (*) Align types on their "natural boundaries". This means that
+                a type should be aligned on boundaries divisible by its size.
+                For example, a 2-byte integer should be aligned on a 2-byte
+                boundary, or a 4-byte integer should be aligned on a 4-byte
+                boundary. This alignment technique allows types to be directly
+                assigned to or from the data buffer. However, aligning the data
+                buffer for the next type is slightly more expensive since it
+                requires a few extra instructions to compute the alignment
+                boundary than our approach.
+
+    (2) Types are serialized into the message in their native representations.
+        We do not change the representation to either big endian or little 
+        endian. Instead, the recipient of the message is responsible for
+        converting the data into its native representation. If both processes
+        have the same native representation, then the reordering of bytes can
+        be avoided (this is always the case with local processes). This policy
+        has been referred to as "reader makes right". That is, the reader is
+        responsible for making the incoming data into the "right" 
+        representation.
+
+    (3) All arrays are represented by their size followed by their elements.
+        The size is always 4 bytes with 4 extra bytes of padding. In this way,
+        the elements always begin on an 8-byte boundary. The elements are packed
+        end to end with no padding.
+
+    (4) Strings are represented like arrays (size plus elements).
+
+    (5) Boolean are represented as a single byte, either 0 or 1.
+
+    (6) Complex objects that have optional elements or boolean elements, often 
+        employ a single 4-byte bit mask that indicates which flags are true
+        and which elements are present in the network buffer. For example,
+        the CIMProperty representation has a bit mask that indicates whether
+        the property:
+
+            (*) is an array.
+            (*) is propagated.
+            (*) has qualifiers.
+            (*) has a non-empty references class .
+            (*) has a non-empty class origin.
+
+        This save considerable space. For example, if there are no qualifiers,
+        then we save 8 bytes that would be needed to represent an empty 
+        qualifier array.
+
+What is the layout of a binary message?
+=======================================
+
+Binary messages are comprised of a header followed by a body. The header has
+the following elements:
+
+    (1) Magic number - contains 0xF00DFACE.
+    (2) Version number - 1 for the first version.
+    (3) Flags - flags used to represent boolean options of the message.
+    (4) Message ID - same as the message ID in a CIM message.
+    (5) Operation - an integer representing the CIM operation, given as follows:
+
+        (*) Invalid = 1
+        (*) GetClass = 2
+        (*) GetInstance = 3
+        (*) IndicationDelivery = 4 (binary version not implemented)
+        (*) DeleteClass = 5
+        (*) DeleteInstance = 6
+        (*) CreateClass = 7
+        (*) CreateInstance = 8
+        (*) ModifyClass = 9
+        (*) ModifyInstance = 10
+        (*) EnumerateClasses = 11
+        (*) EnumerateClassNames = 12
+        (*) EnumerateInstances = 13
+        (*) EnumerateInstanceNames = 14
+        (*) ExecQuery = 15
+        (*) Associators = 16
+        (*) AssociatorNames = 17
+        (*) References = 18
+        (*) ReferenceNames = 19
+        (*) GetProperty = 20
+        (*) SetProperty = 21
+        (*) GetQualifier = 22
+        (*) SetQualifier = 23
+        (*) DeleteQualifier = 24
+        (*) EnumerateQualifiers = 25
+        (*) InvokeMethod = 26
+
+Does the binary protocol use HTTP?
+==================================
+
+Yes. The binary protocol uses the existing OpenPegasus HTTP infrastructure.
+It preserve the same headers as the conventional protocol.
+
+Does the binary protocol define new HTTP headers?
+=================================================
+
+Yes. It defines two new headers:
+
+    Content-Type: application/x-openpegasus
+    Accept: application/x-openpegasus
+
+The first header is borne by both binary requests and binary responses.
+It indicates that the content (payload) contains an OpenPegasus binary messages.
+
+The second header is sent by a request and indicates that the client can
+handle OpenPegasus binary responses.
+
+The client can combine these headers to achieve 4 different behaviors:
+
+    (1) Binary request/Binary response:
+
+            Content-Type: application/x-openpegasus
+            Accept: application/x-openpegasus
+
+    (2) Binary request/XML response:
+
+            Content-Type: application/x-openpegasus
+
+    (3) XML request/binary response:
+
+            Accept: application/x-openpegasus
+
+    (4) XML request/XML response:
+
+            (omit both headers)
+
+Only 1 and 4 can be achieved without minor code changes to OpenPegasus.
+
+How does protocol versioning work?
+==================================
+
+The binary messages carries a version number in the header. This will be used
+to support backwards compatibility with clients. The server must never be
+modified to send version N+1 messages to version N clients.
+
+Does the binary protocol support remote communication?
+======================================================
+
+Yes, although there is no official SDK interface for enabling it. To enable
+it, one must obtain the CIMClientRep from the CIMClient instance and set
+the following data members to true.
+
+    CIMClientRep::_binaryRequest
+    CIMClientRep::_binaryResponse
+
+The following code fragment shows how one might do this in a program.
+
+    static void _SetBinaryRequest(CIMClient& client, Boolean flag)
+    {
+        CIMClientRep* rep = *(reinterpret_cast<CIMClientRep**>(&client));
+        rep->setBinaryRequest(flag);
+    }
+
+    static void _SetBinaryResponse(CIMClient& client, Boolean flag)
+    {
+        CIMClientRep* rep = *(reinterpret_cast<CIMClientRep**>(&client));
+        rep->setBinaryResponse(flag);
+    }
+
+    ...
+
+    CIMClient client;
+    _SetBinaryRequest(client, true);
+    _SetBinaryResponse(client, true);
+
+    client.connect("localhost", 22000, String(), String());
+
+This forces a remote binary connection.
+
+What is on-demand de-serialization?
+===================================
+
+The binary protocol supports a feature we call "on-demand de-serialization". 
+When using out-of-process providers, data may be de-serialized unnecessarily.
+Consider the following sequence of events.
+
+    (1) The client sends an EnumerateInstances request to the server.
+    (2) The server de-serializes the request.
+    (3) The server serializes the request for the provider agent.
+    (4) The provider agent de-serializes the request.
+    (5) The provider agent obtains response.
+    (6) The provider agent serializes the response for the server.
+    (7) The server de-serializes the request.
+    (8) The server serializes the request for the client.
+    (9) The client de-serializes the request.
+
+The on-demand de-serialization feature eliminates the de-serialization of the
+returned instances, saving them in a data buffer. Then in step 8, the data 
+buffer is sent to the client. This optimization avoids one de-serialization and
+one serialization. For the EnumerateInstances operation, this optimization 
+alone doubles the speed of servicing this operation.
+
+On-demand de-serialization is implemented for the following operations:
+
+    (1) EnumerateInstances
+    (2) GetInstance
+
+Where is the binary encoding/decoding code located?
+===================================================
+
+The source code for encoding and decoding binary requests and responses is
+all included in a single module. The source files are located here:
+
+    pegasus/src/Pegaus/Common/BinaryCodec.h
+    pegasus/src/Pegaus/Common/BinaryCodec.cpp
+
+The source code that implements the encoding of objects themselves is located
+here:
+
+    pegasus/src/Pegaus/Common/CIMBuffer.h
+    pegasus/src/Pegaus/Common/CIMBuffer.cpp
+
+How do you build OpenPegasus with binary protocol support?
+==========================================================
+
+To build OpenPegasus with binary protocol support, define the following
+environment variable first:
+
+    $ export PEGASUS_ENABLE_PROTOCOL_BINARY=true
+
+Are there further improvements that could be made to the protocol?
+==================================================================
+
+Yes, here are a few.
+
+    (1) Excessive copying is required to convert CIMBuffer objects into
+        Buffer objects. CIMBuffer could be reimplemented to use Buffer
+        as its representation. Then it would be possible to "swap" their
+        implementations rather than copying one to the other.
+
+    (2) It might have been better to align objects on their natural boundaries
+        rather than on 8-byte boundaries. This would probably reduce the 
+        message size by 25% or so.
+
+    (3) The on-demand de-serialization should probably be extended to operations
+        other than just GetInstance and EnumerateInstances. For example, the
+        following operations would benefit the most.
+
+            (*) EnumerateInstanceNames
+            (*) ExecQuery
+            (*) Associators
+            (*) AssociatorNames
+            (*) References
+            (*) ReferenceNames
+            (*) InvokeMethod
+
+    (4) The binary protocol should be extended to support the pull-operations
+        whenever they are implemented for XML.
index 4d71942577b49a9944ba1c96b3262d148b22a718..73a9433f9f3a1c306d6e6da7486ae44d7116997e 100644 (file)
@@ -45,6 +45,7 @@ PEGASUS_USING_STD;
 
 PEGASUS_NAMESPACE_BEGIN
 
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 // CIMClientRep
@@ -56,7 +57,9 @@ CIMClientRep::CIMClientRep(Uint32 timeoutMilliseconds)
     MessageQueue(PEGASUS_QUEUENAME_CLIENT),
     _timeoutMilliseconds(timeoutMilliseconds),
     _connected(false),
-    _doReconnect(false)
+    _doReconnect(false),
+    _binaryRequest(false),
+    _binaryResponse(false)
 {
     //
     // Create Monitor and HTTPConnector
@@ -91,7 +94,7 @@ Uint32 _getShowType(String& s)
     return 0;
 }
 
-void CIMClientRep::_connect()
+void CIMClientRep::_connect(bool binaryRequest, bool binaryResponse)
 {
     //
     // Test for Display optons of the form
@@ -157,7 +160,9 @@ void CIMClientRep::_connect()
 
     AutoPtr<CIMOperationRequestEncoder> requestEncoder(
         new CIMOperationRequestEncoder(
-            httpConnection.get(), connectHost, &_authenticator, showOutput));
+            httpConnection.get(), connectHost, &_authenticator, showOutput,
+            binaryRequest,
+            binaryResponse));
 
     _responseDecoder.reset(responseDecoder.release());
     _httpConnection = httpConnection.release();
@@ -170,6 +175,8 @@ void CIMClientRep::_connect()
 
     _doReconnect = false;
     _connected = true;
+    _binaryRequest = binaryRequest;
+    _binaryResponse = binaryResponse;
     _httpConnection->setSocketWriteTimeout(_timeoutMilliseconds/1000+1);
 }
 
@@ -247,8 +254,7 @@ void CIMClientRep::connect(
     _connectSSLContext.reset();
     _connectHost = hostName;
     _connectPortNumber = portNumber;
-
-    _connect();
+    _connect(_binaryRequest, _binaryResponse);
 }
 
 
@@ -293,12 +299,20 @@ void CIMClientRep::connect(
     _connectPortNumber = portNumber;
 
     _connectSSLContext.reset(new SSLContext(sslContext));
-    _connect();
+    _connect(_binaryRequest, _binaryResponse);
 }
 
 
 void CIMClientRep::connectLocal()
 {
+#if defined(PEGASUS_ENABLE_PROTOCOL_BINARY)
+    bool binaryRequest = true;
+    bool binaryResponse = true;
+#else
+    bool binaryRequest = false;
+    bool binaryResponse = false;
+#endif
+
     //
     // If already connected, bail out!
     //
@@ -315,7 +329,7 @@ void CIMClientRep::connectLocal()
     _connectSSLContext.reset();
     _connectHost = String::EMPTY;
     _connectPortNumber = 0;
-    _connect();
+    _connect(binaryRequest, binaryResponse);
 #else
 
     try
@@ -333,7 +347,7 @@ void CIMClientRep::connectLocal()
 
         _connectSSLContext.reset();
 
-        _connect();
+        _connect(binaryRequest, binaryResponse);
     }
     catch (const CannotConnectException &)
     {
@@ -364,7 +378,7 @@ void CIMClientRep::connectLocal()
         _connectSSLContext.reset(
             new SSLContext(String::EMPTY, NULL, randFile));
 
-        _connect();
+        _connect(binaryRequest, binaryResponse);
     }
 #endif
 }
@@ -1003,7 +1017,7 @@ Message* CIMClientRep::_doRequest(
 
     if (_doReconnect)
     {
-        _connect();
+        _connect(_binaryRequest, _binaryResponse);
         _doReconnect = false;
     }
 
@@ -1205,7 +1219,7 @@ Message* CIMClientRep::_doRequest(
                 //
                 if (_doReconnect)
                 {
-                    _connect();
+                    _connect(_binaryRequest, _binaryResponse);
                 }
 
                 _requestEncoder->enqueue(response.release());
index 0d3ab15cca489dd6ec1f311b5b542fd0b0336226..dfe9de71c6d4629affc4e637fb46698dbd06023e 100644 (file)
@@ -295,9 +295,13 @@ public:
 
     void deregisterClientOpPerformanceDataHandler();
 
+    void setBinaryResponse(bool x) { _binaryResponse = x; }
+
+    void setBinaryRequest(bool x) { _binaryRequest = x; }
+
 private:
 
-    void _connect();
+    void _connect(bool binaryRequest, bool binaryResponse);
     void _disconnect();
 
     Message* _doRequest(
@@ -334,6 +338,8 @@ private:
     AcceptLanguageList requestAcceptLanguages;
     ContentLanguageList requestContentLanguages;
     ContentLanguageList responseContentLanguages;
+    bool _binaryRequest;
+    bool _binaryResponse;
 };
 
 PEGASUS_NAMESPACE_END
index 446fa326c033b0e654560724a0257d4b4e514e3e..dd039b554f6305c00d56a9132953b7a445bf9844 100644 (file)
@@ -32,6 +32,7 @@
 //%/////////////////////////////////////////////////////////////////////////////
 
 #include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/BinaryCodec.h>
 #include <iostream>
 #include <Pegasus/Common/Constants.h>
 #include <Pegasus/Common/XmlWriter.h>
@@ -47,13 +48,17 @@ CIMOperationRequestEncoder::CIMOperationRequestEncoder(
     MessageQueue* outputQueue,
     const String& hostName,
     ClientAuthenticator* authenticator,
-    Uint32 showOutput)
+    Uint32 showOutput,
+    bool binaryRequest,
+    bool binaryResponse)
     :
     MessageQueue(PEGASUS_QUEUENAME_OPREQENCODER),
     _outputQueue(outputQueue),
     _hostName(hostName.getCString()),
     _authenticator(authenticator),
-    _showOutput(showOutput)
+    _showOutput(showOutput),
+    _binaryRequest(binaryRequest),
+    _binaryResponse(binaryResponse)
 {
     dataStore_prt=NULL;
 }
@@ -71,6 +76,34 @@ void CIMOperationRequestEncoder::handleEnqueue()
 
     _authenticator->setRequestMessage(message);
 
+    //
+    // Encode request as binary request.
+    //
+
+    if (_binaryRequest)
+    {
+        CIMOperationRequestMessage* msg = 
+            dynamic_cast<CIMOperationRequestMessage*>(message);
+
+        if (msg)
+        {
+            Buffer buf;
+
+            if (BinaryCodec::encodeRequest(buf, _hostName, 
+                _authenticator->buildRequestAuthHeader(), msg, _binaryResponse))
+            {
+                _sendRequest(buf);
+                return;
+            }
+
+            // Drop through and encode as an XML request below.
+        }
+    }
+
+    //
+    // Encode request as an XML request.
+    //
+
     switch (message->getType())
     {
         case CIM_CREATE_CLASS_REQUEST_MESSAGE:
@@ -226,7 +259,7 @@ void CIMOperationRequestEncoder::_encodeCreateClassRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
     _sendRequest(buffer);
 }
 
@@ -259,7 +292,7 @@ void CIMOperationRequestEncoder::_encodeGetClassRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -280,7 +313,7 @@ void CIMOperationRequestEncoder::_encodeModifyClassRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -305,7 +338,7 @@ void CIMOperationRequestEncoder::_encodeEnumerateClassNamesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -341,7 +374,7 @@ void CIMOperationRequestEncoder::_encodeEnumerateClassesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -363,7 +396,7 @@ void CIMOperationRequestEncoder::_encodeDeleteClassRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -384,7 +417,7 @@ void CIMOperationRequestEncoder::_encodeCreateInstanceRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -421,7 +454,7 @@ void CIMOperationRequestEncoder::_encodeGetInstanceRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -449,7 +482,7 @@ void CIMOperationRequestEncoder::_encodeModifyInstanceRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -471,7 +504,7 @@ void CIMOperationRequestEncoder::_encodeEnumerateInstanceNamesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -510,7 +543,7 @@ void CIMOperationRequestEncoder::_encodeEnumerateInstancesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -531,7 +564,7 @@ void CIMOperationRequestEncoder::_encodeDeleteInstanceRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -555,7 +588,7 @@ void CIMOperationRequestEncoder::_encodeGetPropertyRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -583,7 +616,7 @@ void CIMOperationRequestEncoder::_encodeSetPropertyRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -603,7 +636,7 @@ void CIMOperationRequestEncoder::_encodeSetQualifierRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -625,7 +658,7 @@ void CIMOperationRequestEncoder::_encodeGetQualifierRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -643,7 +676,7 @@ void CIMOperationRequestEncoder::_encodeEnumerateQualifiersRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -665,7 +698,7 @@ void CIMOperationRequestEncoder::_encodeDeleteQualifierRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -699,7 +732,7 @@ void CIMOperationRequestEncoder::_encodeReferenceNamesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -743,7 +776,7 @@ void CIMOperationRequestEncoder::_encodeReferencesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -790,7 +823,7 @@ void CIMOperationRequestEncoder::_encodeAssociatorNamesRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -847,7 +880,7 @@ void CIMOperationRequestEncoder::_encodeAssociatorsRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -871,7 +904,7 @@ void CIMOperationRequestEncoder::_encodeExecQueryRequest(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
             ContentLanguageListContainer::NAME)).getLanguages(),
-        params);
+        params, _binaryResponse);
 
     _sendRequest(buffer);
 }
@@ -886,7 +919,8 @@ void CIMOperationRequestEncoder::_encodeInvokeMethodRequest(
         ((AcceptLanguageListContainer)message->operationContext.get(
             AcceptLanguageListContainer::NAME)).getLanguages(),
         ((ContentLanguageListContainer)message->operationContext.get(
-            ContentLanguageListContainer::NAME)).getLanguages());
+            ContentLanguageListContainer::NAME)).getLanguages(), 
+        _binaryResponse);
 
     _sendRequest(buffer);
 }
index 09f4ef52e68d4fb122386a2dd155428323907c1a..85c8f6ad5ebc2d7aab3c18a34cef83b5614a9a49 100644 (file)
@@ -60,7 +60,9 @@ public:
         MessageQueue* outputQueue,
         const String& hostName,
         ClientAuthenticator* authenticator,
-        Uint32 showOutput);
+        Uint32 showOutput,
+        bool binaryRequest = false,
+        bool binaryResponse = false);
 
     /** Destructor. */
     ~CIMOperationRequestEncoder();
@@ -157,6 +159,8 @@ private:
     // Controls client trace output. 1 = con, 2 == log
     Uint32 _showOutput;
     ClientPerfDataStore* dataStore_prt;
+    bool _binaryRequest;
+    bool _binaryResponse;
 };
 
 PEGASUS_NAMESPACE_END
index e89182d94275d8ca360c8c264774d557f3e868f5..5b481df429eab4f8cefe9baf5d84935ab6e5765f 100644 (file)
@@ -41,6 +41,7 @@
 #include <Pegasus/Common/HTTPMessage.h>
 #include <Pegasus/Common/CIMMessage.h>
 #include <Pegasus/Common/Exception.h>
+#include <Pegasus/Common/BinaryCodec.h>
 #include "CIMOperationResponseDecoder.h"
 
 #include <Pegasus/Common/MessageLoader.h>
@@ -308,6 +309,7 @@ void CIMOperationResponseDecoder::_handleHTTPMessage(HTTPMessage* httpMessage)
     //              type "/" subtype *( ";" parameter )
     // ex. text/xml;Charset="utf8"
     String cimContentType;
+    bool binaryResponse = false;
 
     if (HTTPMessage::lookupHeader(
             headers, "Content-Type", cimContentType, true))
@@ -317,9 +319,14 @@ void CIMOperationResponseDecoder::_handleHTTPMessage(HTTPMessage* httpMessage)
 
         if (!HTTPMessage::parseContentTypeHeader(
                 cimContentType, type, charset) ||
-            (!String::equalNoCase(type, "application/xml") &&
+            ((!String::equalNoCase(type, "application/xml") &&
              !String::equalNoCase(type, "text/xml")) ||
             !String::equalNoCase(charset, "utf-8"))
+#if defined(PEGASUS_ENABLE_PROTOCOL_BINARY)
+            && !(binaryResponse=String::equalNoCase(
+                type, "application/x-openpegasus"))
+#endif
+        )
         {
             CIMClientMalformedHTTPException* malformedHTTPException = new
                 CIMClientMalformedHTTPException
@@ -431,16 +438,39 @@ void CIMOperationResponseDecoder::_handleHTTPMessage(HTTPMessage* httpMessage)
 
     dataStore->setResponseSize(contentLength);
     dataStore->setEndNetworkTime(networkEndTime);
-    _handleMethodResponse(content, httpMessage->contentLanguages,cimReconnect);
+    _handleMethodResponse(content, contentLength, 
+        httpMessage->contentLanguages, cimReconnect, binaryResponse);
 }
 
 void CIMOperationResponseDecoder::_handleMethodResponse(
     char* content,
+    Uint32 contentLength,
     const ContentLanguageList& contentLanguages,
-    Boolean cimReconnect)
+    Boolean cimReconnect,
+    Boolean binaryResponse)
 {
     Message* response = 0;
 
+    //
+    // Decode binary messages up-front and skip remainder:
+    //
+
+    if (binaryResponse)
+    {
+        // Note: this may throw an excpetion which will be caught by caller.
+
+        Buffer in(content, contentLength);
+
+        CIMResponseMessage* msg = BinaryCodec::decodeResponse(in);
+
+        msg->operationContext.set(
+            ContentLanguageListContainer(contentLanguages));
+        msg->setCloseConnect(cimReconnect);
+        _outputQueue->enqueue(msg);
+
+        return;
+    }
+
     //
     // Create and initialize XML parser:
     //
index dd0e3aab875f813ab6d0eca017e4ea7631c42c36..4ab308231c3ebf34220fe3bb0b70ffa9ca400461 100644 (file)
@@ -106,8 +106,10 @@ private:
 
     void _handleMethodResponse(
         char* content,
+        Uint32 contentLength,
         const ContentLanguageList& contentLanguages,
-        Boolean reconnect);
+        Boolean reconnect,
+        bool binaryResponse);
 
     CIMCreateClassResponseMessage* _decodeCreateClassResponse(
         XmlParser& parser,
diff --git a/src/Pegasus/Client/tests/BinaryClient/BinaryClient.cpp b/src/Pegasus/Client/tests/BinaryClient/BinaryClient.cpp
new file mode 100644 (file)
index 0000000..30702c8
--- /dev/null
@@ -0,0 +1,107 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <cstdlib>
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/Print.h>
+#include <Pegasus/Client/CIMClient.h>
+#include <Pegasus/Client/CIMClientRep.h>
+
+PEGASUS_USING_STD;
+PEGASUS_USING_PEGASUS;
+
+//==============================================================================
+//
+// TestBinaryClient host port
+//
+//     This program enumerates instances of CIM_ManagedElement using the
+//     OpenPegasus binary protocol.
+//
+//==============================================================================
+
+static void _SetBinaryResponse(CIMClient& client, Boolean flag)
+{
+    CIMClientRep* rep = *(reinterpret_cast<CIMClientRep**>(&client));
+    rep->setBinaryResponse(flag);
+}
+
+int main(int argc, char** argv)
+{
+    // Check args:
+
+    if (argc != 3)
+    {
+        cerr << "Usage: " << argv[0] << " host port" << endl;
+        exit(1);
+    }
+
+    // Extract args:
+
+    String host = argv[1];
+    Uint32 port = atoi(argv[2]);
+
+    if (port == 0)
+    {
+        cerr << argv[0] << ": illegal value for port number" << endl;
+        exit(1);
+    }
+
+    // Connect and enumerate instances.
+
+    CIMClient client;
+    _SetBinaryResponse(client, true);
+
+    try
+    {
+        client.connect(host, port, String(), String());
+
+        Array<CIMInstance> result = client.enumerateInstances("root/cimv2",
+            "CIM_ManagedElement");
+
+        for (Uint32 i = 0; i < result.size(); i++)
+        {
+#if defined(PEGASUS_DEBUG)
+            PrintInstance(cout, result[i]);
+#endif
+        }
+    }
+    catch (Exception& e)
+    {
+        cerr << e.getMessage() << endl;
+        exit(1);
+    }
+
+    cout << "TestBinaryClient +++++ passed all tests" << endl;
+
+    return 0;
+}
diff --git a/src/Pegasus/Client/tests/BinaryClient/Makefile b/src/Pegasus/Client/tests/BinaryClient/Makefile
new file mode 100644 (file)
index 0000000..3c59f1a
--- /dev/null
@@ -0,0 +1,47 @@
+#//%2006////////////////////////////////////////////////////////////////////////
+#//
+#// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+#// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+#// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+#// IBM Corp.; EMC Corporation, The Open Group.
+#// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+#// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+#// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+#// EMC Corporation; VERITAS Software Corporation; The Open Group.
+#// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+#// EMC Corporation; Symantec Corporation; The Open Group.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a copy
+#// of this software and associated documentation files (the "Software"), to
+#// deal in the Software without restriction, including without limitation the
+#// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+#// sell copies of the Software, and to permit persons to whom the Software is
+#// furnished to do so, subject to the following conditions:
+#// 
+#// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+#// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+#// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+#// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+#// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+#// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+#// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//==============================================================================
+ROOT = $(PEGASUS_ROOT)
+DIR = Pegasus/Client/tests/BinaryClient
+include $(ROOT)/mak/config.mak
+include ../libraries.mak
+
+EXTRA_INCLUDES = $(SYS_INCLUDES)
+
+LOCAL_DEFINES = -DPEGASUS_INTERNALONLY
+
+PROGRAM = TestBinaryClient
+SOURCES = BinaryClient.cpp
+
+include $(ROOT)/mak/program.mak
+
+tests:
+
+poststarttests:        
index 180baaff9dd5f6a4857524cfc526c97439ea6fe6..0ad50f24a06f9736db1eb9e6f6a94415dc0b3db2 100644 (file)
@@ -39,7 +39,8 @@ DIRS =        AssociationClient \
        EnumInstances \
        DeleteNamespace \
        ClientStatistics \
-       TestStaticClient
+       TestStaticClient \
+        BinaryClient
 
 DIRS_SLP = \
     slp
diff --git a/src/Pegasus/Client/tests/Print/Makefile b/src/Pegasus/Client/tests/Print/Makefile
new file mode 100644 (file)
index 0000000..a57e2fe
--- /dev/null
@@ -0,0 +1,46 @@
+#//%2006////////////////////////////////////////////////////////////////////////
+#//
+#// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+#// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+#// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+#// IBM Corp.; EMC Corporation, The Open Group.
+#// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+#// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+#// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+#// EMC Corporation; VERITAS Software Corporation; The Open Group.
+#// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+#// EMC Corporation; Symantec Corporation; The Open Group.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a copy
+#// of this software and associated documentation files (the "Software"), to
+#// deal in the Software without restriction, including without limitation the
+#// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+#// sell copies of the Software, and to permit persons to whom the Software is
+#// furnished to do so, subject to the following conditions:
+#// 
+#// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+#// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+#// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+#// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+#// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+#// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+#// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//==============================================================================
+ROOT = ../../../../..
+DIR = Pegasus/Common/tests/Print
+include $(ROOT)/mak/config.mak
+include ../libraries.mak
+
+LOCAL_DEFINES = -DPEGASUS_INTERNALONLY
+
+PROGRAM = TestPrint
+SOURCES = TestPrint.cpp
+
+include $(ROOT)/mak/program.mak
+
+tests:
+       $(PROGRAM)
+
+poststarttests:
diff --git a/src/Pegasus/Client/tests/Print/TestPrint.cpp b/src/Pegasus/Client/tests/Print/TestPrint.cpp
new file mode 100644 (file)
index 0000000..88690cd
--- /dev/null
@@ -0,0 +1,112 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/PegasusAssert.h>
+#include <Pegasus/Client/CIMClient.h>
+#include <Pegasus/Common/Print.h>
+#include <iostream>
+
+PEGASUS_USING_PEGASUS;
+PEGASUS_USING_STD;
+
+static Boolean verbose;
+
+//==============================================================================
+//
+// This program obtains instances of the given class when invoked as follows:
+//
+//     $ TestPrint <CLASSNAME>
+//
+// It connects locally to the CIM server, enumerates instances of that class 
+// and then prints each one.
+//
+//==============================================================================
+
+int main(int argc, char** argv)
+{
+    // Check usage:
+
+    if (argc != 2)
+    {
+        cerr << "Usage: " << argv[0] << " classname" << endl;
+        exit(1);
+    }
+
+    // Check classname argument:
+
+    CIMName name;
+
+    try
+    {
+        name = argv[1];
+    }
+    catch (...)
+    {
+        cerr << argv[0] << ": illegal CIM classname: " << argv[1] << endl;
+        exit(1);
+    }
+
+
+    // Connect:
+
+    CIMClient cc;
+
+    try
+    {
+        cc.connectLocal();
+    }
+    catch (...)
+    {
+        cerr << "failed to connect" << endl;
+        exit(1);
+    }
+
+    // Enumerate and print:
+
+    try
+    {
+        Array<CIMInstance> a = cc.enumerateInstances("root/cimv2", name);
+
+        for (Uint32 i = 0; i < a.size(); i++)
+        {
+            PrintInstance(cout, a[i]);
+        }
+    }
+    catch (...)
+    {
+        cerr << "failed to enumerate instances of " << name.getString() << endl;
+        exit(1);
+    }
+
+    return 0;
+}
index 502b50b7da22f9bc6d7a7d68ce8fba964bb5104e..bae0527aa39666c886b78a30071c11c435a5a913 100644 (file)
@@ -31,7 +31,7 @@
 //
 //%////////////////////////////////////////////////////////////////////////////
 
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
 # include <Pegasus/Common/CIMBinMsgSerializer.h>
 # include <Pegasus/Common/CIMBinMsgDeserializer.h>
 #else
@@ -66,7 +66,7 @@ AnonymousPipe::Status AnonymousPipe::writeMessage (CIMMessage * message)
     //
     // Serialize the request
     //
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
     CIMBuffer messageBuffer(4096);
 #else
     Buffer messageBuffer;
@@ -75,7 +75,7 @@ AnonymousPipe::Status AnonymousPipe::writeMessage (CIMMessage * message)
 
     try
     {
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
         CIMBinMsgSerializer::serialize(messageBuffer, message);
 #else
         CIMMessageSerializer::serialize (messageBuffer, message);
@@ -138,7 +138,7 @@ AnonymousPipe::Status AnonymousPipe::readMessage (CIMMessage * & message)
     //
     //  Read the message data
     //
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
     // CIMBuffer uses realloc() and free() so the buffer must be allocated
     // with malloc().
     AutoPtr<char, FreeCharPtr> messageBuffer((char*)malloc(messageLength + 1));
@@ -166,7 +166,7 @@ AnonymousPipe::Status AnonymousPipe::readMessage (CIMMessage * & message)
         //
         //  De-serialize the message
         //
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
         // CIMBuffer frees messageBuffer upon destruction.
         CIMBuffer buf(messageBuffer.release(), messageLength);
         message = CIMBinMsgDeserializer::deserialize(buf, messageLength);
diff --git a/src/Pegasus/Common/BinaryCodec.cpp b/src/Pegasus/Common/BinaryCodec.cpp
new file mode 100644 (file)
index 0000000..4c3f98d
--- /dev/null
@@ -0,0 +1,3878 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/StatisticalData.h>
+#include "XmlWriter.h"
+#include "BinaryCodec.h"
+#include "CIMBuffer.h"
+#include "StringConversion.h"
+#include "Print.h"
+
+#define ENABLE_VALIDATION
+
+#if defined(_EQUAL)
+# undef _EQUAL
+#endif
+
+#define _EQUAL(X, Y) (X.size() == (sizeof(Y)-1) && String::equalNoCase(X, Y))
+
+// Header flags:
+#define LOCAL_ONLY              (1 << 0)
+#define INCLUDE_QUALIFIERS      (1 << 1)
+#define INCLUDE_CLASS_ORIGIN    (1 << 2)
+#define DEEP_INHERITANCE        (1 << 3)
+
+PEGASUS_NAMESPACE_BEGIN
+
+//==============================================================================
+//
+// Local definitions:
+//
+//==============================================================================
+
+static const Uint32 _MAGIC = 0xF00DFACE;
+static const Uint32 _REVERSE_MAGIC = 0xCEFA0DF0;
+static const Uint32 _VERSION = 1;
+static const size_t _DEFAULT_CIM_BUFFER_SIZE = 16*1024;
+
+enum Operation
+{
+    OP_Invalid,
+    OP_GetClass,
+    OP_GetInstance,
+    OP_IndicationDelivery,
+    OP_DeleteClass,
+    OP_DeleteInstance,
+    OP_CreateClass,
+    OP_CreateInstance,
+    OP_ModifyClass,
+    OP_ModifyInstance,
+    OP_EnumerateClasses,
+    OP_EnumerateClassNames,
+    OP_EnumerateInstances,
+    OP_EnumerateInstanceNames,
+    OP_ExecQuery,
+    OP_Associators,
+    OP_AssociatorNames,
+    OP_References,
+    OP_ReferenceNames,
+    OP_GetProperty,
+    OP_SetProperty,
+    OP_GetQualifier,
+    OP_SetQualifier,
+    OP_DeleteQualifier,
+    OP_EnumerateQualifiers,
+    OP_InvokeMethod,
+    OP_Count,
+};
+
+struct CIMBufferReleaser
+{
+    CIMBufferReleaser(CIMBuffer& buf) : _buf(buf)
+    {
+    }
+
+    ~CIMBufferReleaser()
+    {
+        _buf.release();
+    }
+
+private:
+    CIMBuffer& _buf;
+};
+
+static Operation _NameToOp(const CIMName& name)
+{
+    const String& s = name.getString();
+
+    switch (s[0])
+    {
+        case 'A':
+            if (_EQUAL(s, "Associators"))
+                return OP_Associators;
+            if (_EQUAL(s, "AssociatorNames"))
+                return OP_AssociatorNames;
+            break;
+        case 'C':
+            if (_EQUAL(s, "CreateInstance"))
+                return OP_CreateInstance;
+            if (_EQUAL(s, "CreateClass"))
+                return OP_CreateClass;
+            break;
+        case 'D':
+            if (_EQUAL(s, "DeleteInstance"))
+                return OP_DeleteInstance;
+            if (_EQUAL(s, "DeleteClass"))
+                return OP_DeleteClass;
+            if (_EQUAL(s, "DeleteQualifier"))
+                return OP_DeleteQualifier;
+            break;
+        case 'E':
+            if (_EQUAL(s, "EnumerateInstances"))
+                return OP_EnumerateInstances;
+            if (_EQUAL(s, "EnumerateInstanceNames"))
+                return OP_EnumerateInstanceNames;
+            if (_EQUAL(s, "ExecQuery"))
+                return OP_ExecQuery;
+            if (_EQUAL(s, "EnumerateClassNames"))
+                return OP_EnumerateClassNames;
+            if (_EQUAL(s, "EnumerateClasses"))
+                return OP_EnumerateClasses;
+            if (_EQUAL(s, "EnumerateQualifiers"))
+                return OP_EnumerateQualifiers;
+            break;
+        case 'G':
+            if (_EQUAL(s, "GetInstance"))
+                return OP_GetInstance;
+            if (_EQUAL(s, "GetClass"))
+                return OP_GetClass;
+            if (_EQUAL(s, "GetQualifier"))
+                return OP_GetQualifier;
+            if (_EQUAL(s, "GetProperty"))
+                return OP_GetProperty;
+            break;
+        case 'I':
+            if (_EQUAL(s, "InvokeMethod"))
+                return OP_InvokeMethod;
+            if (_EQUAL(s, "IndicationDelivery"))
+                return OP_IndicationDelivery;
+            break;
+        case 'M':
+            if (_EQUAL(s, "ModifyInstance"))
+                return OP_ModifyInstance;
+            if (_EQUAL(s, "ModifyClass"))
+                return OP_ModifyClass;
+            break;
+        case 'R':
+            if (_EQUAL(s, "References"))
+                return OP_References;
+            if (_EQUAL(s, "ReferenceNames"))
+                return OP_ReferenceNames;
+            break;
+        case 'S':
+            if (_EQUAL(s, "SetQualifier"))
+                return OP_SetQualifier;
+            if (_EQUAL(s, "SetProperty"))
+                return OP_SetProperty;
+            break;
+    }
+
+    // Unknown, se we will assume it is an extrinsic method!
+    return OP_InvokeMethod;
+}
+
+static void _putHeader(
+    CIMBuffer& out,
+    Uint32 flags,
+    const String& messageId,
+    Operation operation)
+{
+    // [MAGIC]
+    out.putUint32(_MAGIC);
+
+    // [VERSION]
+    out.putUint32(_VERSION);
+
+    // [FLAGS]
+    out.putUint32(flags);
+
+    // [MESSAGEID]
+    out.putString(messageId);
+
+    // [OPERATION]
+    out.putUint32(operation);
+}
+
+static bool _getHeader(
+    CIMBuffer& in,
+    Uint32& flags,
+    String& messageId,
+    Operation& operation_)
+{
+    Uint32 magic;
+    Uint32 version;
+
+    // [MAGIC]
+    if (!in.getUint32(magic))
+        return false;
+
+    if (magic != _MAGIC)
+    {
+        if (magic != _REVERSE_MAGIC)
+            return false;
+
+        // Sender has opposite endianess so turn on endian swapping:
+        in.setSwap(true);
+    }
+
+    // [VERSION]
+    if (!in.getUint32(version) || version != _VERSION)
+        return false;
+
+    // [FLAGS]
+    if (!in.getUint32(flags))
+        return false;
+
+    // [MESSAGEID]
+    if (!in.getString(messageId))
+        return false;
+
+    // [OPERATION]
+    {
+        Uint32 op;
+
+        if (!in.getUint32(op) || op == OP_Invalid || op >= OP_Count)
+            return false;
+
+        operation_ = Operation(op);
+    }
+
+    return true;
+}
+
+//==============================================================================
+//
+// EnumerateInstances
+//
+//==============================================================================
+
+static void _encodeEnumerateInstancesRequest(
+    CIMBuffer& buf,
+    CIMEnumerateInstancesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("EnumerateInstances");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->localOnly)
+        flags |= LOCAL_ONLY;
+
+    if (msg->deepInheritance)
+        flags |= DEEP_INHERITANCE;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_EnumerateInstances);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static CIMEnumerateInstancesRequestMessage* _decodeEnumerateInstancesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean deepInheritance = flags & DEEP_INHERITANCE;
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    // [PROPERTY-LIST]
+    CIMPropertyList propertyList;
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMEnumerateInstancesRequestMessage> request(
+        new CIMEnumerateInstancesRequestMessage(
+            messageId,
+            nameSpace,
+            className,
+            deepInheritance,
+            false,    // Bug 1985 localOnly is deprecated
+#ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
+            false,
+#else
+            includeQualifiers,
+#endif
+            includeClassOrigin,
+            propertyList,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeEnumerateInstancesResponseBody(
+    CIMBuffer& out,
+    CIMEnumerateInstancesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("EnumerateInstances");
+    name = NAME;
+
+    if (msg->resolveCallback && msg->binaryEncoding)
+    {
+        const Array<Uint8>& data = msg->binaryData;
+        out.putBytes((char*)data.getData(), data.size());
+    }
+    else
+    {
+        out.putInstanceA(msg->getNamedInstances(), false);
+    }
+}
+
+static CIMEnumerateInstancesResponseMessage* _decodeEnumerateInstancesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMInstance> instances;
+
+    while (in.more())
+    {
+        Array<CIMInstance> tmp;
+
+        if (!in.getInstanceA(tmp))
+            return 0;
+
+        instances.append(tmp.getData(), tmp.size());
+    }
+
+    CIMEnumerateInstancesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMEnumerateInstancesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->setNamedInstances(instances);
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// EnumerateInstanceNames
+//
+//==============================================================================
+
+static CIMEnumerateInstanceNamesRequestMessage* 
+_decodeEnumerateInstanceNamesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    AutoPtr<CIMEnumerateInstanceNamesRequestMessage> request(
+        new CIMEnumerateInstanceNamesRequestMessage(
+            messageId,
+            nameSpace,
+            className,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static CIMEnumerateInstanceNamesResponseMessage* 
+_decodeEnumerateInstanceNamesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    Array<CIMObjectPath> instanceNames;
+
+    while (in.more())
+    {
+        Array<CIMObjectPath> tmp;
+
+        if (!in.getObjectPathA(tmp))
+            return 0;
+
+        instanceNames.append(tmp.getData(), tmp.size());
+    }
+
+    CIMEnumerateInstanceNamesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMEnumerateInstanceNamesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        instanceNames);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+static void _encodeEnumerateInstanceNamesRequest(
+    CIMBuffer& buf,
+    CIMEnumerateInstanceNamesRequestMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("EnumerateInstanceNames");
+    name = NAME;
+
+    // [HEADER]
+
+    _putHeader(buf, 0, msg->messageId, OP_EnumerateInstanceNames);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+}
+
+static void _encodeEnumerateInstanceNamesResponseBody(
+    CIMBuffer& out,
+    CIMEnumerateInstanceNamesResponseMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("EnumerateInstanceNames");
+    name = NAME;
+
+    out.putObjectPathA(msg->instanceNames, false);
+}
+
+//==============================================================================
+//
+// GetInstance
+//
+//==============================================================================
+
+static CIMGetInstanceRequestMessage* _decodeGetInstanceRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    STAT_GETSTARTTIME
+
+    // [FLAGS]
+
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [INSTANCE-NAME]
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    // [PROPERTY-LIST]
+    CIMPropertyList propertyList;
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMGetInstanceRequestMessage> request(
+        new CIMGetInstanceRequestMessage(
+            messageId,
+            nameSpace,
+            instanceName,
+            false,    // Bug 1985 localOnly is deprecated
+#ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
+            false,
+#else
+            includeQualifiers,
+#endif
+            includeClassOrigin,
+            propertyList,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static CIMGetInstanceResponseMessage* _decodeGetInstanceResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    CIMInstance instance;
+
+    if (!in.getInstance(instance))
+        return 0;
+
+    CIMGetInstanceResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMGetInstanceResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->setCimInstance(instance);
+    msg->binaryRequest = true;
+    return msg;
+}
+
+static void _encodeGetInstanceRequest(
+    CIMBuffer& buf,
+    CIMGetInstanceRequestMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("GetInstance");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->localOnly)
+        flags |= LOCAL_ONLY;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_GetInstance);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [INSTANCE-NAME]
+    buf.putObjectPath(msg->instanceName);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static void _encodeGetInstanceResponseBody(
+    CIMBuffer& out,
+    CIMGetInstanceResponseMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("GetInstance");
+    name = NAME;
+
+    if (msg->resolveCallback && msg->binaryEncoding)
+    {
+        const Array<Uint8>& data = msg->binaryData;
+        out.putBytes((char*)data.getData(), data.size());
+    }
+    else
+    {
+        out.putInstance(msg->getCimInstance(), false, false);
+    }
+}
+
+//==============================================================================
+//
+// CreateInstance
+//
+//==============================================================================
+
+static void _encodeCreateInstanceRequest(
+    CIMBuffer& buf,
+    CIMCreateInstanceRequestMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("CreateInstance");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_CreateInstance);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [NEW-INSTANCE]
+    buf.putInstance(msg->newInstance, false);
+}
+
+static CIMCreateInstanceRequestMessage* _decodeCreateInstanceRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [NEW-INSTANCE]
+
+    CIMInstance newInstance;
+
+    if (!in.getInstance(newInstance))
+        return 0;
+
+    AutoPtr<CIMCreateInstanceRequestMessage> request(
+        new CIMCreateInstanceRequestMessage(
+            messageId,
+            nameSpace,
+            newInstance,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeCreateInstanceResponseBody(
+    CIMBuffer& out,
+    CIMCreateInstanceResponseMessage* msg,
+    CIMName& name)
+{
+    static const CIMName NAME("CreateInstance");
+    name = NAME;
+
+    out.putObjectPath(msg->instanceName, false);
+}
+
+static CIMCreateInstanceResponseMessage* _decodeCreateInstanceResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    CIMCreateInstanceResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMCreateInstanceResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        instanceName);
+
+    msg->binaryRequest = true;
+
+    return msg;
+}
+
+//==============================================================================
+//
+// ModifyInstance
+//
+//==============================================================================
+
+static void _encodeModifyInstanceRequest(
+    CIMBuffer& buf,
+    CIMModifyInstanceRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("ModifyInstance");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    _putHeader(buf, flags, msg->messageId, OP_ModifyInstance);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [MODIFIED-INSTANCE]
+    buf.putInstance(msg->modifiedInstance, false);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static CIMModifyInstanceRequestMessage* _decodeModifyInstanceRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [MODIFIED-INSTANCE]
+    CIMInstance modifiedInstance;
+
+    if (!in.getInstance(modifiedInstance))
+        return 0;
+
+    // [PROPERTY-LIST]
+    CIMPropertyList propertyList;
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMModifyInstanceRequestMessage> request(
+        new CIMModifyInstanceRequestMessage(
+            messageId,
+            nameSpace,
+            modifiedInstance,
+            includeQualifiers,
+            propertyList,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeModifyInstanceResponseBody(
+    CIMBuffer& out,
+    CIMModifyInstanceResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("ModifyInstance");
+    name = NAME;
+}
+
+static CIMModifyInstanceResponseMessage* _decodeModifyInstanceResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMInstance> instances;
+
+    while (in.more())
+    {
+        Array<CIMInstance> tmp;
+
+        if (!in.getInstanceA(tmp))
+            return 0;
+
+        instances.append(tmp.getData(), tmp.size());
+    }
+
+    CIMModifyInstanceResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMModifyInstanceResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// DeleteInstance
+//
+//==============================================================================
+
+static void _encodeDeleteInstanceRequest(
+    CIMBuffer& buf,
+    CIMDeleteInstanceRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("DeleteInstance");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_DeleteInstance);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [INSTANCE-NAME]
+    buf.putObjectPath(msg->instanceName, false);
+}
+
+static CIMDeleteInstanceRequestMessage* _decodeDeleteInstanceRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [INSTANCE-NAME]
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    AutoPtr<CIMDeleteInstanceRequestMessage> request(
+        new CIMDeleteInstanceRequestMessage(
+            messageId,
+            nameSpace,
+            instanceName,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeDeleteInstanceResponseBody(
+    CIMBuffer& out,
+    CIMDeleteInstanceResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("DeleteInstance");
+    name = NAME;
+}
+
+static CIMDeleteInstanceResponseMessage* _decodeDeleteInstanceResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMDeleteInstanceResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMDeleteInstanceResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// Associators
+//
+//==============================================================================
+
+static void _encodeAssociatorsRequest(
+    CIMBuffer& buf,
+    CIMAssociatorsRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("Associators");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_Associators);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [OBJECT-NAME]
+    buf.putObjectPath(msg->objectName);
+
+    // [ASSOC-CLASS]
+    buf.putName(msg->assocClass);
+
+    // [RESULT-CLASS]
+    buf.putName(msg->resultClass);
+
+    // [ROLE]
+    buf.putString(msg->role);
+
+    // [RESULT-ROLE]
+    buf.putString(msg->resultRole);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static CIMAssociatorsRequestMessage* _decodeAssociatorsRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [OBJECT-NAME]
+    CIMObjectPath objectName;
+
+    if (!in.getObjectPath(objectName))
+        return 0;
+
+    // [ASSOC-CLASS]
+
+    CIMName assocClass;
+
+    if (!in.getName(assocClass))
+        return 0;
+
+    // [RESULT-CLASS]
+
+    CIMName resultClass;
+
+    if (!in.getName(resultClass))
+        return 0;
+
+    // [ROLE]
+
+    String role;
+
+    if (!in.getString(role))
+        return 0;
+
+    // [RESULT-ROLE]
+
+    String resultRole;
+
+    if (!in.getString(resultRole))
+        return 0;
+
+    // [PROPERTY-LIST]
+
+    CIMPropertyList propertyList;
+
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMAssociatorsRequestMessage> request(
+        new CIMAssociatorsRequestMessage(
+            messageId,
+            nameSpace,
+            objectName,
+            assocClass,
+            resultClass,
+            role,
+            resultRole,
+            includeQualifiers,
+            includeClassOrigin,
+            propertyList,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeAssociatorsResponseBody(
+    CIMBuffer& out,
+    CIMAssociatorsResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("Associators");
+    name = NAME;
+
+    out.putObjectA(msg->cimObjects);
+}
+
+static CIMAssociatorsResponseMessage* _decodeAssociatorsResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMObject> cimObjects;
+
+    while (in.more())
+    {
+        Array<CIMObject> tmp;
+
+        if (!in.getObjectA(tmp))
+            return 0;
+
+        cimObjects.append(tmp.getData(), tmp.size());
+    }
+
+    CIMAssociatorsResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMAssociatorsResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimObjects);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// AssociatorNames
+//
+//==============================================================================
+
+static void _encodeAssociatorNamesRequest(
+    CIMBuffer& buf,
+    CIMAssociatorNamesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("AssociatorNames");
+    name = NAME;
+
+    // [HEADER]
+    Uint32 flags = 0;
+
+    _putHeader(buf, flags, msg->messageId, OP_AssociatorNames);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [OBJECT-NAME]
+    buf.putObjectPath(msg->objectName);
+
+    // [ASSOC-CLASS]
+    buf.putName(msg->assocClass);
+
+    // [RESULT-CLASS]
+    buf.putName(msg->resultClass);
+
+    // [ROLE]
+    buf.putString(msg->role);
+
+    // [RESULT-ROLE]
+    buf.putString(msg->resultRole);
+}
+
+static CIMAssociatorNamesRequestMessage* _decodeAssociatorNamesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [OBJECT-NAME]
+    CIMObjectPath objectName;
+
+    if (!in.getObjectPath(objectName))
+        return 0;
+
+    // [ASSOC-CLASS]
+
+    CIMName assocClass;
+
+    if (!in.getName(assocClass))
+        return 0;
+
+    // [RESULT-CLASS]
+
+    CIMName resultClass;
+
+    if (!in.getName(resultClass))
+        return 0;
+
+    // [ROLE]
+
+    String role;
+
+    if (!in.getString(role))
+        return 0;
+
+    // [RESULT-ROLE]
+
+    String resultRole;
+
+    if (!in.getString(resultRole))
+        return 0;
+
+    AutoPtr<CIMAssociatorNamesRequestMessage> request(
+        new CIMAssociatorNamesRequestMessage(
+            messageId,
+            nameSpace,
+            objectName,
+            assocClass,
+            resultClass,
+            role,
+            resultRole,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeAssociatorNamesResponseBody(
+    CIMBuffer& out,
+    CIMAssociatorNamesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("AssociatorNames");
+    name = NAME;
+
+    out.putObjectPathA(msg->objectNames);
+}
+
+static CIMAssociatorNamesResponseMessage* _decodeAssociatorNamesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMObjectPath> objectNames;
+
+    while (in.more())
+    {
+        Array<CIMObjectPath> tmp;
+
+        if (!in.getObjectPathA(tmp))
+            return 0;
+
+        objectNames.append(tmp.getData(), tmp.size());
+    }
+
+    CIMAssociatorNamesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMAssociatorNamesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        objectNames);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// References
+//
+//==============================================================================
+
+static void _encodeReferencesRequest(
+    CIMBuffer& buf,
+    CIMReferencesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("References");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_References);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [OBJECT-NAME]
+    buf.putObjectPath(msg->objectName);
+
+    // [RESULT-CLASS]
+    buf.putName(msg->resultClass);
+
+    // [ROLE]
+    buf.putString(msg->role);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static CIMReferencesRequestMessage* _decodeReferencesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [OBJECT-NAME]
+
+    CIMObjectPath objectName;
+
+    if (!in.getObjectPath(objectName))
+        return 0;
+
+    // [RESULT-CLASS]
+
+    CIMName resultClass;
+
+    if (!in.getName(resultClass))
+        return 0;
+
+    // [ROLE]
+
+    String role;
+
+    if (!in.getString(role))
+        return 0;
+
+    // [PROPERTY-LIST]
+
+    CIMPropertyList propertyList;
+
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMReferencesRequestMessage> request(
+        new CIMReferencesRequestMessage(
+            messageId,
+            nameSpace,
+            objectName,
+            resultClass,
+            role,
+            includeQualifiers,
+            includeClassOrigin,
+            propertyList,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeReferencesResponseBody(
+    CIMBuffer& out,
+    CIMReferencesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("References");
+    name = NAME;
+
+    out.putObjectA(msg->cimObjects);
+}
+
+static CIMReferencesResponseMessage* _decodeReferencesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMObject> cimObjects;
+
+    while (in.more())
+    {
+        Array<CIMObject> tmp;
+
+        if (!in.getObjectA(tmp))
+        {
+            return 0;
+        }
+
+        cimObjects.append(tmp.getData(), tmp.size());
+    }
+
+    CIMReferencesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMReferencesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimObjects);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// ReferenceNames
+//
+//==============================================================================
+
+static void _encodeReferenceNamesRequest(
+    CIMBuffer& buf,
+    CIMReferenceNamesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("ReferenceNames");
+    name = NAME;
+
+    // [HEADER]
+    Uint32 flags = 0;
+
+    _putHeader(buf, flags, msg->messageId, OP_ReferenceNames);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [OBJECT-NAME]
+    buf.putObjectPath(msg->objectName);
+
+    // [RESULT-CLASS]
+    buf.putName(msg->resultClass);
+
+    // [ROLE]
+    buf.putString(msg->role);
+}
+
+static CIMReferenceNamesRequestMessage* _decodeReferenceNamesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [OBJECT-NAME]
+    CIMObjectPath objectName;
+
+    if (!in.getObjectPath(objectName))
+        return 0;
+
+    // [RESULT-CLASS]
+
+    CIMName resultClass;
+
+    if (!in.getName(resultClass))
+        return 0;
+
+    // [ROLE]
+
+    String role;
+
+    if (!in.getString(role))
+        return 0;
+
+    AutoPtr<CIMReferenceNamesRequestMessage> request(
+        new CIMReferenceNamesRequestMessage(
+            messageId,
+            nameSpace,
+            objectName,
+            resultClass,
+            role,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeReferenceNamesResponseBody(
+    CIMBuffer& out,
+    CIMReferenceNamesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("ReferenceNames");
+    name = NAME;
+
+    out.putObjectPathA(msg->objectNames);
+}
+
+static CIMReferenceNamesResponseMessage* _decodeReferenceNamesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMObjectPath> objectNames;
+
+    while (in.more())
+    {
+        Array<CIMObjectPath> tmp;
+
+        if (!in.getObjectPathA(tmp))
+            return 0;
+
+        objectNames.append(tmp.getData(), tmp.size());
+    }
+
+    CIMReferenceNamesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMReferenceNamesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        objectNames);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// GetClass
+//
+//==============================================================================
+
+static void _encodeGetClassRequest(
+    CIMBuffer& buf,
+    CIMGetClassRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("GetClass");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->localOnly)
+        flags |= LOCAL_ONLY;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_GetClass);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+
+    // [PROPERTY-LIST]
+    buf.putPropertyList(msg->propertyList);
+}
+
+static CIMGetClassRequestMessage* _decodeGetClassRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean localOnly = flags & LOCAL_ONLY;
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    // [PROPERTY-LIST]
+    CIMPropertyList propertyList;
+    if (!in.getPropertyList(propertyList))
+        return 0;
+
+    AutoPtr<CIMGetClassRequestMessage> request(new CIMGetClassRequestMessage(
+        messageId,
+        nameSpace,
+        className,
+        localOnly,
+        includeQualifiers,
+        includeClassOrigin,
+        propertyList,
+        QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeGetClassResponseBody(
+    CIMBuffer& out,
+    CIMGetClassResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("GetClass");
+    name = NAME;
+
+    out.putClass(msg->cimClass);
+}
+
+static CIMGetClassResponseMessage* _decodeGetClassResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMClass cimClass;
+
+    if (!in.getClass(cimClass))
+        return 0;
+
+    CIMGetClassResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMGetClassResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimClass);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// EnumerateClasses
+//
+//==============================================================================
+
+static void _encodeEnumerateClassesRequest(
+    CIMBuffer& buf,
+    CIMEnumerateClassesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("EnumerateClasses");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->localOnly)
+        flags |= LOCAL_ONLY;
+
+    if (msg->deepInheritance)
+        flags |= DEEP_INHERITANCE;
+
+    if (msg->includeQualifiers)
+        flags |= INCLUDE_QUALIFIERS;
+
+    if (msg->includeClassOrigin)
+        flags |= INCLUDE_CLASS_ORIGIN;
+
+    _putHeader(buf, flags, msg->messageId, OP_EnumerateClasses);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+}
+
+static CIMEnumerateClassesRequestMessage* _decodeEnumerateClassesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean localOnly = flags & LOCAL_ONLY;
+    Boolean deepInheritance = flags & DEEP_INHERITANCE;
+    Boolean includeQualifiers = flags & INCLUDE_QUALIFIERS;
+    Boolean includeClassOrigin = flags & INCLUDE_CLASS_ORIGIN;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    AutoPtr<CIMEnumerateClassesRequestMessage> request(
+        new CIMEnumerateClassesRequestMessage(
+            messageId,
+            nameSpace,
+            className,
+            deepInheritance,
+            localOnly,
+            includeQualifiers,
+            includeClassOrigin,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeEnumerateClassesResponseBody(
+    CIMBuffer& out,
+    CIMEnumerateClassesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("EnumerateClasses");
+    name = NAME;
+
+    out.putClassA(msg->cimClasses);
+}
+
+static CIMEnumerateClassesResponseMessage* _decodeEnumerateClassesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMClass> cimClasses;
+
+    while (in.more())
+    {
+        Array<CIMClass> tmp;
+
+        if (!in.getClassA(tmp))
+            return 0;
+
+        cimClasses.append(tmp.getData(), tmp.size());
+    }
+
+    CIMEnumerateClassesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMEnumerateClassesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimClasses);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// EnumerateClassNames
+//
+//==============================================================================
+
+static void _encodeEnumerateClassNamesRequest(
+    CIMBuffer& buf,
+    CIMEnumerateClassNamesRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("EnumerateClassNames");
+    name = NAME;
+
+    // [HEADER]
+
+    Uint32 flags = 0;
+
+    if (msg->deepInheritance)
+        flags |= DEEP_INHERITANCE;
+
+    _putHeader(buf, flags, msg->messageId, OP_EnumerateClassNames);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+}
+
+static CIMEnumerateClassNamesRequestMessage* _decodeEnumerateClassNamesRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    Boolean deepInheritance = flags & DEEP_INHERITANCE;
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    AutoPtr<CIMEnumerateClassNamesRequestMessage> request(
+        new CIMEnumerateClassNamesRequestMessage(
+            messageId,
+            nameSpace,
+            className,
+            deepInheritance,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeEnumerateClassNamesResponseBody(
+    CIMBuffer& out,
+    CIMEnumerateClassNamesResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("EnumerateClassNames");
+    name = NAME;
+
+    out.putNameA(msg->classNames);
+}
+
+static CIMEnumerateClassNamesResponseMessage* 
+_decodeEnumerateClassNamesResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMName> classNames;
+
+    while (in.more())
+    {
+        Array<CIMName> tmp;
+
+        if (!in.getNameA(tmp))
+            return 0;
+
+        classNames.append(tmp.getData(), tmp.size());
+    }
+
+    CIMEnumerateClassNamesResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMEnumerateClassNamesResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        classNames);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// CreateClass
+//
+//==============================================================================
+
+static void _encodeCreateClassRequest(
+    CIMBuffer& buf,
+    CIMCreateClassRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("CreateClass");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_CreateClass);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [NEW-CLASS]
+    buf.putClass(msg->newClass);
+}
+
+static CIMCreateClassRequestMessage* _decodeCreateClassRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [NEW-CLASS]
+    CIMClass newClass;
+
+    if (!in.getClass(newClass))
+        return 0;
+
+    AutoPtr<CIMCreateClassRequestMessage> request(
+        new CIMCreateClassRequestMessage(
+            messageId,
+            nameSpace,
+            newClass,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeCreateClassResponseBody(
+    CIMBuffer& out,
+    CIMCreateClassResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("CreateClass");
+    name = NAME;
+}
+
+static CIMCreateClassResponseMessage* _decodeCreateClassResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMCreateClassResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMCreateClassResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// DeleteClass
+//
+//==============================================================================
+
+static void _encodeDeleteClassRequest(
+    CIMBuffer& buf,
+    CIMDeleteClassRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("DeleteClass");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_DeleteClass);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [CLASSNAME]
+    buf.putName(msg->className);
+}
+
+static CIMDeleteClassRequestMessage* _decodeDeleteClassRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [CLASSNAME]
+    CIMName className;
+
+    if (!in.getName(className))
+        return 0;
+
+    AutoPtr<CIMDeleteClassRequestMessage> request(
+        new CIMDeleteClassRequestMessage(
+            messageId,
+            nameSpace,
+            className,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeDeleteClassResponseBody(
+    CIMBuffer& out,
+    CIMDeleteClassResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("DeleteClass");
+    name = NAME;
+}
+
+static CIMDeleteClassResponseMessage* _decodeDeleteClassResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMDeleteClassResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMDeleteClassResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// ModifyClass
+//
+//==============================================================================
+
+static void _encodeModifyClassRequest(
+    CIMBuffer& buf,
+    CIMModifyClassRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("ModifyClass");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_ModifyClass);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [NEW-CLASS]
+    buf.putClass(msg->modifiedClass);
+}
+
+static CIMModifyClassRequestMessage* _decodeModifyClassRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [MODIFIED-CLASS]
+    CIMClass modifiedClass;
+
+    if (!in.getClass(modifiedClass))
+        return 0;
+
+    AutoPtr<CIMModifyClassRequestMessage> request(
+        new CIMModifyClassRequestMessage(
+            messageId,
+            nameSpace,
+            modifiedClass,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeModifyClassResponseBody(
+    CIMBuffer& out,
+    CIMModifyClassResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("ModifyClass");
+    name = NAME;
+}
+
+static CIMModifyClassResponseMessage* _decodeModifyClassResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMModifyClassResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMModifyClassResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// SetQualifier
+//
+//==============================================================================
+
+static void _encodeSetQualifierRequest(
+    CIMBuffer& buf,
+    CIMSetQualifierRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("SetQualifier");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_SetQualifier);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [QUALIFIER-DECLARATION]
+    buf.putQualifierDecl(msg->qualifierDeclaration);
+}
+
+static CIMSetQualifierRequestMessage* _decodeSetQualifierRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [QUALIFIER.DECLARATION]
+
+    CIMQualifierDecl qualifierDeclaration;
+
+    if (!in.getQualifierDecl(qualifierDeclaration))
+        return 0;
+
+    AutoPtr<CIMSetQualifierRequestMessage> request(
+        new CIMSetQualifierRequestMessage(
+            messageId,
+            nameSpace,
+            qualifierDeclaration,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeSetQualifierResponseBody(
+    CIMBuffer& out,
+    CIMSetQualifierResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("SetQualifier");
+    name = NAME;
+}
+
+static CIMSetQualifierResponseMessage* _decodeSetQualifierResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMSetQualifierResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMSetQualifierResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// GetQualifier
+//
+//==============================================================================
+
+static void _encodeGetQualifierRequest(
+    CIMBuffer& buf,
+    CIMGetQualifierRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("GetQualifier");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_GetQualifier);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [QUALIFIER-NAME]
+    buf.putName(msg->qualifierName);
+}
+
+static CIMGetQualifierRequestMessage* _decodeGetQualifierRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [QUALIFIER-NAME]
+    CIMName qualifierName;
+
+    if (!in.getName(qualifierName))
+        return 0;
+
+    AutoPtr<CIMGetQualifierRequestMessage> request(
+        new CIMGetQualifierRequestMessage(
+            messageId,
+            nameSpace,
+            qualifierName,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeGetQualifierResponseBody(
+    CIMBuffer& out,
+    CIMGetQualifierResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("GetQualifier");
+    name = NAME;
+
+    out.putQualifierDecl(msg->cimQualifierDecl);
+}
+
+static CIMGetQualifierResponseMessage* _decodeGetQualifierResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMQualifierDecl cimQualifierDecl;
+
+    if (!in.getQualifierDecl(cimQualifierDecl))
+        return 0;
+
+    CIMGetQualifierResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMGetQualifierResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimQualifierDecl);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// DeleteQualifier
+//
+//==============================================================================
+
+static void _encodeDeleteQualifierRequest(
+    CIMBuffer& buf,
+    CIMDeleteQualifierRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("DeleteQualifier");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_DeleteQualifier);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [QUALIFIER-NAME]
+    buf.putName(msg->qualifierName);
+}
+
+static CIMDeleteQualifierRequestMessage* _decodeDeleteQualifierRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [QUALIFIER-NAME]
+    CIMName qualifierName;
+
+    if (!in.getName(qualifierName))
+        return 0;
+
+    AutoPtr<CIMDeleteQualifierRequestMessage> request(
+        new CIMDeleteQualifierRequestMessage(
+            messageId,
+            nameSpace,
+            qualifierName,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeDeleteQualifierResponseBody(
+    CIMBuffer& out,
+    CIMDeleteQualifierResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("DeleteQualifier");
+    name = NAME;
+}
+
+static CIMDeleteQualifierResponseMessage* _decodeDeleteQualifierResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMDeleteQualifierResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMDeleteQualifierResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// EnumerateQualifiers
+//
+//==============================================================================
+
+static void _encodeEnumerateQualifiersRequest(
+    CIMBuffer& buf,
+    CIMEnumerateQualifiersRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("EnumerateQualifiers");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_EnumerateQualifiers);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+}
+
+static CIMEnumerateQualifiersRequestMessage* _decodeEnumerateQualifiersRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    AutoPtr<CIMEnumerateQualifiersRequestMessage> request(
+        new CIMEnumerateQualifiersRequestMessage(
+            messageId,
+            nameSpace,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeEnumerateQualifiersResponseBody(
+    CIMBuffer& out,
+    CIMEnumerateQualifiersResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("EnumerateQualifiers");
+    name = NAME;
+
+    out.putQualifierDeclA(msg->qualifierDeclarations);
+}
+
+static CIMEnumerateQualifiersResponseMessage* 
+    _decodeEnumerateQualifiersResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMQualifierDecl> qualifierDecls;
+
+    while (in.more())
+    {
+        Array<CIMQualifierDecl> tmp;
+
+        if (!in.getQualifierDeclA(tmp))
+            return 0;
+
+        qualifierDecls.append(tmp.getData(), tmp.size());
+    }
+
+    CIMEnumerateQualifiersResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMEnumerateQualifiersResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        qualifierDecls);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// GetProperty
+//
+//==============================================================================
+
+static void _encodeGetPropertyRequest(
+    CIMBuffer& buf,
+    CIMGetPropertyRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("GetProperty");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_GetProperty);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [INSTANCE-NAME]
+    buf.putObjectPath(msg->instanceName);
+
+    // [PROPERTY-NAME]
+    buf.putName(msg->propertyName);
+}
+
+static CIMGetPropertyRequestMessage* _decodeGetPropertyRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [INSTANCE-NAME]
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    // [PROPERTY-NAME]
+    CIMName propertyName;
+
+    if (!in.getName(propertyName))
+        return 0;
+
+    AutoPtr<CIMGetPropertyRequestMessage> request(
+        new CIMGetPropertyRequestMessage(
+            messageId,
+            nameSpace,
+            instanceName,
+            propertyName,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeGetPropertyResponseBody(
+    CIMBuffer& out,
+    CIMGetPropertyResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("GetProperty");
+    name = NAME;
+
+    // [VALUE]
+    out.putValue(msg->value);
+}
+
+static CIMGetPropertyResponseMessage* _decodeGetPropertyResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    // [VALUE]
+    CIMValue value;
+
+    if (!in.getValue(value))
+        return 0;
+
+    // Unfortunately the CIM GetProperty() method is only able to return
+    // a string since there is no containing element that specifies its
+    // type. So even though the binary protocol properly transmits the type,
+    // we are force to convert that type to string to match the XML protocol
+    // behavior.
+
+    if (value.isNull())
+        value.setNullValue(CIMTYPE_STRING, false);
+    else
+        value.set(value.toString());
+
+    CIMGetPropertyResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMGetPropertyResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        value);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// SetProperty
+//
+//==============================================================================
+
+static void _encodeSetPropertyRequest(
+    CIMBuffer& buf,
+    CIMSetPropertyRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("SetProperty");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_SetProperty);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [INSTANCE-NAME]
+    buf.putObjectPath(msg->instanceName);
+
+    // [PROPERTY-NAME]
+    buf.putName(msg->propertyName);
+
+    // [VALUE]
+    buf.putValue(msg->newValue);
+}
+
+static CIMSetPropertyRequestMessage* _decodeSetPropertyRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [INSTANCE-NAME]
+
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    // [PROPERTY-NAME]
+
+    CIMName propertyName;
+
+    if (!in.getName(propertyName))
+        return 0;
+
+    // [PROPERTY-VALUE]
+
+    CIMValue propertyValue;
+
+    if (!in.getValue(propertyValue))
+        return 0;
+
+    AutoPtr<CIMSetPropertyRequestMessage> request(
+        new CIMSetPropertyRequestMessage(
+            messageId,
+            nameSpace,
+            instanceName,
+            propertyName,
+            propertyValue,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeSetPropertyResponseBody(
+    CIMBuffer& out,
+    CIMSetPropertyResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("SetProperty");
+    name = NAME;
+}
+
+static CIMSetPropertyResponseMessage* _decodeSetPropertyResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    CIMSetPropertyResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMSetPropertyResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack());
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// InvokeMethod
+//
+//==============================================================================
+
+static void _encodeInvokeMethodRequest(
+    CIMBuffer& buf,
+    CIMInvokeMethodRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    name = msg->methodName;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_InvokeMethod);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [INSTANCE-NAME]
+    buf.putObjectPath(msg->instanceName);
+
+    // [METHOD-NAME]
+    buf.putName(msg->methodName);
+
+    // [IN-PARAMETERS]
+    buf.putParamValueA(msg->inParameters);
+}
+
+static CIMInvokeMethodRequestMessage* _decodeInvokeMethodRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [INSTANCE-NAME]
+
+    CIMObjectPath instanceName;
+
+    if (!in.getObjectPath(instanceName))
+        return 0;
+
+    // [METHOD-NAME]
+
+    CIMName methodName;
+
+    if (!in.getName(methodName))
+        return 0;
+
+    // [IN-PARAMETERS]
+
+    Array<CIMParamValue> inParameters;
+
+    if (!in.getParamValueA(inParameters))
+        return 0;
+
+    AutoPtr<CIMInvokeMethodRequestMessage> request(
+        new CIMInvokeMethodRequestMessage(
+            messageId,
+            nameSpace,
+            instanceName,
+            methodName,
+            inParameters,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeInvokeMethodResponseBody(
+    CIMBuffer& out,
+    CIMInvokeMethodResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    name = msg->methodName;
+
+    // [METHOD-NAME]
+    out.putName(msg->methodName);
+
+    // [RETURN-VALUE]
+    out.putValue(msg->retValue);
+
+    // [OUT-PARAMETERS]
+    out.putParamValueA(msg->outParameters);
+}
+
+static CIMInvokeMethodResponseMessage* _decodeInvokeMethodResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    // [METHOD-NAME]
+
+    CIMName methodName;
+
+    if (!in.getName(methodName))
+        return 0;
+
+    // [RETURN-VALUE]
+
+    CIMValue returnValue;
+
+    if (!in.getValue(returnValue))
+        return 0;
+
+    // [OUT-PARAMETERS]
+
+    Array<CIMParamValue> outParameters;
+
+    if (!in.getParamValueA(outParameters))
+        return 0;
+
+    CIMInvokeMethodResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMInvokeMethodResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        returnValue,
+        outParameters,
+        methodName);
+
+    msg->binaryRequest = true;
+
+    return msg;
+}
+
+//==============================================================================
+//
+// ExecQuery
+//
+//==============================================================================
+
+static void _encodeExecQueryRequest(
+    CIMBuffer& buf,
+    CIMExecQueryRequestMessage* msg,
+    CIMName& name)
+{
+    /* See ../Client/CIMOperationRequestEncoder.cpp */
+
+    static const CIMName NAME("ExecQuery");
+    name = NAME;
+
+    // [HEADER]
+    _putHeader(buf, 0, msg->messageId, OP_ExecQuery);
+
+    // [NAMESPACE]
+    buf.putNamespaceName(msg->nameSpace);
+
+    // [QUERY-LANGUAGE]
+    buf.putString(msg->queryLanguage);
+
+    // [QUERY]
+    buf.putString(msg->query);
+}
+
+static CIMExecQueryRequestMessage* _decodeExecQueryRequest(
+    CIMBuffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Server/CIMOperationRequestDecoder.cpp */
+
+    STAT_GETSTARTTIME
+
+    // [NAMESPACE]
+
+    CIMNamespaceName nameSpace;
+
+    if (!in.getNamespaceName(nameSpace))
+        return 0;
+
+    // [QUERY-LANGUAGE]]
+    String queryLanguage;
+
+    if (!in.getString(queryLanguage))
+        return 0;
+
+    // [QUERY]]
+    String query;
+
+    if (!in.getString(query))
+        return 0;
+
+    AutoPtr<CIMExecQueryRequestMessage> request(
+        new CIMExecQueryRequestMessage(
+            messageId,
+            nameSpace,
+            queryLanguage,
+            query,
+            QueueIdStack(queueId, returnQueueId)));
+
+    request->binaryRequest = true;
+
+    STAT_SERVERSTART
+
+    return request.release();
+}
+
+static void _encodeExecQueryResponseBody(
+    CIMBuffer& out,
+    CIMExecQueryResponseMessage* msg,
+    CIMName& name)
+{
+    /* See ../Server/CIMOperationResponseEncoder.cpp */
+
+    static const CIMName NAME("ExecQuery");
+    name = NAME;
+
+    out.putObjectA(msg->cimObjects, false);
+}
+
+static CIMExecQueryResponseMessage* _decodeExecQueryResponse(
+    CIMBuffer& in,
+    Uint32 flags,
+    const String& messageId)
+{
+    /* See ../Client/CIMOperationResponseDecoder.cpp */
+
+    Array<CIMObject> cimObjects;
+
+    while (in.more())
+    {
+        Array<CIMObject> tmp;
+
+        if (!in.getObjectA(tmp))
+            return 0;
+
+        cimObjects.append(tmp.getData(), tmp.size());
+    }
+
+    CIMExecQueryResponseMessage* msg;
+    CIMException cimException;
+
+    msg = new CIMExecQueryResponseMessage(
+        messageId,
+        cimException,
+        QueueIdStack(),
+        cimObjects);
+
+    msg->binaryRequest = true;
+    return msg;
+}
+
+//==============================================================================
+//
+// BinaryCodec::hexDump()
+//
+//==============================================================================
+
+#if defined(PEGASUS_DEBUG)
+
+void BinaryCodec::hexDump(const void* data, size_t size)
+{
+    unsigned char* p = (unsigned char*)data;
+    unsigned char buf[16];
+    size_t n = 0;
+
+    for (size_t i = 0, col = 0; i < size; i++)
+    {
+        unsigned char c = p[i];
+        buf[n++] = c;
+
+        if (col == 0)
+            printf("%06X ", (unsigned int)i);
+
+        printf("%02X ", c);
+
+        if (col + 1 == sizeof(buf) || i + 1 == size)
+        {
+            for (size_t j = col + 1; j < sizeof(buf); j++)
+                printf("   ");
+
+            for (size_t j = 0; j < n; j++)
+            {
+                c = buf[j];
+
+                if (c >= ' ' && c <= '~')
+                    printf("%c", buf[j]);
+                else
+                    printf(".");
+            }
+
+            printf("\n");
+            n = 0;
+        }
+
+        if (col + 1 == sizeof(buf))
+            col = 0;
+        else
+            col++;
+    }
+
+    printf("\n");
+}
+
+#endif /* defined(PEGASUS_DEBUG) */
+
+//==============================================================================
+//
+// BinaryCodec::decodeRequest()
+//
+//==============================================================================
+
+CIMOperationRequestMessage* BinaryCodec::decodeRequest(
+    const Buffer& in,
+    Uint32 queueId,
+    Uint32 returnQueueId)
+{
+    CIMBuffer buf((char*)in.getData(), in.size());
+    CIMBufferReleaser buf_(buf);
+
+    // Turn on validation:
+#if defined(ENABLE_VALIDATION)
+    buf.setValidate(true);
+#endif
+
+    Uint32 flags;
+    String messageId;
+    Operation operation;
+
+
+    if (!_getHeader(buf, flags, messageId, operation))
+    {
+        return 0;
+    }
+
+    switch (operation)
+    {
+        case OP_EnumerateInstances:
+            return _decodeEnumerateInstancesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_EnumerateInstanceNames:
+            return _decodeEnumerateInstanceNamesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_GetInstance:
+            return _decodeGetInstanceRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_CreateInstance:
+            return _decodeCreateInstanceRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_ModifyInstance:
+            return _decodeModifyInstanceRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_DeleteInstance:
+            return _decodeDeleteInstanceRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_Associators:
+            return _decodeAssociatorsRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_AssociatorNames:
+            return _decodeAssociatorNamesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_References:
+            return _decodeReferencesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_ReferenceNames:
+            return _decodeReferenceNamesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_GetClass:
+            return _decodeGetClassRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_EnumerateClasses:
+            return _decodeEnumerateClassesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_EnumerateClassNames:
+            return _decodeEnumerateClassNamesRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_CreateClass:
+            return _decodeCreateClassRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_DeleteClass:
+            return _decodeDeleteClassRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_ModifyClass:
+            return _decodeModifyClassRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_SetQualifier:
+            return _decodeSetQualifierRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_GetQualifier:
+            return _decodeGetQualifierRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_DeleteQualifier:
+            return _decodeDeleteQualifierRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_EnumerateQualifiers:
+            return _decodeEnumerateQualifiersRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_GetProperty:
+           return _decodeGetPropertyRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_SetProperty:
+           return _decodeSetPropertyRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_InvokeMethod:
+           return _decodeInvokeMethodRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        case OP_ExecQuery:
+           return _decodeExecQueryRequest(
+                buf, queueId, returnQueueId, flags, messageId);
+        default:
+            // Unexpected message type
+            PEGASUS_ASSERT(0);
+            return 0;
+    }
+}
+
+//==============================================================================
+//
+// BinaryCodec::decodeResponse()
+//
+//==============================================================================
+
+CIMResponseMessage* BinaryCodec::decodeResponse(
+    const Buffer& in)
+{
+    CIMBuffer buf((char*)in.getData(), in.size());
+    CIMBufferReleaser buf_(buf);
+
+    // Turn on validation:
+#if defined(ENABLE_VALIDATION)
+    buf.setValidate(true);
+#endif
+
+    Uint32 flags;
+    String messageId;
+    Operation operation;
+
+    if (!_getHeader(buf, flags, messageId, operation))
+    {
+        throw CIMException(CIM_ERR_FAILED, "Corrupt binary message header");
+        return 0;
+    }
+
+    CIMResponseMessage* msg = 0;
+
+    switch (operation)
+    {
+        case OP_EnumerateInstances:
+            msg = _decodeEnumerateInstancesResponse(buf, flags, messageId);
+            break;
+        case OP_EnumerateInstanceNames:
+            msg = _decodeEnumerateInstanceNamesResponse(buf, flags, messageId);
+            break;
+        case OP_GetInstance:
+            msg = _decodeGetInstanceResponse(buf, flags, messageId);
+            break;
+        case OP_CreateInstance:
+            msg = _decodeCreateInstanceResponse(buf, flags, messageId);
+            break;
+        case OP_ModifyInstance:
+            msg = _decodeModifyInstanceResponse(buf, flags, messageId);
+            break;
+        case OP_DeleteInstance:
+            msg = _decodeDeleteInstanceResponse(buf, flags, messageId);
+            break;
+        case OP_Associators:
+            msg = _decodeAssociatorsResponse(buf, flags, messageId);
+            break;
+        case OP_AssociatorNames:
+            msg = _decodeAssociatorNamesResponse(buf, flags, messageId);
+            break;
+        case OP_References:
+            msg = _decodeReferencesResponse(buf, flags, messageId);
+            break;
+        case OP_ReferenceNames:
+            msg = _decodeReferenceNamesResponse(buf, flags, messageId);
+            break;
+        case OP_GetClass:
+            msg = _decodeGetClassResponse(buf, flags, messageId);
+            break;
+        case OP_EnumerateClasses:
+            msg = _decodeEnumerateClassesResponse(buf, flags, messageId);
+            break;
+        case OP_EnumerateClassNames:
+            msg = _decodeEnumerateClassNamesResponse(buf, flags, messageId);
+            break;
+        case OP_CreateClass:
+            msg = _decodeCreateClassResponse(buf, flags, messageId);
+            break;
+        case OP_DeleteClass:
+            msg = _decodeDeleteClassResponse(buf, flags, messageId);
+            break;
+        case OP_ModifyClass:
+            msg = _decodeModifyClassResponse(buf, flags, messageId);
+            break;
+        case OP_SetQualifier:
+            msg = _decodeSetQualifierResponse(buf, flags, messageId);
+            break;
+        case OP_GetQualifier:
+            msg = _decodeGetQualifierResponse(buf, flags, messageId);
+            break;
+        case OP_DeleteQualifier:
+            msg = _decodeDeleteQualifierResponse(buf, flags, messageId);
+            break;
+        case OP_EnumerateQualifiers:
+            msg = _decodeEnumerateQualifiersResponse(buf, flags, messageId);
+            break;
+        case OP_GetProperty:
+            msg = _decodeGetPropertyResponse(buf, flags, messageId);
+            break;
+        case OP_SetProperty:
+            msg = _decodeSetPropertyResponse(buf, flags, messageId);
+            break;
+        case OP_InvokeMethod:
+            msg = _decodeInvokeMethodResponse(buf, flags, messageId);
+            break;
+        case OP_ExecQuery:
+            msg = _decodeExecQueryResponse(buf, flags, messageId);
+            break;
+        default:
+            // Unexpected message type
+            PEGASUS_ASSERT(0);
+            break;
+    }
+
+    if (!msg)
+        throw CIMException(CIM_ERR_FAILED, "Received corrupted binary message");
+
+    return msg;
+}
+
+//==============================================================================
+//
+// BinaryCodec::formatSimpleIMethodRspMessage()
+//
+//==============================================================================
+
+Buffer BinaryCodec::formatSimpleIMethodRspMessage(
+    const CIMName& iMethodName,
+    const String& messageId,
+    HttpMethod httpMethod,
+    const ContentLanguageList& httpContentLanguages,
+    const Buffer& body,
+    Uint64 serverResponseTime,
+    Boolean isFirst,
+    Boolean isLast)
+{
+    Buffer out;
+
+    if (isFirst == true)
+    {
+        // Write HTTP header:
+        XmlWriter::appendMethodResponseHeader(out, httpMethod, 
+            httpContentLanguages, 0, serverResponseTime, true);
+
+        // Binary message header:
+        CIMBuffer cb(128);
+        _putHeader(cb, 0, messageId, _NameToOp(iMethodName));
+        out.append(cb.getData(), cb.size());
+    }
+
+    if (body.size() != 0)
+    {
+        out.append(body.getData(), body.size());
+    }
+
+    return out;
+}
+
+//==============================================================================
+//
+// BinaryCodec::encodeRequest()
+//
+//==============================================================================
+
+bool BinaryCodec::encodeRequest(
+    Buffer& out,
+    const char* host,
+    const String& authHeader,
+    CIMOperationRequestMessage* msg,
+    bool binaryResponse)
+{
+    CIMBuffer buf;
+    CIMName name;
+
+    switch (msg->getType())
+    {
+        case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
+        {
+            _encodeEnumerateInstancesRequest(buf,
+                (CIMEnumerateInstancesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
+        {
+            _encodeEnumerateInstanceNamesRequest(buf,
+                (CIMEnumerateInstanceNamesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_INSTANCE_REQUEST_MESSAGE:
+        {
+            _encodeGetInstanceRequest(buf,
+                (CIMGetInstanceRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
+        {
+            _encodeCreateInstanceRequest(buf,
+                (CIMCreateInstanceRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
+        {
+            _encodeModifyInstanceRequest(buf,
+                (CIMModifyInstanceRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
+        {
+            _encodeDeleteInstanceRequest(buf,
+                (CIMDeleteInstanceRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ASSOCIATORS_REQUEST_MESSAGE:
+        {
+            _encodeAssociatorsRequest(buf,
+                (CIMAssociatorsRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE:
+        {
+            _encodeAssociatorNamesRequest(buf,
+                (CIMAssociatorNamesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_REFERENCES_REQUEST_MESSAGE:
+        {
+            _encodeReferencesRequest(buf,
+                (CIMReferencesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_REFERENCE_NAMES_REQUEST_MESSAGE:
+        {
+            _encodeReferenceNamesRequest(buf,
+                (CIMReferenceNamesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_CLASS_REQUEST_MESSAGE:
+        {
+            _encodeGetClassRequest(buf,
+                (CIMGetClassRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_CLASSES_REQUEST_MESSAGE:
+        {
+            _encodeEnumerateClassesRequest(buf,
+                (CIMEnumerateClassesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_CLASS_NAMES_REQUEST_MESSAGE:
+        {
+            _encodeEnumerateClassNamesRequest(buf,
+                (CIMEnumerateClassNamesRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_CREATE_CLASS_REQUEST_MESSAGE:
+        {
+            _encodeCreateClassRequest(buf,
+                (CIMCreateClassRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_CLASS_REQUEST_MESSAGE:
+        {
+            _encodeDeleteClassRequest(buf,
+                (CIMDeleteClassRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_MODIFY_CLASS_REQUEST_MESSAGE:
+        {
+            _encodeModifyClassRequest(buf,
+                (CIMModifyClassRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_SET_QUALIFIER_REQUEST_MESSAGE:
+        {
+            _encodeSetQualifierRequest(buf,
+                (CIMSetQualifierRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_QUALIFIER_REQUEST_MESSAGE:
+        {
+            _encodeGetQualifierRequest(buf,
+                (CIMGetQualifierRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_QUALIFIER_REQUEST_MESSAGE:
+        {
+            _encodeDeleteQualifierRequest(buf,
+                (CIMDeleteQualifierRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_QUALIFIERS_REQUEST_MESSAGE:
+        {
+            _encodeEnumerateQualifiersRequest(buf,
+                (CIMEnumerateQualifiersRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_PROPERTY_REQUEST_MESSAGE:
+        {
+            _encodeGetPropertyRequest(buf,
+                (CIMGetPropertyRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_SET_PROPERTY_REQUEST_MESSAGE:
+        {
+            _encodeSetPropertyRequest(buf,
+                (CIMSetPropertyRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
+        {
+            _encodeInvokeMethodRequest(buf,
+                (CIMInvokeMethodRequestMessage*)msg, name);
+            break;
+        }
+
+        case CIM_EXEC_QUERY_REQUEST_MESSAGE:
+        {
+            _encodeExecQueryRequest(buf,
+                (CIMExecQueryRequestMessage*)msg, name);
+            break;
+        }
+
+        default:
+            // Unexpected message type
+            PEGASUS_ASSERT(0);
+            return false;
+    }
+
+    // [HTTP-HEADERS]
+    XmlWriter::appendMethodCallHeader(
+        out,
+        host,
+        name,
+        msg->nameSpace.getString(),
+        authHeader,
+        msg->getHttpMethod(),
+        AcceptLanguageListContainer(msg->operationContext.get(
+            AcceptLanguageListContainer::NAME)).getLanguages(),
+        ContentLanguageListContainer(msg->operationContext.get(
+            ContentLanguageListContainer::NAME)).getLanguages(),
+        buf.size(), 
+        true, /* binaryRequest */
+        binaryResponse);
+
+    out.append(buf.getData(), buf.size());
+
+    return true;
+}
+
+//==============================================================================
+//
+// BinaryCodec::encodeResponseBody()
+//
+//==============================================================================
+
+bool BinaryCodec::encodeResponseBody(
+    Buffer& out,
+    const CIMResponseMessage* msg,
+    CIMName& name)
+{
+    CIMBuffer buf;
+
+    switch (msg->getType())
+    {
+        case CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE:
+        {
+            _encodeEnumerateInstancesResponseBody(buf,
+                (CIMEnumerateInstancesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_INSTANCE_NAMES_RESPONSE_MESSAGE:
+        {
+            _encodeEnumerateInstanceNamesResponseBody(buf,
+                (CIMEnumerateInstanceNamesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_INSTANCE_RESPONSE_MESSAGE:
+        {
+            _encodeGetInstanceResponseBody(buf,
+                (CIMGetInstanceResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_CREATE_INSTANCE_RESPONSE_MESSAGE:
+        {
+            _encodeCreateInstanceResponseBody(buf,
+                (CIMCreateInstanceResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_MODIFY_INSTANCE_RESPONSE_MESSAGE:
+        {
+            _encodeModifyInstanceResponseBody(buf,
+                (CIMModifyInstanceResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_INSTANCE_RESPONSE_MESSAGE:
+        {
+            _encodeDeleteInstanceResponseBody(buf,
+                (CIMDeleteInstanceResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ASSOCIATORS_RESPONSE_MESSAGE:
+        {
+            _encodeAssociatorsResponseBody(buf,
+                (CIMAssociatorsResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ASSOCIATOR_NAMES_RESPONSE_MESSAGE:
+        {
+            _encodeAssociatorNamesResponseBody(buf,
+                (CIMAssociatorNamesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_REFERENCES_RESPONSE_MESSAGE:
+        {
+            _encodeReferencesResponseBody(buf,
+                (CIMReferencesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_REFERENCE_NAMES_RESPONSE_MESSAGE:
+        {
+            _encodeReferenceNamesResponseBody(buf,
+                (CIMReferenceNamesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_CLASS_RESPONSE_MESSAGE:
+        {
+            _encodeGetClassResponseBody(buf,
+                (CIMGetClassResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_CLASSES_RESPONSE_MESSAGE:
+        {
+            _encodeEnumerateClassesResponseBody(buf,
+                (CIMEnumerateClassesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_CLASS_NAMES_RESPONSE_MESSAGE:
+        {
+            _encodeEnumerateClassNamesResponseBody(buf,
+                (CIMEnumerateClassNamesResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_CREATE_CLASS_RESPONSE_MESSAGE:
+        {
+            _encodeCreateClassResponseBody(buf,
+                (CIMCreateClassResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_CLASS_RESPONSE_MESSAGE:
+        {
+            _encodeDeleteClassResponseBody(buf,
+                (CIMDeleteClassResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_MODIFY_CLASS_RESPONSE_MESSAGE:
+        {
+            _encodeModifyClassResponseBody(buf,
+                (CIMModifyClassResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_SET_QUALIFIER_RESPONSE_MESSAGE:
+        {
+            _encodeSetQualifierResponseBody(buf,
+                (CIMSetQualifierResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_QUALIFIER_RESPONSE_MESSAGE:
+        {
+            _encodeGetQualifierResponseBody(buf,
+                (CIMGetQualifierResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_DELETE_QUALIFIER_RESPONSE_MESSAGE:
+        {
+            _encodeDeleteQualifierResponseBody(buf,
+                (CIMDeleteQualifierResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_ENUMERATE_QUALIFIERS_RESPONSE_MESSAGE:
+        {
+            _encodeEnumerateQualifiersResponseBody(buf,
+                (CIMEnumerateQualifiersResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_GET_PROPERTY_RESPONSE_MESSAGE:
+        {
+            _encodeGetPropertyResponseBody(buf,
+                (CIMGetPropertyResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_SET_PROPERTY_RESPONSE_MESSAGE:
+        {
+            _encodeSetPropertyResponseBody(buf,
+                (CIMSetPropertyResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_INVOKE_METHOD_RESPONSE_MESSAGE:
+        {
+            _encodeInvokeMethodResponseBody(buf,
+                (CIMInvokeMethodResponseMessage*)msg, name);
+            break;
+        }
+
+        case CIM_EXEC_QUERY_RESPONSE_MESSAGE:
+        {
+            _encodeExecQueryResponseBody(buf,
+                (CIMExecQueryResponseMessage*)msg, name);
+            break;
+        }
+
+        default:
+            // Unexpected message type
+            PEGASUS_ASSERT(0);
+            return false;
+    }
+
+    out.append(buf.getData(), buf.size());
+    return true;
+}
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Pegasus/Common/BinaryCodec.h b/src/Pegasus/Common/BinaryCodec.h
new file mode 100644 (file)
index 0000000..bbc870b
--- /dev/null
@@ -0,0 +1,94 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_BinaryCodec_h
+#define Pegasus_BinaryCodec_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/Buffer.h>
+#include <Pegasus/Common/CIMBuffer.h>
+#include <Pegasus/Common/CIMMessage.h>
+#include <Pegasus/Common/AcceptLanguageList.h>
+#include <Pegasus/Common/ContentLanguageList.h>
+#include <Pegasus/Common/Linkage.h>
+
+PEGASUS_NAMESPACE_BEGIN
+
+/** This is the coder-decoder (codec) for the OpenPegasus proprietary binary 
+    protocol.
+*/
+class PEGASUS_COMMON_LINKAGE BinaryCodec
+{
+public:
+
+    // Peform hex dump of the given data.
+    static void hexDump(const void* data, size_t size);
+
+    static bool encodeRequest(
+        Buffer& out,
+        const char* host,
+        const String& authenticationHeader,
+        CIMOperationRequestMessage* msg,
+        bool binaryResponse);
+
+    static bool encodeResponseBody(
+        Buffer& out,
+        const CIMResponseMessage* msg,
+        CIMName& name);
+
+    static CIMOperationRequestMessage* decodeRequest(
+        const Buffer& in,
+        Uint32 queueId,
+        Uint32 returnQueueId);
+
+    static CIMResponseMessage* decodeResponse(
+        const Buffer& in);
+
+    static Buffer formatSimpleIMethodRspMessage(
+        const CIMName& iMethodName,
+        const String& messageId,
+        HttpMethod httpMethod,
+        const ContentLanguageList& httpContentLanguages,
+        const Buffer& body,
+        Uint64 serverResponseTime,
+        Boolean isFirst,
+        Boolean isLast);
+
+private:
+
+    BinaryCodec();
+};
+
+PEGASUS_NAMESPACE_END
+
+#endif /* Pegasus_BinaryCodec_h */
index c80e59a879136c74ab8be2ed62b12a1e7b1ade82..fbf70471729b1e8c9c337fef0698c4abcfcb4a26 100644 (file)
@@ -784,7 +784,16 @@ void BinaryStreamer::_unpackProperty(
             // class definitions, and only NULL values are recognized. We
             // currently don't handle embedded object types with default
             // values in the class definition.
+#if defined(PEGASUS_ENABLE_PROTOCOL_BINARY)
+            // The binary protocol (unlike the XML protocol) successfully 
+            // transmits embedded object default values. But since they are
+            // not handled elsewhere, we discard the value.
+            cimProperty.setValue(
+                CIMValue(value.getType(),value.isArray(),value.getArraySize()));
+#else
             PEGASUS_ASSERT(value.isNull());
+#endif
+
             realType = CIMTYPE_OBJECT;
         }
 
index cd3ac2009cf21d6fa297326df72476176f78890e..a283ad04ac61dcdf5c4840ad82c167d36a45ecc9 100644 (file)
@@ -36,6 +36,7 @@
 #include <Pegasus/Common/System.h>
 
 #include "CIMBinMsgDeserializer.h"
+#include "BinaryCodec.h"
 
 PEGASUS_NAMESPACE_BEGIN
 
@@ -58,6 +59,20 @@ CIMMessage* CIMBinMsgDeserializer::deserialize(
     if (!in.getString(messageID))
         return 0;
 
+    // [binaryRequest]
+
+    Boolean binaryRequest;
+
+    if (!in.getBoolean(binaryRequest))
+        return 0;
+
+    // [binaryResponse]
+
+    Boolean binaryResponse;
+
+    if (!in.getBoolean(binaryResponse))
+        return 0;
+
     // [type]
 
     MessageType type;
@@ -123,13 +138,15 @@ CIMMessage* CIMBinMsgDeserializer::deserialize(
 
     if (present)
     {
-        if (!(msg = _getResponseMessage(in, type)))
+        if (!(msg = _getResponseMessage(in, type, binaryResponse)))
             return 0;
     }
 
     // Initialize the messge:
 
     msg->messageId = messageID;
+    msg->binaryRequest = binaryRequest;
+    msg->binaryResponse = binaryResponse;
 #ifndef PEGASUS_DISABLE_PERFINST
     msg->setServerStartTime(serverStartTimeMicroseconds);
     msg->setProviderTime(providerTimeMicroseconds);
@@ -350,7 +367,8 @@ CIMRequestMessage* CIMBinMsgDeserializer::_getRequestMessage(
 
 CIMResponseMessage* CIMBinMsgDeserializer::_getResponseMessage(
     CIMBuffer& in,
-    MessageType type)
+    MessageType type,
+    bool binaryResponse)
 {
     CIMResponseMessage* msg = 0;
     QueueIdStack queueIdStack;
@@ -370,7 +388,7 @@ CIMResponseMessage* CIMBinMsgDeserializer::_getResponseMessage(
     switch (type)
     {
         case CIM_GET_INSTANCE_RESPONSE_MESSAGE:
-            msg = _getGetInstanceResponseMessage(in);
+            msg = _getGetInstanceResponseMessage(in, binaryResponse);
             break;
         case CIM_DELETE_INSTANCE_RESPONSE_MESSAGE:
             msg = _getDeleteInstanceResponseMessage(in);
@@ -382,7 +400,7 @@ CIMResponseMessage* CIMBinMsgDeserializer::_getResponseMessage(
             msg = _getModifyInstanceResponseMessage(in);
             break;
         case CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE:
-            msg = _getEnumerateInstancesResponseMessage(in);
+            msg = _getEnumerateInstancesResponseMessage(in, binaryResponse);
             break;
         case CIM_ENUMERATE_INSTANCE_NAMES_RESPONSE_MESSAGE:
             msg = _getEnumerateInstanceNamesResponseMessage(in);
@@ -1547,18 +1565,13 @@ CIMBinMsgDeserializer::_getSubscriptionInitCompleteRequestMessage(
         QueueIdStack());
 }
 
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
-static Boolean _resolveInstanceCallback(
-    const Array<Sint8>& instanceData,
-    const Array<Sint8>& referenceData,
-    const String& hostData,
-    const CIMNamespaceName& nameSpaceData,
+static Boolean _resolveXMLInstance(
+    CIMGetInstanceResponseMessage* msg,
     CIMInstance& cimInstance)
 {
     // Deserialize instance:
     {
-        XmlParser parser((char*)instanceData.getData());
+        XmlParser parser((char*)msg->instanceData.getData());
 
         if (!XmlReader::getInstanceElement(parser, cimInstance))
         {
@@ -1569,16 +1582,16 @@ static Boolean _resolveInstanceCallback(
 
     // Deserialize path:
     {
-        XmlParser parser((char*)referenceData.getData());
+        XmlParser parser((char*)msg->referenceData.getData());
         CIMObjectPath cimObjectPath;
 
         if (XmlReader::getValueReferenceElement(parser, cimObjectPath))
         {
-            if (hostData.size())
-                cimObjectPath.setHost(hostData);
+            if (msg->hostData.size())
+                cimObjectPath.setHost(msg->hostData);
 
-            if (!nameSpaceData.isNull())
-                cimObjectPath.setNameSpace(nameSpaceData);
+            if (!msg->nameSpaceData.isNull())
+                cimObjectPath.setNameSpace(msg->nameSpaceData);
 
             cimInstance.setPath(cimObjectPath);
         }
@@ -1587,128 +1600,136 @@ static Boolean _resolveInstanceCallback(
     return true;
 }
 
-static Boolean _resolveNamedInstanceCallback(
-    const Array<Sint8>& instanceData,
-    const Array<Sint8>& referenceData,
-    const String& hostData,
-    const CIMNamespaceName& nameSpaceData,
-    CIMInstance& cimInstance)
+static Boolean _resolveXMLInstances(
+    CIMEnumerateInstancesResponseMessage* msg,
+    Array<CIMInstance>& instances)
 {
-    // Deserialize instance:
+    instances.clear();
+
+    for (Uint32 i = 0; i < msg->instancesData.size(); i++)
     {
-        XmlParser parser((char*)instanceData.getData());
+        CIMInstance cimInstance;
 
-        if (!XmlReader::getInstanceElement(parser, cimInstance))
+        // Deserialize instance:
         {
-            cimInstance = CIMInstance();
-        }
-    }
+            XmlParser parser((char*)msg->instancesData[i].getData());
 
-    // Deserialize path:
-    {
-        XmlParser parser((char*)referenceData.getData());
-        CIMObjectPath cimObjectPath;
+            if (!XmlReader::getInstanceElement(parser, cimInstance))
+            {
+                cimInstance = CIMInstance();
+            }
+        }
 
-        if (XmlReader::getInstanceNameElement(parser, cimObjectPath))
+        // Deserialize path:
         {
-            if (!nameSpaceData.isNull())
-                cimObjectPath.setNameSpace(nameSpaceData);
+            XmlParser parser((char*)msg->referencesData[i].getData());
+            CIMObjectPath cimObjectPath;
 
-            if (hostData.size())
-                cimObjectPath.setHost(hostData);
+            if (XmlReader::getInstanceNameElement(parser, cimObjectPath))
+            {
+                if (!msg->nameSpacesData[i].isNull())
+                    cimObjectPath.setNameSpace(msg->nameSpacesData[i]);
 
-            cimInstance.setPath(cimObjectPath);
+                if (msg->hostsData[i].size())
+                    cimObjectPath.setHost(msg->hostsData[i]);
+
+                cimInstance.setPath(cimObjectPath);
+            }
         }
+
+        instances.append(cimInstance);
     }
 
     return true;
 }
 
-static Boolean _resolveNamedInstancesCallback(
-    const Array<ArraySint8>& instancesData,
-    const Array<ArraySint8>& referencesData,
-    const Array<String>& hostsData,
-    const Array<CIMNamespaceName>& nameSpacesData,
-    Array<CIMInstance>& instances)
+static Boolean _resolveBinaryInstance(
+    CIMGetInstanceResponseMessage* msg,
+    CIMInstance& instance)
 {
-    instances.clear();
+    CIMBuffer in((char*)msg->binaryData.getData(), msg->binaryData.size());
 
-    for (Uint32 i = 0; i < instancesData.size(); i++)
+    if (!in.getInstance(instance))
     {
-        CIMInstance ci;
-
-        if (!_resolveNamedInstanceCallback(
-            instancesData[i], 
-            referencesData[i], 
-            hostsData[i],
-            nameSpacesData[i], 
-            ci))
-        {
-            instances.clear();
-            return false;
-        }
-
-        instances.append(ci);
+        instance = CIMInstance();
+        in.release();
+        return false;
     }
 
+    in.release();
     return true;
 }
 
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
-
-CIMGetInstanceResponseMessage*
-CIMBinMsgDeserializer::_getGetInstanceResponseMessage(
-    CIMBuffer& in)
+static Boolean _resolveBinaryInstances(
+    CIMEnumerateInstancesResponseMessage* msg,
+    Array<CIMInstance>& instances)
 {
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
-    Array<Sint8> instanceData;
-    Array<Sint8> referenceData;
-    String hostData;
-    CIMNamespaceName nameSpaceData;
+    instances.clear();
 
-    if (!in.getSint8A(instanceData))
-        return NULL;
+    CIMBuffer in((char*)msg->binaryData.getData(), msg->binaryData.size());
 
-    if (!in.getSint8A(referenceData))
-        return NULL;
+    if (!in.getInstanceA(instances))
+    {
+        in.release();
+        return false;
+    }
 
-    if (!in.getString(hostData))
-        return NULL;
+    in.release();
+    return true;
+}
 
-    if (!in.getNamespaceName(nameSpaceData))
-        return NULL;
+CIMGetInstanceResponseMessage*
+CIMBinMsgDeserializer::_getGetInstanceResponseMessage(
+    CIMBuffer& in,
+    bool binaryResponse)
+{
+    if (binaryResponse)
+    {
+        CIMGetInstanceResponseMessage* msg = new CIMGetInstanceResponseMessage(
+            String::EMPTY,
+            CIMException(),
+            QueueIdStack());
 
-    CIMGetInstanceResponseMessage* msg = new CIMGetInstanceResponseMessage(
-        String::EMPTY,
-        CIMException(),
-        QueueIdStack());
+        if (!in.getUint8A(msg->binaryData))
+            return 0;
 
-    msg->resolveCallback = _resolveInstanceCallback;
-    msg->instanceData = instanceData;
-    msg->referenceData = referenceData;
-    msg->hostData = hostData;
-    msg->nameSpaceData = nameSpaceData;
+        msg->resolveCallback = _resolveBinaryInstance;
+        msg->binaryEncoding = true;
 
-    return msg;
+        return msg;
+    }
+    else
+    {
+        Array<Sint8> instanceData;
+        Array<Sint8> referenceData;
+        String hostData;
+        CIMNamespaceName nameSpaceData;
 
-#else /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+        if (!in.getSint8A(instanceData))
+            return NULL;
 
-    CIMInstance x;
+        if (!in.getSint8A(referenceData))
+            return NULL;
 
-    if (!in.getInstance(x))
-        return 0;
+        if (!in.getString(hostData))
+            return NULL;
 
-    CIMGetInstanceResponseMessage* msg = new CIMGetInstanceResponseMessage(
-        String::EMPTY,
-        CIMException(),
-        QueueIdStack());
+        if (!in.getNamespaceName(nameSpaceData))
+            return NULL;
 
-    msg->setCimInstance(x);
+        CIMGetInstanceResponseMessage* msg = new CIMGetInstanceResponseMessage(
+            String::EMPTY,
+            CIMException(),
+            QueueIdStack());
 
-    return msg;
+        msg->resolveCallback = _resolveXMLInstance;
+        msg->instanceData = instanceData;
+        msg->referenceData = referenceData;
+        msg->hostData = hostData;
+        msg->nameSpaceData = nameSpaceData;
 
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+        return msg;
+    }
 }
 
 CIMDeleteInstanceResponseMessage*
@@ -1749,77 +1770,80 @@ CIMBinMsgDeserializer::_getModifyInstanceResponseMessage(
 
 CIMEnumerateInstancesResponseMessage*
 CIMBinMsgDeserializer::_getEnumerateInstancesResponseMessage(
-    CIMBuffer& in)
+    CIMBuffer& in,
+    bool binaryResponse)
 {
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
-    Uint32 count;
-
-    if (!in.getUint32(count))
-        return 0;
-
-    Array<ArraySint8> instancesData;
-    Array<ArraySint8> referencesData;
-    Array<String> hostsData;
-    Array<CIMNamespaceName> nameSpacesData;
-
-    for (Uint32 i = 0; i < count; i++)
+    if (binaryResponse)
     {
-        Array<Sint8> inst;
-        Array<Sint8> ref;
-        CIMNamespaceName ns;
-        String host;
+        // Inject data into message so that the instances can be deserialized 
+        // on demand later (hopefully never; hopefully it can be written out on
+        // the wire intact).
 
-        if (!in.getSint8A(inst))
-            return 0;
+        CIMEnumerateInstancesResponseMessage* msg;
 
-        if (!in.getSint8A(ref))
-            return 0;
+        msg = new CIMEnumerateInstancesResponseMessage(String::EMPTY,
+            CIMException(), QueueIdStack());
 
-        if (!in.getString(host))
+        if (!in.getUint8A(msg->binaryData))
             return 0;
 
-        if (!in.getNamespaceName(ns))
-            return 0;
+        msg->resolveCallback = _resolveBinaryInstances;
+        msg->binaryEncoding = true;
 
-        instancesData.append(inst);
-        referencesData.append(ref);
-        hostsData.append(host);
-        nameSpacesData.append(ns);
+        return msg;
     }
+    else
+    {
+        Uint32 count;
 
-    CIMEnumerateInstancesResponseMessage* msg;
-    
-    msg = new CIMEnumerateInstancesResponseMessage(
-        String::EMPTY,
-        CIMException(),
-        QueueIdStack());
+        if (!in.getUint32(count))
+            return 0;
 
-    msg->resolveCallback = _resolveNamedInstancesCallback;
-    msg->instancesData = instancesData;
-    msg->referencesData = referencesData;
-    msg->hostsData = hostsData;
-    msg->nameSpacesData = nameSpacesData;
+        Array<ArraySint8> instancesData;
+        Array<ArraySint8> referencesData;
+        Array<String> hostsData;
+        Array<CIMNamespaceName> nameSpacesData;
 
-    return msg;
+        for (Uint32 i = 0; i < count; i++)
+        {
+            Array<Sint8> inst;
+            Array<Sint8> ref;
+            CIMNamespaceName ns;
+            String host;
 
-#else /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+            if (!in.getSint8A(inst))
+                return 0;
 
-    Array<CIMInstance> x;
+            if (!in.getSint8A(ref))
+                return 0;
 
-    if (!in.getInstanceA(x))
-        return 0;
+            if (!in.getString(host))
+                return 0;
 
-    CIMEnumerateInstancesResponseMessage* msg;
+            if (!in.getNamespaceName(ns))
+                return 0;
 
-    msg = new CIMEnumerateInstancesResponseMessage(String::EMPTY,
-        CIMException(), QueueIdStack());
+            instancesData.append(inst);
+            referencesData.append(ref);
+            hostsData.append(host);
+            nameSpacesData.append(ns);
+        }
 
-    msg->setNamedInstances(x);
+        CIMEnumerateInstancesResponseMessage* msg;
+        
+        msg = new CIMEnumerateInstancesResponseMessage(
+            String::EMPTY,
+            CIMException(),
+            QueueIdStack());
 
-    return msg;
+        msg->resolveCallback = _resolveXMLInstances;
+        msg->instancesData = instancesData;
+        msg->referencesData = referencesData;
+        msg->hostsData = hostsData;
+        msg->nameSpacesData = nameSpacesData;
 
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+        return msg;
+    }
 }
 
 CIMEnumerateInstanceNamesResponseMessage*
index f03d48c95231dcb5b596a584c56a036810062cdb..afed84759108e81cdd2fe2b98d5b906a47dcb2bb 100644 (file)
@@ -60,7 +60,8 @@ private:
     PEGASUS_HIDDEN_LINKAGE
     static CIMResponseMessage* _getResponseMessage(
         CIMBuffer& in,
-        MessageType type);
+        MessageType type,
+        bool binaryResponse);
 
     PEGASUS_HIDDEN_LINKAGE
     static Boolean _getUserInfo(
@@ -229,8 +230,8 @@ private:
             (CIMBuffer& in);
 
     PEGASUS_HIDDEN_LINKAGE
-    static CIMGetInstanceResponseMessage*
-        _getGetInstanceResponseMessage(CIMBuffer& in);
+    static CIMGetInstanceResponseMessage* _getGetInstanceResponseMessage(
+        CIMBuffer& in, bool binaryResponse);
 
     PEGASUS_HIDDEN_LINKAGE
     static CIMDeleteInstanceResponseMessage*
@@ -246,7 +247,8 @@ private:
 
     PEGASUS_HIDDEN_LINKAGE
     static CIMEnumerateInstancesResponseMessage*
-        _getEnumerateInstancesResponseMessage(CIMBuffer& in);
+    _getEnumerateInstancesResponseMessage(
+        CIMBuffer& in, bool binaryResponse);
 
     PEGASUS_HIDDEN_LINKAGE
     static CIMEnumerateInstanceNamesResponseMessage*
index 638d6c649a4f08e76ce702eb9848d458ab8b36b2..dec121afb53f653329d6afc31d0f4cae833a1b7e 100644 (file)
@@ -36,8 +36,6 @@
 
 PEGASUS_NAMESPACE_BEGIN
 
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
 void _putXMLInstance(
     CIMBuffer& out,
     const CIMInstance& ci)
@@ -134,8 +132,6 @@ void _putXMLNamedInstance(
     }
 }
 
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
-
 void CIMBinMsgSerializer::serialize(
     CIMBuffer& out, 
     CIMMessage* cimMessage)
@@ -146,6 +142,12 @@ void CIMBinMsgSerializer::serialize(
     // [messageId]
     out.putString(cimMessage->messageId);
 
+    // [binaryRequest]
+    out.putBoolean(cimMessage->binaryRequest);
+
+    // [binaryResponse]
+    out.putBoolean(cimMessage->binaryResponse);
+
     // [type]
     out.putUint32(Uint32(cimMessage->getType()));
 
@@ -1035,15 +1037,17 @@ void CIMBinMsgSerializer::_putGetInstanceResponseMessage(
     CIMBuffer& out,
     CIMGetInstanceResponseMessage* msg)
 {
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
-    _putXMLInstance(out, msg->getCimInstance());
-
-#else /* PEGASUS_ENABLE_ENCAPSULATED_XML */
-
-    out.putInstance(msg->getCimInstance());
-
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+    if (msg->binaryResponse)
+    {
+        CIMBuffer data(4096);
+        data.putInstance(msg->getCimInstance(), false, false);
+        out.putUint32(data.size());
+        out.putBytes(data.getData(), data.size());
+    }
+    else
+    {
+        _putXMLInstance(out, msg->getCimInstance());
+    }
 }
 
 void CIMBinMsgSerializer::_putDeleteInstanceResponseMessage(
@@ -1069,24 +1073,25 @@ void CIMBinMsgSerializer::_putEnumerateInstancesResponseMessage(
     CIMBuffer& out,
     CIMEnumerateInstancesResponseMessage* msg)
 {
-#if defined(PEGASUS_ENABLE_ENCAPSULATED_XML)
-
-    const Array<CIMInstance>& a = msg->getNamedInstances();
-
-    Uint32 n = a.size();
-    out.putUint32(n);
-    Buffer buf(4096);
-
-    for (Uint32 i = 0; i < n; i++)
+    if (msg->binaryResponse)
     {
-        _putXMLNamedInstance(out, a[i]);
+        CIMBuffer data(16 * 4096);
+        data.putInstanceA(msg->getNamedInstances(), false);
+        out.putUint32(data.size());
+        out.putBytes(data.getData(), data.size());
     }
+    else
+    {
+        const Array<CIMInstance>& a = msg->getNamedInstances();
 
-#else /* PEGASUS_ENABLE_ENCAPSULATED_XML */
-
-    out.putInstanceA(msg->getNamedInstances());
+        Uint32 n = a.size();
+        out.putUint32(n);
 
-#endif /* PEGASUS_ENABLE_ENCAPSULATED_XML */
+        for (Uint32 i = 0; i < n; i++)
+        {
+            _putXMLNamedInstance(out, a[i]);
+        }
+    }
 }
 
 void CIMBinMsgSerializer::_putEnumerateInstanceNamesResponseMessage(
index 486a8a5fce43042a160e32263be819ba0e9f6d8d..6c4a946e599a9891d5059c9ceacf3daaedd7b4ed 100644 (file)
@@ -5,6 +5,7 @@
 #include "CIMInstanceRep.h"
 #include "CIMClassRep.h"
 #include "CIMQualifierRep.h"
+#include "CIMQualifierDeclRep.h"
 #include "CIMParameterRep.h"
 #include "CIMMethodRep.h"
 #include "CIMPropertyList.h"
 #include "CIMPropertyListRep.h"
 #include "StringRep.h"
 #include "CIMValueRep.h"
+#include "StringRep.h"
+#include "StringInline.h"
+#include "Buffer.h"
+#include "BinaryCodec.h"
 
 #define INSTANCE_MAGIC 0xD6EF2219
 #define CLASS_MAGIC 0xA8D7DE41
 #define PRESENT_MAGIC 0xF55A7330
 #define ABSENT_MAGIC 0x77A0A639
 
+#define FLAG_IS_NULL             (1 << 0)
+#define FLAG_IS_ARRAY            (1 << 1)
+#define FLAG_IS_PROPAGATED       (1 << 2)
+#define FLAG_HAS_CLASS_ORIGIN    (1 << 3)
+#define FLAG_HAS_REFERENCE_CLASS (1 << 4)
+#define FLAG_HAS_QUALIFIERS      (1 << 5)
+
 PEGASUS_USING_STD;
 
 PEGASUS_NAMESPACE_BEGIN
 
-CIMBuffer::CIMBuffer(size_t size)
+static bool _validString(const Uint16* p, size_t n)
+{
+    const Uint16* start = p;
+
+    while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0)
+    {
+        p += 8;
+        n -= 8;
+    }
+
+    while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0)
+    {
+        p += 4;
+        n -= 4;
+    }
+
+    while (n)
+    {
+        Uint16 c = *p;
+
+        if (c >= 128)
+        {
+            if (c == 0xFFFE || c == 0xFFFF || (c >= 0xFDD0 && c <= 0xFDEF))
+                return false;
+
+            if (c >= 0xD800 && c <= 0xDBFF)
+            {
+                if (n == 1 || !(p[1] >= 0xDC00 && p[1] <= 0xDFFF))
+                    return false;
+            }
+
+            if (c >= 0xDC00 && c <= 0xDFFF)
+            {
+                if (p == start || !(p[-1] >= 0xD800  && p[-1] <= 0xDBFF))
+                    return false;
+            }
+        }
+
+        n--;
+        p++;
+    }
+
+    return true;
+}
+
+static inline bool _validName(const String& str)
+{
+    if (str.size() == 0)
+        return true;
+
+    return CIMName::legal(str);
+}
+
+static inline bool _validNamespaceName(const String& str)
+{
+    if (str.size() == 0)
+        return true;
+
+    return CIMNamespaceName::legal(str);
+}
+
+void CIMBuffer::_create(size_t size)
 {
     if (size < 1024)
         size = 1024;
 
 #if defined(PEGASUS_TEST_VALGRIND)
     // Valgrind complains that we leave uninitialized bytes in this buffer so
-    // we clear all newly allocated memory when testing with Valgrind.
     _data = (char*)calloc(1, size);
 #else
     _data = (char*)malloc(size);
 #endif
 
+#if defined(PEGASUS_DEBUG)
+    memset(_data, 0xAA, size);
+#endif
+
     if (!_data)
     {
         throw PEGASUS_STD(bad_alloc)();
@@ -50,6 +126,15 @@ CIMBuffer::CIMBuffer(size_t size)
     _ptr = _data;
 }
 
+CIMBuffer::CIMBuffer(size_t size) : _swap(0), _validate(0)
+{
+    _create(size);
+}
+
+CIMBuffer::CIMBuffer() : _data(0), _end(0), _ptr(0), _swap(0), _validate(0)
+{
+}
+
 CIMBuffer::~CIMBuffer()
 {
     free(_data);
@@ -61,6 +146,9 @@ void CIMBuffer::_grow(size_t size)
     size_t m = _ptr - _data;
     size_t cap = n * 2;
 
+    if (cap <= 4096)
+        cap = 4096;
+
     // Double the size of the buffer (n * 2). If size is greater than n, then
     // we will need yet more space so we increment cap by size.
 
@@ -76,11 +164,15 @@ void CIMBuffer::_grow(size_t size)
 
     _end = _data + cap;
     _ptr = _data + m;
-#if defined(PEGASUS_TEST_VALGRIND)
+
+#if defined(PEGASUS_DEBUG)
+    memset(_ptr, 0xAA, _end - _ptr);
+#elif defined(PEGASUS_TEST_VALGRIND)
     // Valgrind complains that we leave uninitialized bytes in this buffer so
     // we clear all newly allocated memory when testing with Valgrind.
     memset(_ptr, 0, _end - _ptr);
 #endif
+
 }
 
 bool CIMBuffer::getString(String& x)
@@ -95,43 +187,122 @@ bool CIMBuffer::getString(String& x)
     if (_end - _ptr < ptrdiff_t(r))
         return false;
 
-    if (n)
+    if (_swap)
     {
-        x.assign((Char16*)_ptr, n);
+        _swapUint16Data((Uint16*)_ptr, n);
+    }
+
+    if (_validate)
+    {
+        if (!_validString((Uint16*)_ptr, n))
+            return false;
     }
 
+    if (n)
+        x.assign((Char16*)_ptr, n);
+
     _ptr += r;
     return true;
 }
 
+bool CIMBuffer::getName(CIMName& x)
+{
+    String tmp;
+
+    if (_validate)
+    {
+        // Get string without validation since we will validate name below.
+
+        _validate = false;
+
+        if (!getString(tmp))
+            return false;
+
+        _validate = true;
+
+        if (!_validName(tmp))
+            return false;
+    }
+    else
+    {
+        if (!getString(tmp))
+            return false;
+    }
+
+    x = CIMNameCast(tmp);
+    return true;
+}
+
+bool CIMBuffer::getNamespaceName(CIMNamespaceName& x)
+{
+    String tmp;
+
+    if (_validate)
+    {
+        // Get string without validation since we will validate namespace below.
+
+        _validate = false;
+
+        if (!getString(tmp))
+            return false;
+
+        _validate = true;
+
+        if (!_validNamespaceName(tmp))
+            return false;
+    }
+    else
+    {
+        if (!getString(tmp))
+            return false;
+    }
+
+    x = CIMNamespaceNameCast(tmp);
+    return true;
+}
+
 void CIMBuffer::putValue(const CIMValue& x)
 {
-#if defined(PEGASUS_USE_EMBEDDED_VALUES)
-    CIMValueRep* rep = ((CIMValueRep*)&x);
-#else
     CIMValueRep* rep = *((CIMValueRep**)&x);
-#endif
 
-    _putMagic(VALUE_MAGIC);
-    putUint32(rep->type);
-    putBoolean(rep->isArray);
+    // Resolve null flag:
+
+    bool isNull = rep->isNull;
 
-    if (rep->type == CIMTYPE_INSTANCE && !rep->isArray)
+    if (!isNull && rep->type == CIMTYPE_INSTANCE && !rep->isArray)
     {
         const CIMInstance& ci = *((CIMInstance*)rep->u._instanceValue);
 
         if (ci.isUninitialized())
         {
-            putBoolean(rep->isNull);
-            return;
+            isNull = true;
         }
     }
 
-    putBoolean(rep->isNull);
+    // Magic:
+    _putMagic(VALUE_MAGIC);
+
+    // Put flags:
+    {
+        Uint32 flags = 0;
+
+        if (isNull)
+            flags |= FLAG_IS_NULL;
+
+        if (rep->isArray)
+            flags |= FLAG_IS_ARRAY;
+
+        putUint32(flags);
+    }
+
+    // Type:
+    putUint32(rep->type);
 
-    if (rep->isNull)
+    if (isNull)
         return;
 
+    // Put value:
+
     if (rep->isArray)
     {
         switch (rep->type)
@@ -183,10 +354,12 @@ void CIMBuffer::putValue(const CIMValue& x)
                     *(reinterpret_cast<Array<CIMObjectPath>*>(&rep->u)));
                 break;
             case CIMTYPE_INSTANCE:
-                putInstanceA(*(reinterpret_cast<Array<CIMInstance>*>(&rep->u)));
+                putInstanceA(*(reinterpret_cast<Array<CIMInstance>*>(&rep->u)), 
+                    false, false);
                 break;
             case CIMTYPE_OBJECT:
-                putObjectA(*(reinterpret_cast<Array<CIMObject>*>(&rep->u)));
+                putObjectA(*(reinterpret_cast<Array<CIMObject>*>(&rep->u)),
+                    false, false);
                 break;
             default:
                 PEGASUS_ASSERT(0);
@@ -243,10 +416,10 @@ void CIMBuffer::putValue(const CIMValue& x)
                 putObjectPath(*((CIMObjectPath*)rep->u._referenceValue));
                 break;
             case CIMTYPE_INSTANCE:
-                putInstance(*((CIMInstance*)rep->u._instanceValue));
+                putInstance(*((CIMInstance*)rep->u._instanceValue),false,false);
                 break;
             case CIMTYPE_OBJECT:
-                putObject(*((CIMObject*)rep->u._instanceValue));
+                putObject(*((CIMObject*)rep->u._instanceValue), false, false);
                 break;
             default:
                 PEGASUS_ASSERT(0);
@@ -258,13 +431,24 @@ void CIMBuffer::putValue(const CIMValue& x)
 bool CIMBuffer::getValue(CIMValue& x)
 {
     Uint32 type;
-    Boolean isArray;
     Boolean isNull;
+    Boolean isArray;
 
+    // Magic:
     if (!_testMagic(VALUE_MAGIC))
         return false;
 
-    if (!getUint32(type) || !getBoolean(isArray) || !getBoolean(isNull))
+    // Flags:
+    Uint32 flags;
+
+    if (!getUint32(flags))
+        return false;
+
+    isNull = flags & FLAG_IS_NULL;
+    isArray = flags & FLAG_IS_ARRAY;
+
+    // Type:
+    if (!getUint32(type))
         return false;
 
     if (isNull)
@@ -571,27 +755,30 @@ bool CIMBuffer::getValue(CIMValue& x)
 void CIMBuffer::putKeyBinding(const CIMKeyBinding& x)
 {
     const CIMKeyBindingRep* kb = *(const CIMKeyBindingRep**)&x;
-    putString(kb->_name.getString());
+    putName(kb->_name);
     putString(kb->_value);
     putUint32(kb->_type);
 }
 
 bool CIMBuffer::getKeyBinding(CIMKeyBinding& x)
 {
-    String name;
+    CIMName name;
     String value;
     Uint32 type;
 
-    if (!getString(name) || !getString(value) || !getUint32(type))
+    if (!getName(name) || !getString(value) || !getUint32(type))
         return false;
 
     x.~CIMKeyBinding();
-    new(&x) CIMKeyBinding(CIMNameCast(name), value, CIMKeyBinding::Type(type));
+    new(&x) CIMKeyBinding(name, value, CIMKeyBinding::Type(type));
 
     return true;
 }
 
-void CIMBuffer::putObjectPath(const CIMObjectPath& x)
+void CIMBuffer::putObjectPath(
+    const CIMObjectPath& x, 
+    bool includeHostAndNamespace,
+    bool includeKeyBindings)
 {
     const CIMObjectPathRep* rep = *((const CIMObjectPathRep**)&x);
 
@@ -605,22 +792,38 @@ void CIMBuffer::putObjectPath(const CIMObjectPath& x)
     else
         putBoolean(true);
 
-    putString(rep->_host);
-    putString(rep->_nameSpace.getString());
-    putString(rep->_className.getString());
-    putUint32(rep->_keyBindings.size());
 
-    for (Uint32 i = 0, n = rep->_keyBindings.size(); i < n; i++)
+    if (includeHostAndNamespace)
+    {
+        putString(rep->_host);
+        putNamespaceName(rep->_nameSpace);
+    }
+    else
     {
-        putKeyBinding(rep->_keyBindings[i]);
+        putString(String());
+        putString(String());
+    }
+
+    putName(rep->_className);
+
+    if (includeKeyBindings)
+    {
+        putUint32(rep->_keyBindings.size());
+
+        for (Uint32 i = 0, n = rep->_keyBindings.size(); i < n; i++)
+        {
+            putKeyBinding(rep->_keyBindings[i]);
+        }
     }
+    else
+        putUint32(0);
 }
 
 bool CIMBuffer::getObjectPath(CIMObjectPath& x)
 {
     String host;
-    String nameSpace;
-    String className;
+    CIMNamespaceName nameSpace;
+    CIMName className;
     Uint32 size;
     Array<CIMKeyBinding> kbs;
 
@@ -638,7 +841,7 @@ bool CIMBuffer::getObjectPath(CIMObjectPath& x)
         return true;
     }
 
-    if (!getString(host) || !getString(nameSpace) || !getString(className))
+    if (!getString(host) || !getNamespaceName(nameSpace) || !getName(className))
         return false;
 
     if (!getUint32(size))
@@ -657,7 +860,7 @@ bool CIMBuffer::getObjectPath(CIMObjectPath& x)
     x.set(
         host,
         *(reinterpret_cast<CIMNamespaceName*>(&nameSpace)),
-        CIMNameCast(className),
+        className,
         kbs);
 
     return true;
@@ -667,7 +870,7 @@ void CIMBuffer::putQualifier(const CIMQualifier& x)
 {
     const CIMQualifierRep* rep = *((const CIMQualifierRep**)&x);
 
-    putString(rep->_name.getString());
+    putName(rep->_name);
     putValue(rep->_value);
     putUint32(*((Uint32*)&rep->_flavor));
     putBoolean(rep->_propagated);
@@ -675,12 +878,12 @@ void CIMBuffer::putQualifier(const CIMQualifier& x)
 
 bool CIMBuffer::getQualifier(CIMQualifier& x)
 {
-    String name;
+    CIMName name;
     CIMValue value;
     Uint32 flavor;
     Boolean propagated;
 
-    if (!getString(name))
+    if (!getName(name))
         return false;
 
     if (!getValue(value))
@@ -695,7 +898,7 @@ bool CIMBuffer::getQualifier(CIMQualifier& x)
     x.~CIMQualifier();
 
     new(&x) CIMQualifier(
-        CIMNameCast(name),
+        name,
         value,
         *(reinterpret_cast<CIMFlavor*>(&flavor)),
         propagated);
@@ -732,49 +935,146 @@ bool CIMBuffer::getQualifierList(CIMQualifierList& x)
     return true;
 }
 
+void CIMBuffer::putQualifierDecl(const CIMQualifierDecl& x)
+{
+    const CIMQualifierDeclRep* rep = *((const CIMQualifierDeclRep**)&x);
+
+    putName(rep->_name);
+    putValue(rep->_value);
+    putUint32(*((Uint32*)&rep->_scope));
+    putUint32(*((Uint32*)&rep->_flavor));
+    putUint32(rep->_arraySize);
+}
+
+bool CIMBuffer::getQualifierDecl(CIMQualifierDecl& x)
+{
+    CIMName name;
+    CIMValue value;
+    Uint32 scope;
+    Uint32 flavor;
+    Uint32 arraySize;
+
+    if (!getName(name))
+        return false;
+
+    if (!getValue(value))
+        return false;
+
+    if (!getUint32(scope))
+        return false;
+
+    if (!getUint32(flavor))
+        return false;
+
+    if (!getUint32(arraySize))
+        return false;
+
+    x.~CIMQualifierDecl();
+
+    new(&x) CIMQualifierDecl(
+        name,
+        value,
+        *(reinterpret_cast<CIMScope*>(&scope)),
+        *(reinterpret_cast<CIMFlavor*>(&flavor)),
+        arraySize);
+
+    return true;
+}
+
 void CIMBuffer::putProperty(const CIMProperty& x)
 {
     const CIMPropertyRep* rep = *((const CIMPropertyRep**)&x);
-
     // PROPERTY_MAGIC
     _putMagic(PROPERTY_MAGIC);
 
+    // Flags
+    Uint32 flags = 0;
+    {
+        // CIMProperty.arraySize
+        if (rep->_arraySize)
+        {
+            flags |= FLAG_IS_ARRAY;
+        }
+
+        // CIMProperty.referenceClassName
+        if (rep->_referenceClassName.getString().size())
+        {
+            flags |= FLAG_HAS_REFERENCE_CLASS;
+        }
+
+        // CIMProperty.classOrigin
+        if (rep->_classOrigin.getString().size())
+        {
+            flags |= FLAG_HAS_CLASS_ORIGIN;
+        }
+
+        // CIMProperty.propagated
+        if (rep->_propagated)
+        {
+            flags |= FLAG_IS_PROPAGATED;
+        }
+
+        // CIMProperty.qualifiers
+        if (rep->_qualifiers.getCount())
+        {
+            flags |= FLAG_HAS_QUALIFIERS;
+        }
+
+        putUint32(flags);
+    }
+
     // CIMProperty.name
-    putString(rep->_name.getString());
+    putName(rep->_name);
 
     // CIMProperty.value
     putValue(rep->_value);
 
     // CIMProperty.arraySize
-    putUint32(rep->_arraySize);
+    if (flags & FLAG_IS_ARRAY)
+    {
+        putUint32(rep->_arraySize);
+    }
 
     // CIMProperty.referenceClassName
-    putString(rep->_referenceClassName.getString());
+    if (flags & FLAG_HAS_REFERENCE_CLASS)
+    {
+        putName(rep->_referenceClassName);
+    }
 
     // CIMProperty.classOrigin
-    putString(rep->_classOrigin.getString());
-
-    // CIMProperty.propagated
-    putBoolean(rep->_propagated);
+    if (flags & FLAG_HAS_CLASS_ORIGIN)
+    {
+        putName(rep->_classOrigin);
+    }
 
     // CIMProperty.qualifiers
-    putQualifierList(rep->_qualifiers);
+    if (flags & FLAG_HAS_QUALIFIERS)
+    {
+        putQualifierList(rep->_qualifiers);
+        flags |= FLAG_HAS_QUALIFIERS;
+    }
 }
 
 bool CIMBuffer::getProperty(CIMProperty& x)
 {
-    String name;
+    CIMName name;
     CIMValue value;
     Uint32 arraySize;
-    String referenceClassName;
-    String classOrigin;
+    CIMName referenceClassName;
+    CIMName classOrigin;
     Boolean propagated;
 
     if (!_testMagic(PROPERTY_MAGIC))
         return false;
 
+    // Flags:
+    Uint32 flags;
+
+    if (!getUint32(flags))
+        return false;
+
     // CIMProperty.name
-    if (!getString(name))
+    if (!getName(name))
         return false;
 
     // CIMProperty.value
@@ -782,41 +1082,63 @@ bool CIMBuffer::getProperty(CIMProperty& x)
         return false;
 
     // CIMProperty.arraySize
-    if (!getUint32(arraySize))
-        return false;
+
+    if (flags & FLAG_IS_ARRAY)
+    {
+        if (!getUint32(arraySize))
+            return false;
+    }
+    else
+        arraySize = 0;
 
     // CIMProperty.referenceClassName
-    if (!getString(referenceClassName))
-        return false;
+
+    if (flags & FLAG_HAS_REFERENCE_CLASS)
+    {
+        if (!getName(referenceClassName))
+            return false;
+    }
 
     // CIMProperty.classOrigin
-    if (!getString(classOrigin))
-        return false;
+
+    if (flags & FLAG_HAS_CLASS_ORIGIN)
+    {
+        if (!getName(classOrigin))
+            return false;
+    }
 
     // CIMProperty.propagated
-    if (!getBoolean(propagated))
-        return false;
+    propagated = flags & FLAG_IS_PROPAGATED;
+
+    // Create property:
 
     x.~CIMProperty();
 
     new(&x) CIMProperty(
-        CIMNameCast(name),
+        name,
         value,
         arraySize,
-        CIMNameCast(referenceClassName),
-        CIMNameCast(classOrigin),
+        referenceClassName,
+        classOrigin,
         propagated);
 
     CIMPropertyRep* rep = *((CIMPropertyRep**)&x);
 
     // CIMProperty.qualifiers
-    if (!getQualifierList(rep->_qualifiers))
-        return false;
+
+    if (flags & FLAG_HAS_QUALIFIERS)
+    {
+        if (!getQualifierList(rep->_qualifiers))
+            return false;
+    }
 
     return true;
 }
 
-void CIMBuffer::putInstance(const CIMInstance& x)
+void CIMBuffer::putInstance(
+    const CIMInstance& x, 
+    bool includeHostAndNamespace,
+    bool includeKeyBindings)
 {
     const CIMInstanceRep* rep = *((const CIMInstanceRep**)&x);
 
@@ -834,7 +1156,7 @@ void CIMBuffer::putInstance(const CIMInstance& x)
         putBoolean(true);
 
     // CIMInstance.reference:
-    putObjectPath(rep->_reference);
+    putObjectPath(rep->_reference, includeHostAndNamespace, includeKeyBindings);
 
     // CIMInstance.qualifiers:
     putQualifierList(rep->_qualifiers);
@@ -937,7 +1259,7 @@ void CIMBuffer::putClass(const CIMClass& x)
     putObjectPath(rep->_reference);
 
     // CIMClass.superClassName:
-    putString(rep->_superClassName.getString());
+    putName(rep->_superClassName);
 
     // CIMClass.qualifiers:
     putQualifierList(rep->_qualifiers);
@@ -964,8 +1286,7 @@ void CIMBuffer::putClass(const CIMClass& x)
 bool CIMBuffer::getClass(CIMClass& x)
 {
     CIMClassRep* rep;
-    String className;
-    String superClassName;
+    CIMName superClassName;
 
     // CLASS_MAGIC:
 
@@ -994,11 +1315,11 @@ bool CIMBuffer::getClass(CIMClass& x)
 
     // CIMIntsance.superClassName:
 
-    if (!getString(superClassName))
+    if (!getName(superClassName))
         return false;
 
     rep = new CIMClassRep(reference.getClassName(), 
-        CIMNameCast(superClassName));
+        superClassName);
 
     rep->_reference = reference;
 
@@ -1059,7 +1380,7 @@ void CIMBuffer::putParameter(const CIMParameter& x)
     const CIMParameterRep* rep = *((const CIMParameterRep**)&x);
 
     // CIMParameter.name
-    putString(rep->_name.getString());
+    putName(rep->_name);
 
     // CIMParameter.type
     putUint32(rep->_type);
@@ -1071,7 +1392,7 @@ void CIMBuffer::putParameter(const CIMParameter& x)
     putUint32(rep->_arraySize);
 
     // CIMParameter.referenceClassName
-    putString(rep->_referenceClassName.getString());
+    putName(rep->_referenceClassName);
 
     // CIMParameter.qualifiers
     putQualifierList(rep->_qualifiers);
@@ -1079,14 +1400,14 @@ void CIMBuffer::putParameter(const CIMParameter& x)
 
 bool CIMBuffer::getParameter(CIMParameter& x)
 {
-    String name;
+    CIMName name;
     Uint32 type;
     Boolean isArray;
     Uint32 arraySize;
-    String referenceClassName;
+    CIMName referenceClassName;
 
     // CIMParameter.name
-    if (!getString(name))
+    if (!getName(name))
         return false;
 
     // CIMParameter.type
@@ -1102,17 +1423,17 @@ bool CIMBuffer::getParameter(CIMParameter& x)
         return false;
 
     // CIMParameter.referenceClassName
-    if (!getString(referenceClassName))
+    if (!getName(referenceClassName))
         return false;
 
     x.~CIMParameter();
 
     new(&x) CIMParameter(
-        CIMNameCast(name),
+        name,
         CIMType(type),
         isArray,
         arraySize,
-        CIMNameCast(referenceClassName));
+        referenceClassName);
 
     CIMParameterRep* rep = *((CIMParameterRep**)&x);
 
@@ -1128,13 +1449,13 @@ void CIMBuffer::putMethod(const CIMMethod& x)
     const CIMMethodRep* rep = *((const CIMMethodRep**)&x);
 
     // CIMParameter.name
-    putString(rep->_name.getString());
+    putName(rep->_name);
 
     // CIMParameter.type
     putUint32(rep->_type);
 
     // CIMProperty.classOrigin
-    putString(rep->_classOrigin.getString());
+    putName(rep->_classOrigin);
 
     // CIMProperty.propagated
     putBoolean(rep->_propagated);
@@ -1155,14 +1476,13 @@ void CIMBuffer::putMethod(const CIMMethod& x)
 bool CIMBuffer::getMethod(CIMMethod& x)
 {
     CIMMethodRep* rep;
-
-    String name;
+    CIMName name;
     Uint32 type;
-    String classOrigin;
+    CIMName classOrigin;
     Boolean propagated;
 
     // CIMMethod.name
-    if (!getString(name))
+    if (!getName(name))
         return false;
 
     // CIMMethod.type
@@ -1170,14 +1490,15 @@ bool CIMBuffer::getMethod(CIMMethod& x)
         return false;
 
     // CIMParameter.classOrigin
-    if (!getString(classOrigin))
+    if (!getName(classOrigin))
         return false;
 
     // CIMParameter.propagated
     if (!getBoolean(propagated))
         return false;
 
-    rep = new CIMMethodRep(name, CIMType(type), classOrigin, propagated);
+    rep = new CIMMethodRep(
+        name, CIMType(type), classOrigin, propagated);
 
     // CIMMethod.qualifiers:
     if (!getQualifierList(rep->_qualifiers))
@@ -1225,7 +1546,7 @@ void CIMBuffer::putPropertyList(const CIMPropertyList& x)
         putUint32(n);
 
         for (Uint32 i = 0; i < n; i++)
-            putString(rep->propertyNames[i].getString());
+            putName(rep->propertyNames[i]);
     }
 }
 
@@ -1252,12 +1573,12 @@ bool CIMBuffer::getPropertyList(CIMPropertyList& x)
 
         for (Uint32 i = 0; i < n; i++)
         {
-            String name;
+            CIMName name;
 
-            if (!getString(name))
+            if (!getName(name))
                 return false;
 
-            names.append(CIMNameCast(name));
+            names.append(name);
         }
 
         x.~CIMPropertyList();
@@ -1267,7 +1588,10 @@ bool CIMBuffer::getPropertyList(CIMPropertyList& x)
     return true;
 }
 
-void CIMBuffer::putObject(const CIMObject& x)
+void CIMBuffer::putObject(
+    const CIMObject& x,
+    bool includeHostAndNamespace,
+    bool includeKeyBindings)
 {
     _putMagic(OBJECT_MAGIC);
 
@@ -1282,7 +1606,8 @@ void CIMBuffer::putObject(const CIMObject& x)
     if (x.isInstance())
     {
         putUint8('I');
-        putInstance(CIMInstance(x));
+        putInstance(
+            CIMInstance(x), includeHostAndNamespace, includeKeyBindings);
     }
     else
     {
@@ -1405,4 +1730,16 @@ bool CIMBuffer::getPresent(Boolean& flag)
     return false;
 }
 
+void CIMBuffer::putInstanceA(
+    const Array<CIMInstance>& x, 
+    bool includeHostAndNamespace,
+    bool includeKeyBindings)
+{
+    Uint32 n = x.size();
+    putUint32(n);
+
+    for (size_t i = 0; i < n; i++)
+        putInstance(x[i], includeHostAndNamespace, includeKeyBindings);
+}
+
 PEGASUS_NAMESPACE_END
index 9601f83f1bf8f78965cf88c31a5287e417efdd8e..0ecdcd0e244b63eeca732b278e688f8d1495d3b8 100644 (file)
@@ -5,7 +5,9 @@
 #include <Pegasus/Common/CIMInstance.h>
 #include <Pegasus/Common/CIMClass.h>
 #include <Pegasus/Common/CIMQualifierList.h>
+#include <Pegasus/Common/CIMQualifierDecl.h>
 #include <Pegasus/Common/CIMParamValue.h>
+#include <Pegasus/Common/Buffer.h>
 #include <Pegasus/Common/CIMNameCast.h>
 
 #define PEGASUS_USE_MAGIC
@@ -21,11 +23,21 @@ PEGASUS_NAMESPACE_BEGIN
     protocols since it sacrifices size for performance; Whereas the Packer
     class is more suitable for disk storage since it favors size over 
     performance.
+
+    CIMBuffer handles network byte ordering. It uses a "reader makes right"
+    policy whereby the writing process sends data in his own endianess,
+    which he comminicates to the reading process (using a mechanism defined
+    outside of this class). The reader checks to see if that endianess is
+    the same as his own. If so, the data is used as is. Otherwise, the
+    reader calls CIMBuffer::setSwap(true) to cause subsequent get calls to 
+    swap data ordering.
 */
 class PEGASUS_COMMON_LINKAGE CIMBuffer
 {
 public:
 
+    CIMBuffer();
+
     CIMBuffer(size_t size);
 
     CIMBuffer(char* data, size_t size)
@@ -33,10 +45,27 @@ public:
         _data = data;
         _ptr = _data;
         _end = data + size;
+        _swap = 0;
+        _validate = 0;
     }
 
     ~CIMBuffer();
 
+    void setSwap(bool x)
+    {
+        _swap = x ? 1 : 0;
+    }
+
+    void setValidate(bool x)
+    {
+        _validate = x ? 1 : 0;
+    }
+
+    bool more() const
+    {
+        return _ptr != _end;
+    }
+
     void rewind()
     {
         _ptr = _data;
@@ -57,6 +86,20 @@ public:
         return _data;
     }
 
+    const char* getPtr() const 
+    {
+        return _ptr;
+    }
+
+    char* release()
+    {
+        char* data = _data;
+        _data = 0;
+        _ptr = 0;
+        _end = 0;
+        return data;
+    }
+
     static size_t round(size_t size)
     {
         /* Round up to nearest multiple of 8 */
@@ -68,7 +111,7 @@ public:
         if (_end - _ptr < 8)
             _grow(sizeof(x));
 
-        *((Boolean*)_ptr) = x;
+        *((Uint8*)_ptr) = x ? 1 : 0;
         _ptr += 8;
     }
 
@@ -199,7 +242,16 @@ public:
     {
         Uint32 n = x.size();
         putUint32(n);
-        putBytes(x.getData(), n * sizeof(Boolean));
+
+        size_t r = round(n);
+
+        if (_end - _ptr < ptrdiff_t(r))
+            _grow(r);
+
+        for (Uint32 i = 0; i < n; i++)
+            _ptr[i] = x[i] ? 1 : 0;
+
+        _ptr += r;
     }
 
     void putUint8A(const Array<Uint8>& x)
@@ -297,12 +349,24 @@ public:
             putDateTime(x[i]);
     }
 
+    bool getBytes(void* data, size_t size)
+    {
+        size_t r = round(size);
+
+        if (_end - _ptr < ptrdiff_t(r))
+            return false;
+
+        memcpy(data, _ptr, size);
+        _ptr += r;
+        return true;
+    }
+
     bool getBoolean(Boolean& x)
     {
         if (_end - _ptr < 8)
             return false;
 
-        x = *((Boolean*)_ptr);
+        x = *((Uint8*)_ptr);
         _ptr += 8;
         return true;
     }
@@ -333,6 +397,10 @@ public:
             return false;
 
         x = *((Uint16*)_ptr);
+
+        if (_swap)
+            x = _swapUint16(x);    
+
         _ptr += 8;
         return true;
     }
@@ -343,6 +411,10 @@ public:
             return false;
 
         x = *((Sint16*)_ptr);
+
+        if (_swap)
+            x = _swapSint16(x);    
+
         _ptr += 8;
         return true;
     }
@@ -353,6 +425,10 @@ public:
             return false;
 
         x = *((Uint32*)_ptr);
+
+        if (_swap)
+            x = _swapUint32(x);    
+
         _ptr += 8;
         return true;
     }
@@ -363,6 +439,10 @@ public:
             return false;
 
         x = *((Sint32*)_ptr);
+
+        if (_swap)
+            x = _swapSint32(x);    
+
         _ptr += 8;
         return true;
     }
@@ -373,6 +453,10 @@ public:
             return false;
 
         x = *((Uint64*)_ptr);
+
+        if (_swap)
+            x = _swapUint64(x);    
+
         _ptr += 8;
         return true;
     }
@@ -383,6 +467,10 @@ public:
             return false;
 
         x = *((Sint64*)_ptr);
+
+        if (_swap)
+            x = _swapSint64(x);    
+
         _ptr += 8;
         return true;
     }
@@ -393,6 +481,10 @@ public:
             return false;
 
         x = *((Real32*)_ptr);
+
+        if (_swap)
+            x = _swapReal32(x);    
+
         _ptr += 8;
         return true;
     }
@@ -403,6 +495,10 @@ public:
             return false;
 
         x = *((Real64*)_ptr);
+
+        if (_swap)
+            x = _swapReal64(x);    
+
         _ptr += 8;
         return true;
     }
@@ -413,6 +509,10 @@ public:
             return false;
 
         x = *((Char16*)_ptr);
+
+        if (_swap)
+            x = _swapChar16(x);
+
         _ptr += 8;
         return true;
     }
@@ -442,12 +542,16 @@ public:
         if (!getUint32(n))
             return false;
 
-        size_t r = round(n * sizeof(Boolean));
+        size_t r = round(n);
 
         if (_end - _ptr < ptrdiff_t(r))
             return false;
 
-        x.append((const Boolean*)_ptr, n);
+        for (Uint32 i = 0; i < n; i++)
+        {
+            x.append(_ptr[i]);
+        }
+
         _ptr += r;
         return true;
     }
@@ -499,6 +603,10 @@ public:
             return false;
 
         x.append((const Uint16*)_ptr, n);
+
+        if (_swap)
+            _swapUint16Data((Uint16*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -516,6 +624,10 @@ public:
             return false;
 
         x.append((const Sint16*)_ptr, n);
+
+        if (_swap)
+            _swapSint16Data((Sint16*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -533,6 +645,10 @@ public:
             return false;
 
         x.append((const Uint32*)_ptr, n);
+
+        if (_swap)
+            _swapUint32Data((Uint32*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -550,6 +666,10 @@ public:
             return false;
 
         x.append((const Sint32*)_ptr, n);
+
+        if (_swap)
+            _swapSint32Data((Sint32*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -567,6 +687,10 @@ public:
             return false;
 
         x.append((const Uint64*)_ptr, n);
+
+        if (_swap)
+            _swapUint64Data((Uint64*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -584,6 +708,10 @@ public:
             return false;
 
         x.append((const Sint64*)_ptr, n);
+
+        if (_swap)
+            _swapSint64Data((Sint64*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -601,6 +729,10 @@ public:
             return false;
 
         x.append((const Real32*)_ptr, n);
+
+        if (_swap)
+            _swapReal32Data((Real32*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -618,6 +750,10 @@ public:
             return false;
 
         x.append((const Real64*)_ptr, n);
+
+        if (_swap)
+            _swapReal64Data((Real64*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -635,6 +771,10 @@ public:
             return false;
 
         x.append((const Char16*)_ptr, n);
+
+        if (_swap)
+            _swapChar16Data((Char16*)x.getData(), x.size());
+
         _ptr += r;
         return true;
     }
@@ -687,7 +827,13 @@ public:
 
     bool getKeyBinding(CIMKeyBinding& x);
 
-    void putObjectPath(const CIMObjectPath& x);
+    // To omit the host and namespace elements of the object path, set
+    // includeHostAndNamespace to false. This is required for compatibility with
+    // XML transmission of instances, which excludes these elements.
+    void putObjectPath(
+        const CIMObjectPath& x, 
+        bool includeHostAndNamespace = true,
+        bool includeKeyBindings = true);
 
     bool getObjectPath(CIMObjectPath& x);
 
@@ -699,11 +845,18 @@ public:
 
     bool getQualifierList(CIMQualifierList& x);
 
+    void putQualifierDecl(const CIMQualifierDecl& x);
+
+    bool getQualifierDecl(CIMQualifierDecl& x);
+
     void putProperty(const CIMProperty& x);
 
     bool getProperty(CIMProperty& x);
 
-    void putInstance(const CIMInstance& x);
+    void putInstance(
+        const CIMInstance& x, 
+        bool includeHostAndNamespace = true,
+        bool includeKeyBindings = true);
 
     bool getInstance(CIMInstance& x);
 
@@ -723,7 +876,9 @@ public:
 
     bool getPropertyList(CIMPropertyList& x);
 
-    void putObject(const CIMObject& x);
+    void putObject(const CIMObject& x,
+        bool includeHostAndNamespace = true,
+        bool includeKeyBindings = true);
 
     bool getObject(CIMObject& x);
 
@@ -741,27 +896,9 @@ public:
         putString(x.getString());
     }
 
-    bool getName(CIMName& x)
-    {
-        String tmp;
+    bool getName(CIMName& x);
 
-        if (!getString(tmp))
-            return false;
-
-        x = CIMNameCast(tmp);
-        return true;
-    }
-
-    bool getNamespaceName(CIMNamespaceName& x)
-    {
-        String tmp;
-
-        if (!getString(tmp))
-            return false;
-
-        x = CIMNamespaceNameCast(tmp);
-        return true;
-    }
+    bool getNamespaceName(CIMNamespaceName& x);
 
     void putNameA(const Array<CIMName>& x)
     {
@@ -792,13 +929,15 @@ public:
         return true;
     }
 
-    void putObjectPathA(const Array<CIMObjectPath>& x)
+    void putObjectPathA(
+        const Array<CIMObjectPath>& x, 
+        bool includeHostAndNamespace = true)
     {
         Uint32 n = x.size();
         putUint32(n);
 
         for (size_t i = 0; i < n; i++)
-            putObjectPath(x[i]);
+            putObjectPath(x[i], includeHostAndNamespace);
     }
 
     bool getObjectPathA(Array<CIMObjectPath>& x)
@@ -821,16 +960,41 @@ public:
         return true;
     }
 
-    void putInstanceA(const Array<CIMInstance>& x)
+    void putInstanceA(
+        const Array<CIMInstance>& x, 
+        bool includeHostAndNamespace = true,
+        bool includeKeyBindings = true);
+
+    bool getInstanceA(Array<CIMInstance>& x)
+    {
+        Uint32 n;
+
+        if (!getUint32(n))
+            return false;
+
+        for (Uint32 i = 0; i < n; i++)
+        {
+            CIMInstance tmp;
+
+            if (!getInstance(tmp))
+                return false;
+
+            x.append(tmp);
+        }
+
+        return true;
+    }
+
+    void putClassA(const Array<CIMClass>& x)
     {
         Uint32 n = x.size();
         putUint32(n);
 
         for (size_t i = 0; i < n; i++)
-            putInstance(x[i]);
+            putClass(x[i]);
     }
 
-    bool getInstanceA(Array<CIMInstance>& x)
+    bool getClassA(Array<CIMClass>& x)
     {
         Uint32 n;
 
@@ -839,9 +1003,9 @@ public:
 
         for (Uint32 i = 0; i < n; i++)
         {
-            CIMInstance tmp;
+            CIMClass tmp;
 
-            if (!getInstance(tmp))
+            if (!getClass(tmp))
                 return false;
 
             x.append(tmp);
@@ -850,13 +1014,16 @@ public:
         return true;
     }
 
-    void putObjectA(const Array<CIMObject>& x)
+    void putObjectA(
+        const Array<CIMObject>& x,
+        bool includeHostAndNamespace = true,
+        bool includeKeyBindings = true)
     {
         Uint32 n = x.size();
         putUint32(n);
 
         for (size_t i = 0; i < n; i++)
-            putObject(x[i]);
+            putObject(x[i], includeHostAndNamespace, includeKeyBindings);
     }
 
     bool getObjectA(Array<CIMObject>& x)
@@ -908,12 +1075,43 @@ public:
         return true;
     }
 
+    void putQualifierDeclA(const Array<CIMQualifierDecl>& x)
+    {
+        Uint32 n = x.size();
+        putUint32(n);
+
+        for (size_t i = 0; i < n; i++)
+            putQualifierDecl(x[i]);
+    }
+
+    bool getQualifierDeclA(Array<CIMQualifierDecl>& x)
+    {
+        Uint32 n;
+
+        if (!getUint32(n))
+            return false;
+
+        for (Uint32 i = 0; i < n; i++)
+        {
+            CIMQualifierDecl tmp;
+
+            if (!getQualifierDecl(tmp))
+                return false;
+
+            x.append(tmp);
+        }
+
+        return true;
+    }
+
     void putPresent(Boolean flag);
 
     bool getPresent(Boolean& flag);
 
 private:
 
+    void _create(size_t);
+
     void _grow(size_t size);
 
     void _putMagic(Uint32 magic)
@@ -937,9 +1135,138 @@ private:
 #endif
     }
 
+    Uint16 _swapUint16(Uint16 x)
+    {
+        return (Uint16)(
+            (((Uint16)(x) & 0x00ffU) << 8) |
+            (((Uint16)(x) & 0xff00U) >> 8));
+    }
+
+    Sint16 _swapSint16(Sint16 x)
+    {
+        return Sint16(_swapUint16(Uint16(x)));
+    }
+
+    Char16 _swapChar16(Char16 x)
+    {
+        return Char16(_swapUint16(Uint16(x)));
+    }
+
+    Uint32 _swapUint32(Uint32 x)
+    {
+        return (Uint32)(
+            (((Uint32)(x) & 0x000000ffUL) << 24) |
+            (((Uint32)(x) & 0x0000ff00UL) <<  8) |
+            (((Uint32)(x) & 0x00ff0000UL) >>  8) |
+            (((Uint32)(x) & 0xff000000UL) >> 24));
+    }
+
+    Sint32 _swapSint32(Sint32 x)
+    {
+        return Sint32(_swapUint32(Uint32(x)));
+    }
+
+    void _swapBytes(Uint8& x, Uint8& y)
+    {
+        Uint8 t = x;
+        x = y;
+        y = t;
+    }
+
+    Uint64 _swapUint64(Uint64 x)
+    {
+        union
+        {
+            Uint64 x;
+            Uint8 bytes[8];
+        }
+        u;
+
+        u.x = x;
+        _swapBytes(u.bytes[0], u.bytes[7]);
+        _swapBytes(u.bytes[1], u.bytes[6]);
+        _swapBytes(u.bytes[2], u.bytes[5]);
+        _swapBytes(u.bytes[3], u.bytes[4]);
+        return u.x;
+    }
+
+    Sint64 _swapSint64(Sint64 x)
+    {
+        return Sint64(_swapUint64(Uint64(x)));
+    }
+
+    Real32 _swapReal32(Real32 x)
+    {
+        return _swapUint32(*((Uint32*)(void*)&x));
+    }
+
+    Real64 _swapReal64(Real64 x)
+    {
+        return _swapUint64(*((Uint64*)(void*)&x));
+    }
+
+    void _swapUint16Data(Uint16* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapUint16(*p);
+    }
+
+    void _swapSint16Data(Sint16* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapSint16(*p);
+    }
+
+    void _swapUint32Data(Uint32* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapUint32(*p);
+    }
+
+    void _swapSint32Data(Sint32* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapSint32(*p);
+    }
+
+    void _swapUint64Data(Uint64* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapUint64(*p);
+    }
+
+    void _swapSint64Data(Sint64* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapSint64(*p);
+    }
+
+    void _swapReal32Data(Real32* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapReal32(*p);
+    }
+
+    void _swapReal64Data(Real64* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapReal64(*p);
+    }
+
+    void _swapChar16Data(Char16* p, Uint32 n)
+    {
+        for (; n--; p++)
+            *p = _swapChar16(*p);
+    }
+
     char* _data;
     char* _end;
     char* _ptr;
+    // If non-zero, the endianess of reads is swapped (big-endian is changed
+    // to little-endian and visa versa).
+
+    int _swap;
+    int _validate;
 };
 
 PEGASUS_NAMESPACE_END
index 6d529e20be0570f42e27807215b34afb2304ac57..3c3bc5d6d37435b04586627b9aef935d1654f954 100644 (file)
@@ -53,6 +53,8 @@ void CIMResponseMessage::syncAttributes(const CIMRequestMessage* request)
 #ifndef PEGASUS_DISABLE_PERFINST
     setServerStartTime(request->getServerStartTime());
 #endif
+    binaryRequest = request->binaryRequest;
+    binaryResponse = request->binaryResponse;
 }
 
 CIMResponseMessage* CIMGetClassRequestMessage::buildResponse() const
@@ -534,6 +536,9 @@ CIMMessage::CIMMessage(
         AcceptLanguageListContainer(AcceptLanguageList()));
     operationContext.insert(
         ContentLanguageListContainer(ContentLanguageList()));
+
+    binaryRequest = false;
+    binaryResponse = false;
 }
 
 #ifndef PEGASUS_DISABLE_PERFINST
index a43e21eae54cd265cc6e20ca08597e93aadeed99..359a81dbec6f412ee304f5568028606a0cfc2dbd 100644 (file)
@@ -138,6 +138,20 @@ public:
     String messageId;
     OperationContext operationContext;
 
+    // This flag indicates that the original request was a binary request.
+    // That is the HTTP "Content-Type" header had a value of
+    // "application/x-openpegasus". It does not necessarily follow that
+    // the response to this request must also be binary. Binary requests
+    // may have XML responses.
+    Boolean binaryRequest;
+
+    // This flag indications that the ultimate response to this message
+    // must be sent as binary response. This means the original request's
+    // "Accept" HTTP header had a value of "application/x-openpegasus".
+    // Note that a binary response can be sent to an XML request as long
+    // as the "Accept" header is "application/x-openpegasus".
+    Boolean binaryResponse;
+
 private:
 
     ThreadType _languageContextThreadId;
@@ -1432,22 +1446,26 @@ public:
         const QueueIdStack& queueIds_)
     : CIMResponseMessage(CIM_GET_INSTANCE_RESPONSE_MESSAGE,
         messageId_, cimException_, queueIds_), 
-        resolveCallback(0)
+        resolveCallback(0),
+        binaryEncoding(false)
     {
     }
 
     Boolean (*resolveCallback)(
-        const Array<Sint8>& instanceData, 
-        const Array<Sint8>& referenceData, 
-        const String& hostData,
-        const CIMNamespaceName& nameSpaceData,
+        CIMGetInstanceResponseMessage* msg,
         CIMInstance& cimInstance);
 
+    Boolean binaryEncoding;
+
+    // For XML encoding:
     Array<Sint8> instanceData;
     Array<Sint8> referenceData;
     CIMNamespaceName nameSpaceData;
     String hostData;
 
+    // For Binary encoding:
+    Array<Uint8> binaryData;
+
     CIMInstance& getCimInstance() 
     {
         _resolve();
@@ -1482,13 +1500,7 @@ private:
     {
         if (resolveCallback)
         {
-            (*resolveCallback)(
-                instanceData, 
-                referenceData, 
-                hostData,
-                nameSpaceData, 
-                _cimInstance);
-            resolveCallback = 0;
+            (*resolveCallback)(this, _cimInstance);
         }
     }
 
@@ -1643,22 +1655,27 @@ public:
         const QueueIdStack& queueIds_)
     : CIMResponseMessage(
         CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE,
-        messageId_, cimException_, queueIds_), resolveCallback(0)
+        messageId_, cimException_, queueIds_), 
+        resolveCallback(0),
+        binaryEncoding(false)
     {
     }
 
     Boolean (*resolveCallback)(
-        const Array<ArraySint8>& instancesData,
-        const Array<ArraySint8>& referencesData,
-        const Array<String>& hostsData,
-        const Array<CIMNamespaceName>& nameSpacesData,
+        CIMEnumerateInstancesResponseMessage* msg,
         Array<CIMInstance>& instances);
 
+    Boolean binaryEncoding;
+
+    // For XML encoding.
     Array<ArraySint8> instancesData;
     Array<ArraySint8> referencesData;
     Array<String> hostsData;
     Array<CIMNamespaceName> nameSpacesData;
 
+    // For binary encoding.
+    Array<Uint8> binaryData;
+
     Array<CIMInstance>& getNamedInstances()
     {
         _resolve();
@@ -1689,12 +1706,7 @@ private:
     {
         if (resolveCallback)
         {
-            (*resolveCallback)(
-                instancesData,
-                referencesData,
-                hostsData,
-                nameSpacesData,
-                _namedInstances);
+            (*resolveCallback)(this, _namedInstances);
             resolveCallback = 0;
         }
     }
index 3347cf9ad32fc494b672742a4b1170d3687d509d..d85c792b84024998bb245a6826204160dbf7559c 100644 (file)
@@ -138,7 +138,7 @@ private:
     // reference counter as member to avoid
     // virtual function resolution overhead
     AtomicInt _refCounter;
-
+    friend class CIMBuffer;
 };
 
 PEGASUS_NAMESPACE_END
index f2746883f1a6ac887721d7110deda06451f9517c..e816fc7b38a1ea3a45e1ef449185de597aceb0a7 100644 (file)
@@ -63,6 +63,7 @@ endif
 ##
 
 SOURCES1 = \
+    Print.cpp \
     Executor.cpp \
     CIMError.cpp \
     PropertyAccessor.cpp \
@@ -193,7 +194,8 @@ SOURCES2 = \
     CommonUTF.cpp \
     Constants.cpp \
     HostAddress.cpp \
-    HostLocator.cpp
+    HostLocator.cpp \
+    BinaryCodec.cpp
 
 ifeq ($(PEGASUS_PLATFORM),PASE_ISERIES_IBMCXX)
     SOURCES2 += PaseCcsid.cpp
@@ -211,7 +213,7 @@ ifeq ($(PEGASUS_PLATFORM),HPUX_PARISC_ACC)
     SOURCES2 += LoadAndClearWord_HPUX_PARISC_ACC.s
 endif
 
-ifeq ($(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL),true)
+ifeq ($(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY),true)
     SOURCES2 += CIMBuffer.cpp
     SOURCES2 += CIMBinMsgSerializer.cpp
     SOURCES2 += CIMBinMsgDeserializer.cpp
index 290912d556799ac75022c927e83f03cf2543e340..1610ca3423d5a2ca0dc6515a4944c57a72429ea9 100644 (file)
@@ -57,7 +57,7 @@ PEGASUS_NAMESPACE_BEGIN
 
         ...
 
-        once(&_once, _create_X());
+        once(&_once, _create_X);
 
     The _create_X() function is called exactly once no matter how many times
     once() is called on it. Also, once() may be called safely from multiple
diff --git a/src/Pegasus/Common/Print.cpp b/src/Pegasus/Common/Print.cpp
new file mode 100644 (file)
index 0000000..da7686e
--- /dev/null
@@ -0,0 +1,556 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include "Print.h"
+
+PEGASUS_USING_STD;
+
+PEGASUS_NAMESPACE_BEGIN
+
+#if defined(PEGASUS_DEBUG)
+
+struct Ind
+{
+    Ind(Uint32 n_) : n(n_) { }
+    Uint32 n;
+};
+
+inline PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const Ind& x)
+{
+    for (Uint32 i = 0; i < x.n; i++)
+        os << "    ";
+
+    return os;
+}
+
+static const char* _typeStrings[] =
+{
+    "boolean",
+    "uint8",
+    "sint8",
+    "uint16",
+    "sint16",
+    "uint32",
+    "sint32",
+    "uint64",
+    "sint64",
+    "real32",
+    "real64",
+    "char16",
+    "string",
+    "datetime",
+    "reference",
+    "object",
+    "instance"
+};
+
+inline ostream& operator<<(ostream& os, const CIMDateTime& x)
+{
+    os << x.toString();
+    return os;
+}
+
+static void _print(ostream& os, const Boolean& x)
+{
+    os << (x ? "true" : "false");
+}
+
+static void _print(ostream& os, const Uint8& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Sint8& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Uint16& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Sint16& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Uint32& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Sint32& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Uint64& x)
+{
+    char buf[32];
+    sprintf(buf, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", x);
+    os << buf;
+}
+
+static void _print(ostream& os, const Sint64& x)
+{
+    char buf[32];
+    sprintf(buf, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", x);
+    os << buf;
+}
+
+static void _print(ostream& os, const Real32& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Real64& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const Char16& x)
+{
+    os << Uint16(x);
+}
+
+static void _print(ostream& os, const String& x)
+{
+    os << x;
+}
+
+static void _print(ostream& os, const CIMDateTime& x)
+{
+    os << x.toString();
+}
+
+template<class T>
+struct PrintArray
+{
+    static void print(ostream& os, const CIMValue& cv)
+    {
+        Array<T> a;
+        cv.get(a);
+
+        os << "{ ";
+
+        for (Uint32 i = 0; i < a.size(); i++)
+        {
+            _print(os, a[i]);
+
+            if (i + 1 != a.size())
+                os << ", ";
+            else
+                os << " ";
+        }
+
+        os << "}" << endl;
+    }
+};
+
+template<class T>
+struct PrintScalar
+{
+    static void print(ostream& os, const CIMValue& cv)
+    {
+        T x;
+        cv.get(x);
+        _print(os, x);
+        os << endl;
+    }
+};
+
+void _printValue(ostream& os, const CIMValue& cv, Uint32 n)
+{
+    os << Ind(n) << "value=";
+
+    if (cv.isNull())
+    {
+        os << "null" << endl;
+    }
+
+    if (cv.isArray())
+    {
+        switch (cv.getType())
+        {
+            case CIMTYPE_BOOLEAN:
+            {
+                PrintArray<Boolean>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT8:
+            {
+                PrintArray<Uint8>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT8:
+            {
+                PrintArray<Sint8>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT16:
+            {
+                PrintArray<Uint16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT16:
+            {
+                PrintArray<Sint16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT32:
+            {
+                PrintArray<Uint32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT32:
+            {
+                PrintArray<Sint32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT64:
+            {
+                PrintArray<Uint64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT64:
+            {
+                PrintArray<Sint64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_REAL32:
+            {
+                PrintArray<Real32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_REAL64:
+            {
+                PrintArray<Real64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_CHAR16:
+            {
+                PrintArray<Char16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_STRING:
+            {
+                PrintArray<String>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_DATETIME:
+            {
+                PrintArray<CIMDateTime>::print(os, cv);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    else
+    {
+        switch (cv.getType())
+        {
+            case CIMTYPE_BOOLEAN:
+            {
+                PrintScalar<Boolean>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT8:
+            {
+                PrintScalar<Uint8>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT8:
+            {
+                PrintScalar<Sint8>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT16:
+            {
+                PrintScalar<Uint16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT16:
+            {
+                PrintScalar<Sint16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT32:
+            {
+                PrintScalar<Uint32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT32:
+            {
+                PrintScalar<Sint32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_UINT64:
+            {
+                PrintScalar<Uint64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_SINT64:
+            {
+                PrintScalar<Sint64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_REAL32:
+            {
+                PrintScalar<Real32>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_REAL64:
+            {
+                PrintScalar<Real64>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_CHAR16:
+            {
+                PrintScalar<Char16>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_STRING:
+            {
+                PrintScalar<String>::print(os, cv);
+                break;
+            }
+            case CIMTYPE_DATETIME:
+            {
+                PrintScalar<CIMDateTime>::print(os, cv);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+void PrintValue(PEGASUS_STD(ostream)& os, const CIMValue& x, Uint32 n)
+{
+    os << Ind(n) << "CIMValue" << endl;
+    os << Ind(n) << "{" << endl;
+    os << Ind(n) << "    type=" << _typeStrings[x.getType()];
+
+    if (x.isArray())
+        os << "[]";
+
+    os << endl;
+
+    if (x.getType() == CIMTYPE_INSTANCE)
+    {
+        if (x.isArray())
+        {
+            Array<CIMInstance> a;
+            x.get(a);
+
+            for (Uint32 i = 0; i < a.size(); i++)
+            {
+                CIMInstance ci = a[i];
+
+                if (ci.isUninitialized())
+                {
+                    os << Ind(n) << "null" << endl;
+                }
+                else
+                {
+                    PrintInstance(os, ci, n + 1);
+                }
+            }
+        }
+        else
+        {
+            CIMInstance ci;
+            x.get(ci);
+
+            if (ci.isUninitialized())
+            {
+                os << Ind(n) << "null" << endl;
+            }
+            else
+            {
+                PrintInstance(os, ci, n + 1);
+            }
+        }
+    }
+    else if (x.getType() == CIMTYPE_OBJECT)
+    {
+        if (x.isArray())
+        {
+            Array<CIMObject> a;
+            x.get(a);
+
+            for (Uint32 i = 0; i < a.size(); i++)
+            {
+                if (a[i].isInstance())
+                {
+                    CIMInstance ci(a[i]);
+
+                    if (ci.isUninitialized())
+                    {
+                        os << Ind(n) << "null" << endl;
+                    }
+                    else
+                    {
+                        PrintInstance(os, ci, n + 1);
+                    }
+                }
+            }
+        }
+        else
+        {
+            CIMObject co;
+            x.get(co);
+
+            if (co.isInstance())
+            {
+                CIMInstance ci(co);
+
+                if (ci.isUninitialized())
+                {
+                    os << Ind(n) << "null" << endl;
+                }
+                else
+                {
+                    PrintInstance(os, ci, n + 1);
+                }
+            }
+        }
+    }
+    else
+    {
+        _printValue(os, x, n + 1);
+    }
+
+    os << Ind(n) << "}" << endl;
+}
+
+static const char* _keyTypes[] =
+{
+    "boolean",
+    "string",
+    "numeric",
+    "reference",
+};
+
+void _printKeyBinding(
+    PEGASUS_STD(ostream)& os, 
+    const CIMKeyBinding& x, 
+    Uint32 n)
+{
+    os << Ind(n) << "CIMKeyBinding" << endl;
+    os << Ind(n) << "{" << endl;
+
+    os << Ind(n) << "    name=" << x.getName().getString() << endl;
+    os << Ind(n) << "    type=" << _keyTypes[x.getType()] << endl;
+    os << Ind(n) << "    value=" << x.getValue() << endl;
+
+    os << Ind(n) << "}" << endl;
+}
+
+void PrintObjectPath(
+    PEGASUS_STD(ostream)& os, 
+    const CIMObjectPath& x, 
+    Uint32 n)
+{
+    os << Ind(n) << "CIMObjectPath" << endl;
+    os << Ind(n) << "{" << endl;
+    os << Ind(n) << "    host=" << x.getHost() << endl;
+    os << Ind(n) << "    namespace=" << x.getNameSpace().getString() << endl;
+    os << Ind(n) << "    classname=" << x.getClassName().getString() << endl;
+    os << Ind(n) << "    keyBindings" << endl;
+    os << Ind(n) << "    {" << endl;
+
+    const Array<CIMKeyBinding>& a = x.getKeyBindings();
+
+    for (Uint32 i = 0; i < a.size(); i++)
+    {
+        _printKeyBinding(os, a[i], n + 2);
+    }
+
+    os << Ind(n) << "    }" << endl;
+
+    os << Ind(n) << "}" << endl;
+}
+
+void PrintProperty(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstProperty& x, 
+    Uint32 n)
+{
+    os << Ind(n) << "CIMProperty" << endl;
+    os << Ind(n) << "{" << endl;
+    os << Ind(n) << "    name=" << x.getName().getString() << endl;
+    PrintValue(os, x.getValue(), n + 1);
+    os << Ind(n) << "}" << endl;
+}
+
+void PrintInstance(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstInstance& x, 
+    Uint32 n)
+{
+    os << Ind(n) << "CIMInstance" << endl;
+    os << Ind(n) << "{" << endl;
+    os << Ind(n) << "    class=" << x.getClassName().getString() << endl;
+
+    PrintObjectPath(os, x.getPath(), n + 1);
+
+    for (Uint32 i = 0; i < x.getPropertyCount(); i++)
+    {
+        PrintProperty(os, x.getProperty(i), n + 1);
+    }
+
+    os << Ind(n) << "}" << endl;
+}
+
+void PEGASUS_COMMON_LINKAGE PrintQualifierDecl(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstQualifierDecl& x, 
+    Uint32 n)
+{
+    os << Ind(n) << "CIMQualifierDecl" << endl;
+    os << Ind(n) << "{" << endl;
+    os << Ind(n) << "    name=" << x.getName().getString() << endl;
+    os << Ind(n) << "    type=" << _typeStrings[x.getType()] << endl;
+    os << Ind(n) << "    scope=" << x.getScope().toString() << endl;
+    os << Ind(n) << "    flavor=" << x.getFlavor().toString() << endl;
+    os << Ind(n) << "    arraySize=" << x.getArraySize() << endl;
+    PrintValue(os, x.getValue(), n + 1);
+    os << Ind(n) << "}" << endl;
+}
+
+#endif /* defined(PEGASUS_DEBUG) */
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Pegasus/Common/Print.h b/src/Pegasus/Common/Print.h
new file mode 100644 (file)
index 0000000..3ebc2bc
--- /dev/null
@@ -0,0 +1,92 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_Print_h
+#define Pegasus_Print_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/CIMInstance.h>
+#include <Pegasus/Common/CIMQualifierDecl.h>
+#include <Pegasus/Common/Linkage.h>
+#include <iostream>
+
+PEGASUS_NAMESPACE_BEGIN
+
+//==============================================================================
+//
+// PrintValue()
+// PrintProperty()
+// PrintObjectPath()
+// PrintInstance()
+// PrintQualifierDecl()
+//
+//     These functions print selected CIM objects in a format suitable for
+//     debugging. These functions print every element of the object. Some
+//     more conventional formats exclude some elements. For example, MOF
+//     instances do not include the property-type and XML instances exclude
+//     the host and namespace.
+//
+//     You may use these functions for diffing two objects using the following
+//     procedure. (1) Print each object to a file. (2) Diff the files with the
+//     diff command.
+//
+//==============================================================================
+
+PEGASUS_COMMON_LINKAGE void PrintValue(
+    PEGASUS_STD(ostream)& os, 
+    const CIMValue& x, 
+    Uint32 n = 0);
+
+PEGASUS_COMMON_LINKAGE void PrintProperty(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstProperty& x, 
+    Uint32 n = 0);
+
+PEGASUS_COMMON_LINKAGE void PrintObjectPath(
+    PEGASUS_STD(ostream)& os, 
+    const CIMObjectPath& x, 
+    Uint32 n = 0);
+
+PEGASUS_COMMON_LINKAGE void PrintInstance(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstInstance& cimInstance, 
+    Uint32 n = 0);
+
+PEGASUS_COMMON_LINKAGE void PrintQualifierDecl(
+    PEGASUS_STD(ostream)& os, 
+    const CIMConstQualifierDecl& x, 
+    Uint32 n = 0);
+
+PEGASUS_NAMESPACE_END
+
+#endif /* Pegasus_Print_h */
index c7e318ba6a6b13f7745c7ac1296b100c44d690be..3b0ac139b5b8e52c227e8e0fb579880b6700ce13 100644 (file)
@@ -1695,7 +1695,9 @@ void XmlWriter::appendMethodCallHeader(
     HttpMethod httpMethod,
     const AcceptLanguageList& acceptLanguages,
     const ContentLanguageList& contentLanguages,
-    Uint32 contentLength)
+    Uint32 contentLength,
+    bool binaryRequest,
+    bool binaryResponse)
 {
     char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' };
 
@@ -1713,8 +1715,26 @@ void XmlWriter::appendMethodCallHeader(
     {
         out << STRLIT("POST /cimom HTTP/1.1\r\n");
     }
-    out << STRLIT("HOST: ") << host << STRLIT("\r\n" 
-                  "Content-Type: application/xml; charset=\"utf-8\"\r\n");
+    out << STRLIT("HOST: ") << host << STRLIT("\r\n");
+
+    if (binaryRequest)
+    {
+        // Tell the server that the payload is encoded in the OpenPegasus
+        // binary protocol.
+        out << STRLIT("Content-Type: application/x-openpegasus\r\n");
+    }
+    else
+    {
+        out << STRLIT("Content-Type: application/xml; charset=\"utf-8\"\r\n");
+    }
+
+    if (binaryResponse)
+    {
+        // Tell the server that this client accepts the OpenPegasus binary
+        // protocol.
+        out << STRLIT("Accept: application/x-openpegasus\r\n");
+    }
+
     OUTPUT_CONTENTLENGTH(out, contentLength);
     if (acceptLanguages.size() > 0)
     {
@@ -1738,7 +1758,11 @@ void XmlWriter::appendMethodCallHeader(
     if (!clientTransferEncodingOff || *clientTransferEncodingOff != '0')
 #endif
 
-    out << STRLIT("TE: chunked, trailers\r\n");
+    if (!binaryResponse)
+    {
+        // The binary protocol does not allow chunking.
+        out << STRLIT("TE: chunked, trailers\r\n");
+    }
 
     if (httpMethod == HTTP_METHOD_M_POST)
     {
@@ -1773,9 +1797,30 @@ void XmlWriter::appendMethodResponseHeader(
      HttpMethod httpMethod,
      const ContentLanguageList& contentLanguages,
      Uint32 contentLength,
-     Uint64 serverResponseTime)
-{
-     char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' };
+     Uint64 serverResponseTime,
+     bool binaryResponse)
+{
+    // Optimize the typical case for binary messages, circumventing the
+    // more expensive logic below.
+    if (binaryResponse && 
+        contentLength == 0 &&
+        httpMethod != HTTP_METHOD_M_POST &&
+        contentLanguages.size() == 0)
+    {
+        static const char HEADERS[] =
+            "HTTP/1.1 200 OK\r\n"
+            "Content-Type: application/x-openpegasus\r\n"
+            "content-length: 0000000000\r\n"
+            "CIMOperation: MethodResponse\r\n"
+            "\r\n";
+
+        // The HTTP processor fills in the content-length value later.
+        // It searches for a field matching "content-length" (so the first
+        // character must be lower case).
+        out.append(HEADERS, sizeof(HEADERS) - 1);
+        return;
+    }
+
      out << STRLIT("HTTP/1.1 " HTTP_STATUS_OK "\r\n");
 
 #ifndef PEGASUS_DISABLE_PERFINST
@@ -1786,7 +1831,17 @@ void XmlWriter::appendMethodResponseHeader(
      }
 #endif
 
-     out << STRLIT("Content-Type: application/xml; charset=\"utf-8\"\r\n");
+     if (binaryResponse)
+     {
+        // According to MIME RFC, the "x-" prefix should be used for all
+        // non-registered values.
+         out << STRLIT("Content-Type: application/x-openpegasus\r\n");
+     }
+     else
+     {
+         out << STRLIT("Content-Type: application/xml; charset=\"utf-8\"\r\n");
+     }
+
      OUTPUT_CONTENTLENGTH(out, contentLength);
 
      if (contentLanguages.size() > 0)
@@ -1796,6 +1851,8 @@ void XmlWriter::appendMethodResponseHeader(
      }
      if (httpMethod == HTTP_METHOD_M_POST)
      {
+         char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' };
+
          out << STRLIT("Ext:\r\n" 
                        "Cache-Control: no-cache\r\n" 
                        "Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns=");
@@ -2508,7 +2565,8 @@ Buffer XmlWriter::formatSimpleMethodReqMessage(
     HttpMethod httpMethod,
     const String& authenticationHeader,
     const AcceptLanguageList& httpAcceptLanguages,
-    const ContentLanguageList& httpContentLanguages)
+    const ContentLanguageList& httpContentLanguages,
+    bool binaryResponse)
 {
     Buffer out;
     Buffer tmp;
@@ -2537,7 +2595,9 @@ Buffer XmlWriter::formatSimpleMethodReqMessage(
         httpMethod,
         httpAcceptLanguages,
         httpContentLanguages,
-        out.size());
+        out.size(),
+        false,
+        binaryResponse);
     tmp << out;
 
     return tmp;
@@ -2609,7 +2669,8 @@ Buffer XmlWriter::formatSimpleMethodErrorRspMessage(
         tmp,
         httpMethod,
         cimException.getContentLanguages(),
-        out.size());
+        out.size(),
+        false);
     tmp << out;
 
     return tmp;
@@ -2630,7 +2691,8 @@ Buffer XmlWriter::formatSimpleIMethodReqMessage(
     const String& authenticationHeader,
     const AcceptLanguageList& httpAcceptLanguages,
     const ContentLanguageList& httpContentLanguages,
-    const Buffer& body)
+    const Buffer& body,
+    bool binaryResponse)
 {
     Buffer out;
     Buffer tmp;
@@ -2653,7 +2715,9 @@ Buffer XmlWriter::formatSimpleIMethodReqMessage(
         httpMethod,
         httpAcceptLanguages,
         httpContentLanguages,
-        out.size());
+        out.size(), 
+        false,
+        binaryResponse);
     tmp << out;
 
     return tmp;
@@ -2741,7 +2805,7 @@ Buffer XmlWriter::formatSimpleIMethodErrorRspMessage(
     appendMethodResponseHeader(tmp,
         httpMethod,
         cimException.getContentLanguages(),
-        out.size());
+        out.size(), false);
     tmp << out;
 
     return tmp;
index 35a6f59cd2e27d5e85c57b6b4e9be83895737366..183861f919afd982d6cf02e19a9a78702a3bd6ac 100644 (file)
@@ -212,14 +212,17 @@ public:
         HttpMethod httpMethod,
         const AcceptLanguageList& acceptLanguages,
         const ContentLanguageList& contentLanguages,
-        Uint32 contentLength);
+        Uint32 contentLength,
+        bool binaryRequest = false,
+        bool binaryResponse = false);
 
     static void appendMethodResponseHeader(
         Buffer& out,
         HttpMethod httpMethod,
         const ContentLanguageList& contentLanguages,
         Uint32 contentLength,
-        Uint64 serverResponseTime = 0);
+        Uint64 serverResponseTime = 0,
+        bool binaryResponse = false);
 
     static void appendHttpErrorResponseHeader(
         Buffer& out,
@@ -318,7 +321,8 @@ public:
         HttpMethod httpMethod,
         const String& authenticationHeader,
         const AcceptLanguageList& httpAcceptLanguages,
-        const ContentLanguageList& httpContentLanguages);
+        const ContentLanguageList& httpContentLanguages,
+        bool binaryResponse);
 
     static Buffer formatSimpleMethodRspMessage(
         const CIMName& methodName,
@@ -345,7 +349,8 @@ public:
         const String& authenticationHeader,
         const AcceptLanguageList& httpAcceptLanguages,
         const ContentLanguageList& httpContentLanguages,
-        const Buffer& body);
+        const Buffer& body,
+        bool binaryResponse);
 
     static Buffer formatSimpleIMethodRspMessage(
         const CIMName& iMethodName,
@@ -357,6 +362,7 @@ public:
         Boolean isFirst = true,
         Boolean isLast = true);
 
+
     static Buffer formatSimpleIMethodErrorRspMessage(
         const CIMName& iMethodName,
         const String& messageId,
index aa34b4183d541954924ae7293f00bdd772108050..475789ab400e4dbadc7f65506d5a4d06c449644b 100644 (file)
@@ -184,6 +184,60 @@ void test7()
     PEGASUS_TEST_ASSERT(cop1.toString() == cop2.toString());
 }
 
+void test8()
+{
+    CIMBuffer cb;
+
+    CIMObjectPath cop1;
+    cb.putObjectPath(cop1);
+    cb.rewind();
+    CIMObjectPath cop2;
+
+    PEGASUS_TEST_ASSERT(cb.getObjectPath(cop2));
+
+    PEGASUS_TEST_ASSERT(cop1 == cop2);
+    PEGASUS_TEST_ASSERT(cop1.toString() == cop2.toString());
+}
+
+void test9()
+{
+    CIMBuffer cb;
+
+    cb.putBoolean(true);
+    cb.putBoolean(false);
+    cb.putBoolean(true);
+    cb.putBoolean(true);
+
+    Array<Boolean> a;
+    a.append(true);
+    a.append(false);
+    a.append(true);
+    a.append(true);
+    cb.putBooleanA(a);
+
+    cb.putUint32(1234);
+
+    cb.rewind();
+
+    Boolean x;
+    PEGASUS_TEST_ASSERT(cb.getBoolean(x) && x == true);
+    PEGASUS_TEST_ASSERT(cb.getBoolean(x) && x == false);
+    PEGASUS_TEST_ASSERT(cb.getBoolean(x) && x == true);
+    PEGASUS_TEST_ASSERT(cb.getBoolean(x) && x == true);
+
+    Array<Boolean> b;
+    PEGASUS_TEST_ASSERT(cb.getBooleanA(b) && a == b);
+    assert(a.size() == 4);
+    assert(a.size() == b.size());
+    assert(a[0] == b[0]);
+    assert(a[1] == b[1]);
+    assert(a[2] == b[2]);
+    assert(a[3] == b[3]);
+
+    Uint32 y;
+    PEGASUS_TEST_ASSERT(cb.getUint32(y) && y == 1234);
+}
+
 int main(int argc, char** argv)
 {
     test1();
@@ -193,6 +247,8 @@ int main(int argc, char** argv)
     test5();
     test6();
     test7();
+    test8();
+    test9();
 
     cout << argv[0] << " +++++ passed all tests" << endl;
     return 0;
index c00cc8dc0719091abf4f3d9f81f92896cf8eea45..d15c39b42144a818ecc1cc3ebcd2b9f07a3f3173 100644 (file)
@@ -118,7 +118,7 @@ DIRS += \
        Attribute
 endif
 
-ifeq ($(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL),true)
+ifeq ($(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY),true)
     DIRS += CIMBuffer
 endif
 
index e4a024043c0e15c6c3b3f16ae53492ef4c23fce9..4b563bc9e35b5169b2cdbcdc8f7d5852725962b2 100644 (file)
@@ -37,7 +37,7 @@
 #include <Pegasus/Common/System.h>
 #include <Pegasus/Common/OperationContextInternal.h>
 
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
 # include <Pegasus/Common/CIMBinMsgSerializer.h>
 # include <Pegasus/Common/CIMBinMsgDeserializer.h>
 #else
@@ -504,7 +504,7 @@ void validateCIMResponseMessageAttributes(
     a Message object.
 */
 CIMMessage* serializeDeserializeMessage(CIMMessage* inMessage)
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
 {
     CIMBuffer buf(64*1024);
     CIMBinMsgSerializer::serialize(buf, inMessage);
@@ -544,7 +544,7 @@ CIMMessage* serializeDeserializeMessage(CIMMessage* inMessage)
 // testEmptyRequestMessage
 //
 void testEmptyMessage()
-#if defined(PEGASUS_ENABLE_INTERNAL_BINARY_PROTOCOL)
+#if defined(PEGASUS_ENABLE_PROTOCOL_INTERNAL_BINARY)
 {
     CIMBuffer buf(64*1024);
     CIMBinMsgSerializer::serialize(buf, 0);
index c531c140199c24cd6c1321ff86a3dcd1a3072632..54185352bd092620ade86111dcb99ff31b6e6dd2 100644 (file)
@@ -751,7 +751,8 @@ Uint32 test26()
         "Basic: Authorization AAAAA",
         al,
         cl,
-        params);
+        params,
+        false);
 
     SharedArrayPtr<char> reqMsg(Tracer::getHTTPRequestMessage(
             buffer));
@@ -806,7 +807,8 @@ Uint32 test27()
         authHeader,
         al,
         cl,
-        params);
+        params,
+        false);
 
     PEG_TRACE((
         TRC_XML_IO,
index eb65c74bbab5fa86ae30fb04ae943fbf5964225c..29307a73618d8828198edd28c1f1296afc146c26 100644 (file)
@@ -46,6 +46,7 @@
 #include "CIMOperationRequestDecoder.h"
 #include <Pegasus/Common/CommonUTF.h>
 #include <Pegasus/Common/MessageLoader.h>
+#include <Pegasus/Common/BinaryCodec.h>
 
 PEGASUS_USING_STD;
 
@@ -444,12 +445,18 @@ void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
         headers, "Content-Type", cimContentType, true);
     String type;
     String charset;
+    Boolean binaryRequest = false;
 
     if (!contentTypeHeaderFound || 
         !HTTPMessage::parseContentTypeHeader(cimContentType, type, charset) ||
-        (!String::equalNoCase(type, "application/xml") &&
+        ((!String::equalNoCase(type, "application/xml") &&
          !String::equalNoCase(type, "text/xml")) ||
-        !String::equalNoCase(charset, "utf-8"))
+        !String::equalNoCase(charset, "utf-8")) 
+#if defined(PEGASUS_ENABLE_PROTOCOL_BINARY)
+        && !(binaryRequest = String::equalNoCase(type, 
+            "application/x-openpegasus"))
+#endif
+        )
     {
         MessageLoaderParms parms(
             "Server.CIMOperationRequestDecoder.CIMCONTENTTYPE_SYNTAX_ERROR",
@@ -466,7 +473,7 @@ void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
     // Validating content falls within UTF8
     // (required to be complaint with section C12 of Unicode 4.0 spec,
     // chapter 3.)
-    else
+    else if (!binaryRequest)
     {
         Uint32 count = 0;
         while(count<contentLength)
@@ -484,12 +491,27 @@ void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
                     closeConnect);
 
                 PEG_METHOD_EXIT();
-                    return;
+                return;
             }
             UTF8_NEXT(content,count);
         }
     }
 
+    // Check for "Accept: application/x-openpegasus" HTTP header to see if 
+    // client can accept binary responses.
+
+    bool binaryResponse;
+
+    if (HTTPMessage::lookupHeader(headers, "Accept", type, true) &&
+        String::equalNoCase(type, "application/x-openpegasus"))
+    {
+        binaryResponse = true;
+    }
+    else
+    {
+        binaryResponse = false;
+    }
+
     // If it is a method call, then dispatch it to be handled:
 
     handleMethodCall(
@@ -505,7 +527,9 @@ void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
         httpMessage->ipAddress,
         httpMessage->acceptLanguages,
         httpMessage->contentLanguages,
-        closeConnect);
+        closeConnect,
+        binaryRequest,
+        binaryResponse);
 
     PEG_METHOD_EXIT();
 }
@@ -523,7 +547,9 @@ void CIMOperationRequestDecoder::handleMethodCall(
     const String& ipAddress,
     const AcceptLanguageList& httpAcceptLanguages,
     const ContentLanguageList& httpContentLanguages,
-    Boolean closeConnect)
+    Boolean closeConnect,
+    Boolean binaryRequest,
+    Boolean binaryResponse)
 {
     PEG_METHOD_ENTER(TRC_DISPATCHER,
         "CIMOperationRequestDecoder::handleMethodCall()");
@@ -550,16 +576,37 @@ void CIMOperationRequestDecoder::handleMethodCall(
         "CIMOperationRequestdecoder - XML content: %s",
         content));
 
-    // Create a parser:
+    //
+    // Handle binary messages:
+    //
 
-    XmlParser parser(content);
-    XmlEntry entry;
-    String messageId;
-    const char* cimMethodName = "";
     AutoPtr<CIMOperationRequestMessage> request;
 
-    try
+    if (binaryRequest)
     {
+        Buffer buf(content, contentLength);
+
+        request.reset(BinaryCodec::decodeRequest(buf, queueId, _returnQueueId));
+
+        if (!request.get())
+        {
+            sendHttpError(
+                queueId,
+                HTTP_STATUS_BADREQUEST,
+                "Corrupt binary request message",
+                String::EMPTY,
+                closeConnect);
+            PEG_METHOD_EXIT();
+            return;
+        }
+    }
+    else try
+    {
+        XmlParser parser(content);
+        XmlEntry entry;
+        String messageId;
+        const char* cimMethodName = "";
+
         //
         // Process <?xml ... >
         //
@@ -1317,6 +1364,7 @@ void CIMOperationRequestDecoder::handleMethodCall(
     request->userName = userName;
     request->ipAddress = ipAddress;
     request->setHttpMethod (httpMethod);
+    request->binaryResponse = binaryResponse;
 
 //l10n start
 // l10n TODO - might want to move A-L and C-L to Message
index 506bcc3d12f5a28ce0bb824b9af6374ac621b8cf..ea3a3bdc814b79eb91b415e043907a0d34481398 100644 (file)
@@ -106,7 +106,9 @@ public:
         const String& ipAddress,
         const AcceptLanguageList& httpAcceptLanguages,
         const ContentLanguageList& httpContentLanguages,
-        Boolean closeConnect);
+        Boolean closeConnect,
+        Boolean binaryRequest,
+        Boolean binaryResponse);
 
     CIMCreateClassRequestMessage* decodeCreateClassRequest(
         Uint32 queueId,
index aefa821357b34de733520da1c6f0ddad9c4816c8..3faf26d39668b8f34269fb1d6e63286debdf6f65 100644 (file)
 
 #include <Pegasus/Common/Config.h>
 #include <Pegasus/Common/Constants.h>
+#include <Pegasus/Common/CIMBuffer.h>
 #include <cctype>
 #include <cstdio>
 #include <Pegasus/Common/HTTPConnection.h>
+#include <Pegasus/Common/BinaryCodec.h>
 #include <Pegasus/Common/XmlParser.h>
 #include <Pegasus/Common/XmlReader.h>
 #include <Pegasus/Common/XmlWriter.h>
@@ -60,6 +62,52 @@ CIMOperationResponseEncoder::~CIMOperationResponseEncoder()
 {
 }
 
+//==============================================================================
+//
+// CIMOperationResponseEncoder::sendResponse()
+//
+//     This function is called once for every chunk comprising the inner part 
+//     of the HTTP payload. This is true whether chunking is enabled or not. 
+//     The "bodygiven" parameter contains all or part of the inner response 
+//     body. For example, in the case of the enumerate-instances XML response,
+//     each "bodygiven" contains a complete named-instance as shown below.
+//
+//         <VALUE.NAMEDINSTANCE>
+//         ...
+//         <VALUE.NAMEDINSTANCE>
+//     
+//     In the case of the get-class XML response, bodygiven contains the
+//     entire class. Sometimes bodygiven is null, probably indicating that
+//     one of the responding threads returned an empty response (for example,
+//     a provider may return zero instances).
+//
+//     This function wraps the inner payload with the following elements:
+//
+//         1. HTTP status line.
+//         2. HTTP headers.
+//         3. Payload header.
+//         4. Payload footer.
+//
+//     In the case of an enumerate-instances XML response, the payload header
+//     contains all the XML leading up to the first XML chunk. For example:
+//
+//         <?xml version="1.0" encoding="utf-8" ?>
+//         <CIM CIMVERSION="2.0" DTDVERSION="2.0">
+//         <MESSAGE ID="1000" PROTOCOLVERSION="1.0">
+//         <SIMPLERSP>
+//         <IMETHODRESPONSE NAME="EnumerateInstances">
+//         <IRETURNVALUE>
+//
+//     The payload footer then would just contain the closing tags for these:
+//
+//         </IRETURNVALUE>
+//         </IMETHODRESPONSE>
+//         </MESSAGE>
+//         </SIMPLERSP>
+//         </CIM>
+//     
+//==============================================================================
+
 void CIMOperationResponseEncoder::sendResponse(
     CIMResponseMessage* response,
     const String& name,
@@ -160,8 +208,16 @@ void CIMOperationResponseEncoder::sendResponse(
     }
     else
     {
-        formatResponse = XmlWriter::formatSimpleIMethodRspMessage;
         formatError = XmlWriter::formatSimpleIMethodErrorRspMessage;
+
+        if (response->binaryResponse)
+        {
+            formatResponse = BinaryCodec::formatSimpleIMethodRspMessage;
+        }
+        else
+        {
+            formatResponse = XmlWriter::formatSimpleIMethodRspMessage;
+        }
     }
 
     if (cimException.getCode() != CIM_ERR_SUCCESS)
@@ -268,6 +324,7 @@ void CIMOperationResponseEncoder::sendResponse(
     }
 
     httpMessage->setCloseConnect(closeConnect);
+
     queue->enqueue(httpMessage.release());
 
     PEG_METHOD_EXIT();
@@ -301,6 +358,28 @@ void CIMOperationResponseEncoder::handleEnqueue(Message* message)
             "message->getCloseConnect() returned %d",
         message->getCloseConnect()));
 
+    // Handle binary messages up front:
+    {
+        CIMResponseMessage* msg = dynamic_cast<CIMResponseMessage*>(message);
+
+        if (msg && msg->binaryResponse)
+        {
+            if (msg->cimException.getCode() == CIM_ERR_SUCCESS)
+            {
+                Buffer body;
+                CIMName name;
+
+                if (BinaryCodec::encodeResponseBody(body, msg, name))
+                {
+                    sendResponse(msg, name.getString(), true, &body);
+                    delete msg;
+                    PEG_METHOD_EXIT();
+                    return;
+                }
+            }
+        }
+    }
+
     switch (message->getType())
     {
         case CIM_GET_CLASS_RESPONSE_MESSAGE:
@@ -504,7 +583,7 @@ void CIMOperationResponseEncoder::encodeGetInstanceResponse(
     Buffer body;
     if (response->cimException.getCode() == CIM_ERR_SUCCESS)
     {
-        if (response->resolveCallback)
+        if (response->resolveCallback && !response->binaryEncoding)
         {
             body.append(
                 (char*)response->instanceData.getData(), 
@@ -528,9 +607,10 @@ void CIMOperationResponseEncoder::encodeEnumerateInstancesResponse(
     CIMEnumerateInstancesResponseMessage* response)
 {
     Buffer body;
+
     if (response->cimException.getCode() == CIM_ERR_SUCCESS)
     {
-        if (response->resolveCallback)
+        if (response->resolveCallback && !response->binaryEncoding)
         {
             const Array<ArraySint8>& a = response->instancesData;
             const Array<ArraySint8>& b = response->referencesData;
@@ -551,6 +631,7 @@ void CIMOperationResponseEncoder::encodeEnumerateInstancesResponse(
                 XmlWriter::appendValueNamedInstanceElement(body, a[i]);
         }
     }
+
     sendResponse(response, "EnumerateInstances", true, &body);
 }
 
@@ -558,10 +639,13 @@ void CIMOperationResponseEncoder::encodeEnumerateInstanceNamesResponse(
     CIMEnumerateInstanceNamesResponseMessage* response)
 {
     Buffer body;
+
     if (response->cimException.getCode() == CIM_ERR_SUCCESS)
+    {
         for (Uint32 i = 0, n = response->instanceNames.size(); i < n; i++)
             XmlWriter::appendInstanceNameElement(
                 body, response->instanceNames[i]);
+    }
     sendResponse(response, "EnumerateInstanceNames", true, &body);
 }