File: [OMI] / omi / base / messages.c
(download)
Revision: 1.1,
Wed May 30 21:47:49 2012 UTC (12 years, 1 month ago) by mike
Branch: MAIN
Initial revision
|
/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** Licensed under the Apache License, Version 2.0 (the "License"); you may not
** use this file except in compliance with the License. You may obtain a copy
** of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#include "messages.h"
#include "packing.h"
#include <assert.h>
#include "result.h"
#include "io.h"
/*
**==============================================================================
**
** Local definitions
**
**==============================================================================
*/
typedef enum _FieldType
{
FT_BOOLEAN = MI_BOOLEAN,
FT_UINT8 = MI_UINT8,
FT_SINT8 = MI_SINT8,
FT_UINT16 = MI_UINT16,
FT_SINT16 = MI_SINT16,
FT_UINT32 = MI_UINT32,
FT_SINT32 = MI_SINT32,
FT_UINT64 = MI_UINT64,
FT_SINT64 = MI_SINT64,
FT_REAL32 = MI_REAL32,
FT_REAL64 = MI_REAL64,
FT_CHAR16 = MI_CHAR16,
FT_DATETIME = MI_DATETIME,
FT_STRING = MI_STRING,
FT_REFERENCE = MI_REFERENCE,
FT_INSTANCE = MI_INSTANCE,
FT_BOOLEANA = MI_BOOLEANA,
FT_UINT8A = MI_UINT8A,
FT_SINT8A = MI_SINT8A,
FT_UINT16A = MI_UINT16A,
FT_SINT16A = MI_SINT16A,
FT_UINT32A = MI_UINT32A,
FT_SINT32A = MI_SINT32A,
FT_UINT64A = MI_UINT64A,
FT_SINT64A = MI_SINT64A,
FT_REAL32A = MI_REAL32A,
FT_REAL64A = MI_REAL64A,
FT_CHAR16A = MI_CHAR16A,
FT_DATETIMEA = MI_DATETIMEA,
FT_STRINGA = MI_STRINGA,
FT_REFERENCEA = MI_REFERENCEA,
FT_INSTANCEA = MI_INSTANCEA,
FT_RESULT,
FT_ATOMIC
}
FieldType;
/* Defines meta data for message field (to support printing) */
typedef struct Field
{
/* Name of field */
const char* name;
/* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
FieldType type;
/* Byte off within structure to this field */
size_t off;
}
Field;
typedef enum _MessageFieldType
{
MFT_END_OF_LIST, /* special type to terminate list of fields */
MFT_POINTER, /* Pointer that has to be converted */
MFT_POINTER_OPT, /* Pointer that has to be converted (may be null) */
MFT_POINTER_SET_NULL, /* Pointer that has to be nullified instead of converting */
MFT_INSTANCE, /* instance */
MFT_INSTANCE_OPT /* instance (maybe NULL) */
}
MessageFieldType;
/* Defines meta data for message field (to support packing/unpacking) */
typedef struct _MessageField
{
/* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
MessageFieldType type;
/* Byte off within structure to this field and (for instance) to packed pointer/size */
size_t off;
size_t offPackedPtr;
size_t offPackedSize;
}
MessageField;
static const MessageField baseMessageFields[] =
{
{MFT_POINTER_SET_NULL,offsetof(Message, next),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, prev),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, request),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, callback),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, callbackData),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, dtor),0,0},
{MFT_POINTER_SET_NULL,offsetof(Message, dtorData),0,0},
{MFT_POINTER_OPT,offsetof(Message, libraryName),0,0},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField emptyMessageFields[] =
{
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField getInstanceMessageFields[] =
{
{MFT_POINTER,offsetof(GetInstanceReq, nameSpace),0,0},
{MFT_INSTANCE,offsetof(GetInstanceReq, instanceName),offsetof(GetInstanceReq, packedInstanceNamePtr),offsetof(GetInstanceReq, packedInstanceNameSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField postInstanceMessageFields[] =
{
{MFT_INSTANCE,offsetof(PostInstanceMsg, instance),offsetof(PostInstanceMsg, packedInstancePtr),offsetof(PostInstanceMsg, packedInstanceSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField enumerateInstancesMessageFields[] =
{
{MFT_POINTER,offsetof(EnumerateInstancesReq, nameSpace),0,0},
{MFT_POINTER,offsetof(EnumerateInstancesReq, className),0,0},
{MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, requestClassName),0,0},
{MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryLanguage),0,0},
{MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryExpression),0,0},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField invokeMessageFields[] =
{
{MFT_POINTER,offsetof(InvokeReq, nameSpace),0,0},
{MFT_POINTER,offsetof(InvokeReq, function),0,0},
{MFT_POINTER_OPT,offsetof(InvokeReq, className),0,0},
{MFT_INSTANCE_OPT,offsetof(InvokeReq, instance),offsetof(InvokeReq, packedInstancePtr),offsetof(InvokeReq, packedInstanceSize)},
{MFT_INSTANCE_OPT,offsetof(InvokeReq, instanceParams),offsetof(InvokeReq, packedInstanceParamsPtr),offsetof(InvokeReq, packedInstanceParamsSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField associatorsOfMessageFields[] =
{
{MFT_POINTER,offsetof(AssociatorsOfReq, nameSpace),0,0},
{MFT_POINTER_OPT,offsetof(AssociatorsOfReq, className),0,0},
{MFT_POINTER_OPT,offsetof(AssociatorsOfReq, assocClass),0,0},
{MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultClass),0,0},
{MFT_POINTER_OPT,offsetof(AssociatorsOfReq, role),0,0},
{MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultRole),0,0},
{MFT_INSTANCE,offsetof(AssociatorsOfReq, instance),offsetof(AssociatorsOfReq, packedInstancePtr),offsetof(AssociatorsOfReq, packedInstanceSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField referencesOfMessageFields[] =
{
{MFT_POINTER,offsetof(ReferencesOfReq, nameSpace),0,0},
{MFT_POINTER_OPT,offsetof(ReferencesOfReq, className),0,0},
{MFT_POINTER_OPT,offsetof(ReferencesOfReq, assocClass),0,0},
{MFT_POINTER_OPT,offsetof(ReferencesOfReq, role),0,0},
{MFT_INSTANCE,offsetof(ReferencesOfReq, instance),offsetof(ReferencesOfReq, packedInstancePtr),offsetof(ReferencesOfReq, packedInstanceSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField subscribeRequestMessageFields[] =
{
{MFT_POINTER,offsetof(SubscribeReq, nameSpace),0,0},
{MFT_POINTER,offsetof(SubscribeReq, className),0,0},
{MFT_POINTER,offsetof(SubscribeReq, filter),0,0},
{MFT_POINTER,offsetof(SubscribeReq, language),0,0},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField subscribeResponseMessageFields[] =
{
{MFT_POINTER,offsetof(SubscribeRes, subscriptionID),0,0},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField deleteInstanceMessageFields[] =
{
{MFT_POINTER,offsetof(DeleteInstanceReq, nameSpace),0,0},
{MFT_INSTANCE,offsetof(DeleteInstanceReq, instanceName),offsetof(DeleteInstanceReq, packedInstanceNamePtr),offsetof(DeleteInstanceReq, packedInstanceNameSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField createInstanceMessageFields[] =
{
{MFT_POINTER,offsetof(CreateInstanceReq, nameSpace),0,0},
{MFT_INSTANCE,offsetof(CreateInstanceReq, instance),offsetof(CreateInstanceReq, packedInstancePtr),offsetof(CreateInstanceReq, packedInstanceSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField modifyInstanceMessageFields[] =
{
{MFT_POINTER,offsetof(ModifyInstanceReq, nameSpace),0,0},
{MFT_INSTANCE,offsetof(ModifyInstanceReq, instance),offsetof(ModifyInstanceReq, packedInstancePtr),offsetof(ModifyInstanceReq, packedInstanceSize)},
{MFT_END_OF_LIST, 0, 0, 0}
};
static const MessageField binProtocolNotificationFields[] =
{
{MFT_POINTER_OPT,offsetof(BinProtocolNotification, user),0,0},
{MFT_POINTER_OPT,offsetof(BinProtocolNotification, password),0,0},
{MFT_POINTER_OPT,offsetof(BinProtocolNotification, authFile),0,0},
{MFT_END_OF_LIST, 0, 0, 0}
};
/* Entries in this array corresponds to MessageTag values:
GetInstanceReqTag = 1,
PostInstanceMsgTag = 2,
EnumerateInstancesReqTag = 3,
PostResultMsgTag = 4,
NoOpReqTag = 5,
NoOpRspTag = 6,
DispResultMsgTag = 7,
InvokeReqTag = 8,
AssociatorsOfReqTag = 9,
ReferencesOfReqTag = 10,
SubscribeReqTag = 11,
SubscribeResTag = 12,
DeleteInstanceReqTag = 13,
CreateInstanceReqTag = 14,
ModifyInstanceReqTag = 15,
BinProtocolNotificationTag = 16
*/
typedef struct _MessageDeclaration
{
const MessageField* fields;
size_t size;
MI_Boolean cloneRequired;
}
MessageDeclaration;
static const MessageDeclaration allMessages[] = {
{baseMessageFields, 0, MI_FALSE},
{getInstanceMessageFields, sizeof(GetInstanceReq), MI_TRUE},
{postInstanceMessageFields, sizeof(PostInstanceMsg), MI_TRUE},
{enumerateInstancesMessageFields, sizeof(EnumerateInstancesReq), MI_FALSE},
{emptyMessageFields, sizeof(PostResultMsg), MI_FALSE},
{emptyMessageFields, sizeof(NoOpReq), MI_FALSE},
{emptyMessageFields, sizeof(NoOpRsp), MI_FALSE},
{emptyMessageFields, sizeof(DispResultMsg), MI_FALSE},
{invokeMessageFields, sizeof(InvokeReq), MI_TRUE},
{associatorsOfMessageFields, sizeof(AssociatorsOfReq), MI_TRUE},
{referencesOfMessageFields, sizeof(ReferencesOfReq), MI_TRUE},
{subscribeRequestMessageFields, sizeof(SubscribeReq), MI_FALSE},
{subscribeResponseMessageFields, sizeof(SubscribeRes), MI_FALSE},
{deleteInstanceMessageFields, sizeof(DeleteInstanceReq), MI_TRUE},
{createInstanceMessageFields, sizeof(CreateInstanceReq), MI_TRUE},
{modifyInstanceMessageFields, sizeof(ModifyInstanceReq), MI_TRUE},
{binProtocolNotificationFields, sizeof(BinProtocolNotification),MI_FALSE}
};
/*
**==============================================================================
**
** Public definitions
**
**==============================================================================
*/
Message* __Message_New(
MessageTag tag,
size_t structSize,
MI_Uint64 msgID,
MI_Uint32 flags)
{
Batch *batch;
Message* self;
batch = Batch_New(BATCH_MAX_PAGES);
if (!batch)
return NULL;
/* Allocate heap space for message */
self = Batch_Get(batch, structSize);
if (!self)
return NULL;
/* Clear all fields */
memset(self, 0, structSize);
/* Set the tag */
self->tag = tag;
/* Set the message id and flags */
self->msgID = msgID;
self->flags = flags;
/* ref-counter is set to 1, to balance NewMessage/Release Message pair*/
self->refCounter = 1;
/* Copy batch onto message (released by delete method) */
self->batch = batch;
return self;
}
/*
Decrements message's ref-counter and destroys
mesage if last reference was released
Parameters:
self - message to decref/release
*/
void Message_Release(
Message* self)
{
if (AtomicDec(&self->refCounter))
{
/* Call destructor */
if (self->dtor)
(*self->dtor)(self, self->dtorData);
/* Release linked request */
if (self->request)
Message_Release(self->request);
Batch_Destroy(self->batch);
}
}
static void _Message_Print(
const void* msg,
FILE* os,
const char* structName,
const Field fields[])
{
size_t i;
fprintf(os, "%s\n", structName);
fprintf(os, "{\n");
for (i = 0; fields[i].name; i++)
{
const Field* f = &fields[i];
/* Print name */
fprintf(os, " %s=", f->name);
/* Print value */
switch (f->type)
{
case FT_UINT32:
{
MessageTag* p = (MessageTag*)((char*)msg + f->off);
fprintf(os, "%u", *p);
break;
}
case FT_RESULT:
{
MI_Result* p = (MI_Result*)((char*)msg + f->off);
Fzprintf(os, MI_T("%u [%s]"),*p, Result_ToString(*p));
break;
}
case FT_ATOMIC:
{
AtomicInt* p = (AtomicInt*)((char*)msg + f->off);
Fzprintf(os, MI_T("%d"),(int)(*p));
break;
}
case FT_UINT64:
{
MI_Uint64* p = (MI_Uint64*)((char*)msg + f->off);
fprintf(os, UINT64_FMT, *p);
break;
}
case FT_BOOLEAN:
{
MI_Boolean* p = (MI_Boolean*)((char*)msg + f->off);
fprintf(os, "%s", *p ? "TRUE" : "FALSE");
break;
}
case FT_STRING:
{
MI_Char** p = (MI_Char**)((char*)msg + f->off);
if (*p)
Fzprintf(os, MI_T("\"%s\""), *p);
else
fprintf(os, "NULL");
break;
}
case FT_STRINGA:
{
StringArray** p = (StringArray**)((char*)msg + f->off);
if (*p)
StringArray_Print(*p, os);
else
fprintf(os, "NULL");
break;
}
case FT_INSTANCE:
{
MI_Instance** p = (MI_Instance**)((char*)msg + f->off);
if (*p)
{
fputc('\n', os);
MI_Instance_Print(*p, os, 1);
}
else
fprintf(os, "NULL\n");
break;
}
default:
break;
}
if (f->type != FT_INSTANCE)
fputc('\n', os);
}
fprintf(os, "}\n");
}
void MessagePrint(const Message* msg, FILE* os)
{
switch ( msg->tag )
{
case GetInstanceReqTag:
{
const GetInstanceReq* m = (const GetInstanceReq*)msg;
GetInstanceReq_Print(m, os);
}
break;
case PostInstanceMsgTag:
{
const PostInstanceMsg* m = (const PostInstanceMsg*)msg;
PostInstanceMsg_Print(m, os);
}
break;
case EnumerateInstancesReqTag:
{
const EnumerateInstancesReq* m = (const EnumerateInstancesReq*)msg;
EnumerateInstancesReq_Print(m, os);
}
break;
case PostResultMsgTag:
{
const PostResultMsg* m = (const PostResultMsg*)msg;
PostResultMsg_Print(m, os);
}
break;
case NoOpReqTag:
{
const NoOpReq* m = (const NoOpReq*)msg;
NoOpReq_Print(m, os);
}
break;
case NoOpRspTag:
{
const NoOpRsp* m = (const NoOpRsp*)msg;
NoOpRsp_Print(m, os);
}
break;
case DispResultMsgTag:
{
const DispResultMsg* m = (const DispResultMsg*)msg;
DispResultMsg_Print(m, os);
}
break;
case InvokeReqTag:
{
const InvokeReq* m = (const InvokeReq*)msg;
InvokeReq_Print(m, os);
}
break;
case AssociatorsOfReqTag:
{
const AssociatorsOfReq* m = (const AssociatorsOfReq*)msg;
AssociatorsOfReq_Print(m, os);
}
break;
case ReferencesOfReqTag:
{
const ReferencesOfReq* m = (const ReferencesOfReq*)msg;
ReferencesOfReq_Print(m, os);
}
break;
case SubscribeReqTag:
{
const SubscribeReq* m = (const SubscribeReq*)msg;
SubscribeReq_Print(m, os);
}
break;
case SubscribeResTag:
{
const SubscribeRes* m = (const SubscribeRes*)msg;
SubscribeRes_Print(m, os);
}
break;
case DeleteInstanceReqTag:
{
const DeleteInstanceReq* m = (const DeleteInstanceReq*)msg;
DeleteInstanceReq_Print(m, os);
}
break;
case CreateInstanceReqTag:
{
const CreateInstanceReq* m = (const CreateInstanceReq*)msg;
CreateInstanceReq_Print(m, os);
}
break;
case ModifyInstanceReqTag:
{
const ModifyInstanceReq* m = (const ModifyInstanceReq*)msg;
ModifyInstanceReq_Print(m, os);
}
break;
case BinProtocolNotificationTag:
{
const BinProtocolNotification* m = (const BinProtocolNotification*)msg;
BinProtocolNotification_Print(m, os);
}
break;
default:
fprintf(os, "unknown message tag %d\n", msg->tag);
break;
}
}
/*
**==============================================================================
**
** Field information.
**
**==============================================================================
*/
void GetInstanceReq_Print(const GetInstanceReq* msg, FILE* os)
{
typedef GetInstanceReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
{"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
{"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "GetInstanceReq", fields);
}
void CreateInstanceReq_Print(const CreateInstanceReq* msg, FILE* os)
{
typedef CreateInstanceReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"instanceName", FT_INSTANCE, offsetof(Self, instance)},
{"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "CreateInstanceReq", fields);
}
void ModifyInstanceReq_Print(const ModifyInstanceReq* msg, FILE* os)
{
typedef ModifyInstanceReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"instanceName", FT_INSTANCE, offsetof(Self, instance)},
{"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "ModifyInstanceReq", fields);
}
void DeleteInstanceReq_Print(const DeleteInstanceReq* msg, FILE* os)
{
typedef DeleteInstanceReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "DeleteInstanceReq", fields);
}
void InvokeReq_Print(const InvokeReq* msg, FILE* os)
{
typedef InvokeReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
{"className", FT_STRING, offsetof(Self, className)},
{"function", FT_STRING, offsetof(Self, function)},
{"instance", FT_INSTANCE, offsetof(Self, instance)},
{"instanceParams", FT_INSTANCE, offsetof(Self, instanceParams)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "InvokeReq", fields);
}
void AssociatorsOfReq_Print(const AssociatorsOfReq* msg, FILE* os)
{
typedef AssociatorsOfReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
{"assocClass", FT_STRING, offsetof(Self, assocClass)},
{"resultClass", FT_STRING, offsetof(Self, resultClass)},
{"role", FT_STRING, offsetof(Self, role)},
{"resultRole", FT_STRING, offsetof(Self, resultRole)},
{"instance", FT_INSTANCE, offsetof(Self, instance)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "AssociatorsOfReq", fields);
}
void ReferencesOfReq_Print(const ReferencesOfReq* msg, FILE* os)
{
typedef ReferencesOfReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
{"assocClass", FT_STRING, offsetof(Self, assocClass)},
{"role", FT_STRING, offsetof(Self, role)},
{"instance", FT_INSTANCE, offsetof(Self, instance)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "ReferencesOfReq", fields);
}
void PostInstanceMsg_Print(const PostInstanceMsg* msg, FILE* os)
{
typedef PostInstanceMsg Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"instance", FT_INSTANCE, offsetof(Self, instance)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "PostInstanceMsg", fields);
}
void PostResultMsg_Print(const PostResultMsg* msg, FILE* os)
{
typedef PostResultMsg Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"result", FT_RESULT, offsetof(Self, result)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "PostResultMsg", fields);
}
void DispResultMsg_Print(const DispResultMsg* msg, FILE* os)
{
typedef DispResultMsg Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"result", FT_RESULT, offsetof(Self, result)},
{"requestCounter", FT_ATOMIC, offsetof(Self, requestCounter)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "DispResultMsg", fields);
}
void EnumerateInstancesReq_Print(
const EnumerateInstancesReq* msg,
FILE* os)
{
typedef EnumerateInstancesReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
{"className", FT_STRING, offsetof(Self, className)},
{"requestClassName", FT_STRING, offsetof(Self, requestClassName)},
{"deepInheritance", FT_BOOLEAN, offsetof(Self, deepInheritance)},
{"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
{"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
{"queryLanguage", FT_STRING, offsetof(Self, queryLanguage)},
{"queryExpression", FT_STRING, offsetof(Self, queryExpression)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "EnumerateInstancesReq", fields);
}
void SubscribeReq_Print(const SubscribeReq* msg, FILE* os)
{
typedef SubscribeReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
{"className", FT_STRING, offsetof(Self, className)},
{"filter", FT_STRING, offsetof(Self, filter)},
{"language", FT_STRING, offsetof(Self, language)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "SubscribeReq", fields);
}
void SubscribeRes_Print(const SubscribeRes* msg, FILE* os)
{
typedef SubscribeRes Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{"subscriptionID", FT_STRING, offsetof(Self, subscriptionID)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "SubscribeRes", fields);
}
void NoOpReq_Print(const NoOpReq* msg, FILE* os)
{
typedef NoOpReq Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "NoOpReq", fields);
}
void NoOpRsp_Print(const NoOpRsp* msg, FILE* os)
{
typedef NoOpRsp Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "NoOpRsp", fields);
}
void BinProtocolNotification_Print(const BinProtocolNotification* msg, FILE* os)
{
typedef BinProtocolNotification Self;
static const Field fields[] =
{
{"tag", FT_UINT32, offsetof(Self, base.tag)},
{"msgID", FT_UINT64, offsetof(Self, base.msgID)},
{"clientID", FT_UINT64, offsetof(Self, base.clientID)},
{NULL, 0, 0},
};
_Message_Print(msg, os, "BinProtocolNotification", fields);
}
static MI_Boolean _UnpackInstance(
Batch* batch,
void* ptr,
MI_Uint32 size,
MI_Instance** instanceOut)
{
MI_Result r;
Buf buf = BUF_INITIALIZER;
/* borrow pointer for unpacking, leaving it in the batch */
buf.data = ptr;
buf.size = size;
r = Instance_Unpack(instanceOut, &buf, batch, MI_FALSE);
return r == MI_RESULT_OK;
}
static MI_Result _RestoreMessage(
Message* msg,
const Header_BatchInfoItem* ptrAdjustmentInfo,
size_t ptrAdjustmentInfoCount,
MI_Boolean skipInstanceUnpack,
const MessageField* messageFields)
{
char* chunk = (char*)msg;
Batch* batch = msg->batch;
while (messageFields->type != MFT_END_OF_LIST)
{
void** ptr = (void**)(chunk + messageFields->off);
switch (messageFields->type)
{
case MFT_POINTER_SET_NULL:
*ptr = 0;
break;
case MFT_POINTER_OPT:
case MFT_POINTER:
if (*ptr)
{
if (!Batch_FixPointer(
batch,
ptrAdjustmentInfo,
ptrAdjustmentInfoCount,
ptr))
return MI_RESULT_INVALID_PARAMETER;
}
else if (messageFields->type == MFT_POINTER)
return MI_RESULT_INVALID_PARAMETER;
break;
case MFT_INSTANCE:
case MFT_INSTANCE_OPT:
{
void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
MI_Uint32 packedSize = * (const MI_Uint32*)(chunk + messageFields->offPackedSize);
*ptr = 0;
if (*ptrPacked)
{
if (!Batch_FixPointer(
batch,
ptrAdjustmentInfo,
ptrAdjustmentInfoCount,
ptrPacked))
return MI_RESULT_INVALID_PARAMETER;
if (!skipInstanceUnpack && !_UnpackInstance(
batch,
*ptrPacked,
packedSize,
(MI_Instance**)ptr))
return MI_RESULT_INVALID_PARAMETER;
}
else if (messageFields->type == MFT_INSTANCE)
return MI_RESULT_INVALID_PARAMETER;
}
break;
default:
break;
}
messageFields++;
}
return MI_RESULT_OK;
}
static MI_Result _Clone(
const Message* msgSrc,
Message* msg,
const MessageField* messageFields,
size_t size)
{
char* chunk = (char*)msg;
Batch* batch = msg->batch;
const char* chunkSrc = (const char*)msgSrc;
/* copy all primitve data first */
memcpy(chunk + sizeof(Message), chunkSrc + sizeof(Message), size - sizeof(Message));
while (messageFields->type != MFT_END_OF_LIST)
{
void** ptr = (void**)(chunk + messageFields->off);
void** ptrSrc = (void**)(chunkSrc + messageFields->off);
switch (messageFields->type)
{
case MFT_POINTER_SET_NULL:
default:
break;
case MFT_POINTER_OPT:
case MFT_POINTER:
if (*ptrSrc)
{
*ptr = Batch_Strdup2(batch, (const char*)*ptrSrc);
if (!*ptr)
return MI_RESULT_FAILED;
}
else if (messageFields->type == MFT_POINTER)
return MI_RESULT_INVALID_PARAMETER;
break;
case MFT_INSTANCE:
case MFT_INSTANCE_OPT:
{
void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
MI_Uint32* packedSize = (MI_Uint32*)(chunk + messageFields->offPackedSize);
const void* ptrPackedSrc = *(void**)(chunkSrc + messageFields->offPackedPtr);
MI_Uint32 packedSizeSrc = *(MI_Uint32*)(chunkSrc + messageFields->offPackedSize);
*ptr = 0;
if (ptrPackedSrc)
{
/* Take existing packed instance if exist (received from binary protocol */
*packedSize = packedSizeSrc;
*ptrPacked = Batch_Get(batch, packedSizeSrc);
if (!*ptrPacked)
return MI_RESULT_FAILED;
memcpy(*ptrPacked, ptrPackedSrc, packedSizeSrc);
}
else if (*ptrSrc)
{
/* Pack instance in binary buffer (received form wsman) */
if (MI_RESULT_OK != InstanceToBatch(
(const MI_Instance*)(*ptrSrc),
NULL, /* filterProperties */
NULL, /* filterPropertiesData */
batch,
ptrPacked, packedSize))
return MI_RESULT_FAILED;
}
else if (messageFields->type == MFT_INSTANCE)
/* Return error if non-optional parameter is missing */
return MI_RESULT_INVALID_PARAMETER;
}
break;
}
messageFields++;
}
return MI_RESULT_OK;
}
MI_Result MessageFromBatch(
Batch* batch,
void* originalMsgPtr,
const Header_BatchInfoItem* ptrAdjustmentInfo,
size_t ptrAdjustmentInfoCount,
MI_Boolean skipInstanceUnpack,
Message** msgOut)
{
Message* msg = originalMsgPtr;
MI_Uint32 index;
if (!Batch_FixPointer(
batch,
ptrAdjustmentInfo,
ptrAdjustmentInfoCount,
(void*)&msg))
return MI_RESULT_INVALID_PARAMETER;
/* fix base part of message */
msg->batch = batch;
msg->refCounter = 1;
if (MI_RESULT_OK != _RestoreMessage(
msg,
ptrAdjustmentInfo,
ptrAdjustmentInfoCount,
skipInstanceUnpack,
baseMessageFields))
return MI_RESULT_INVALID_PARAMETER;
index = (MI_Uint32)msg->tag;
if (index >= MI_COUNT(allMessages))
return MI_RESULT_INVALID_PARAMETER;
if (MI_RESULT_OK != _RestoreMessage(
msg,
ptrAdjustmentInfo,
ptrAdjustmentInfoCount,
skipInstanceUnpack,
allMessages[index].fields))
return MI_RESULT_INVALID_PARAMETER;
*msgOut = msg;
return MI_RESULT_OK;
}
MI_Result MessagePackCloneForBinarySending(
Message* msgSrc,
Message** msgOut)
{
Message* msg = msgSrc;
MI_Uint32 index;
index = (MI_Uint32)msg->tag;
if (index >= MI_COUNT(allMessages))
return MI_RESULT_INVALID_PARAMETER;
if (!allMessages[index].cloneRequired)
{
*msgOut = msg;
Message_AddRef(msg);
return MI_RESULT_OK;
}
/* create a copy */
msg = __Message_New(msgSrc->tag, allMessages[index].size, msgSrc->msgID, msgSrc->flags);
if (!msg)
return MI_RESULT_FAILED;
msg->clientID = msgSrc->clientID;
if (MI_RESULT_OK != _Clone(msgSrc, msg, allMessages[index].fields, allMessages[index].size))
{
Message_Release(msg);
return MI_RESULT_FAILED;
}
*msgOut = msg;
return MI_RESULT_OK;
}