(file) Return to messages.c CVS log (file) (dir) Up to [OMI] / omi / base

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include "messages.h"
  26           #include "packing.h"
  27           #include <assert.h>
  28           #include "result.h"
  29           #include "io.h"
  30           
  31           /*
  32           **==============================================================================
  33           **
  34           ** Local definitions
  35           **
  36           **==============================================================================
  37           */
  38           
  39           typedef enum _FieldType
  40           {
  41               FT_BOOLEAN = MI_BOOLEAN,
  42               FT_UINT8 = MI_UINT8,
  43 mike  1.1     FT_SINT8 = MI_SINT8,
  44               FT_UINT16 = MI_UINT16,
  45               FT_SINT16 = MI_SINT16,
  46               FT_UINT32 = MI_UINT32,
  47               FT_SINT32 = MI_SINT32,
  48               FT_UINT64 = MI_UINT64,
  49               FT_SINT64 = MI_SINT64,
  50               FT_REAL32 = MI_REAL32,
  51               FT_REAL64 = MI_REAL64,
  52               FT_CHAR16 = MI_CHAR16,
  53               FT_DATETIME = MI_DATETIME,
  54               FT_STRING = MI_STRING,
  55               FT_REFERENCE = MI_REFERENCE,
  56               FT_INSTANCE = MI_INSTANCE,
  57               FT_BOOLEANA = MI_BOOLEANA,
  58               FT_UINT8A = MI_UINT8A,
  59               FT_SINT8A = MI_SINT8A,
  60               FT_UINT16A = MI_UINT16A,
  61               FT_SINT16A = MI_SINT16A,
  62               FT_UINT32A = MI_UINT32A,
  63               FT_SINT32A = MI_SINT32A,
  64 mike  1.1     FT_UINT64A = MI_UINT64A,
  65               FT_SINT64A = MI_SINT64A,
  66               FT_REAL32A = MI_REAL32A,
  67               FT_REAL64A = MI_REAL64A,
  68               FT_CHAR16A = MI_CHAR16A,
  69               FT_DATETIMEA = MI_DATETIMEA,
  70               FT_STRINGA = MI_STRINGA,
  71               FT_REFERENCEA = MI_REFERENCEA,
  72               FT_INSTANCEA = MI_INSTANCEA,
  73               FT_RESULT,
  74               FT_ATOMIC
  75           }
  76           FieldType;
  77           
  78           /* Defines meta data for message field (to support printing) */
  79           typedef struct Field
  80           {
  81               /* Name of field */
  82               const char* name;
  83           
  84               /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
  85 mike  1.1     FieldType type;
  86           
  87               /* Byte off within structure to this field */
  88               size_t off;
  89           }
  90           Field;
  91           
  92           typedef enum _MessageFieldType
  93           {
  94               MFT_END_OF_LIST,    /* special type to terminate list of fields */
  95               MFT_POINTER,        /* Pointer that has to be converted */
  96               MFT_POINTER_OPT,    /* Pointer that has to be converted (may be null) */
  97               MFT_POINTER_SET_NULL,   /* Pointer that has to be nullified instead of converting */
  98               MFT_INSTANCE,       /* instance */
  99               MFT_INSTANCE_OPT    /* instance  (maybe NULL) */
 100           }
 101           MessageFieldType;
 102           
 103           /* Defines meta data for message field (to support packing/unpacking) */
 104           typedef struct _MessageField
 105           {
 106 mike  1.1     /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
 107               MessageFieldType type;
 108           
 109               /* Byte off within structure to this field and (for instance) to packed pointer/size */
 110               size_t off;
 111               size_t offPackedPtr;
 112               size_t offPackedSize;
 113           }
 114           MessageField;
 115           
 116           static const MessageField baseMessageFields[] = 
 117           {
 118               {MFT_POINTER_SET_NULL,offsetof(Message, next),0,0},
 119               {MFT_POINTER_SET_NULL,offsetof(Message, prev),0,0},
 120               {MFT_POINTER_SET_NULL,offsetof(Message, request),0,0},
 121               {MFT_POINTER_SET_NULL,offsetof(Message, callback),0,0},
 122               {MFT_POINTER_SET_NULL,offsetof(Message, callbackData),0,0},
 123               {MFT_POINTER_SET_NULL,offsetof(Message, dtor),0,0},
 124               {MFT_POINTER_SET_NULL,offsetof(Message, dtorData),0,0},
 125               {MFT_POINTER_OPT,offsetof(Message, libraryName),0,0},
 126               {MFT_END_OF_LIST, 0, 0, 0}
 127 mike  1.1 };
 128           
 129           static const MessageField emptyMessageFields[] = 
 130           {
 131               {MFT_END_OF_LIST, 0, 0, 0}
 132           };
 133           
 134           static const MessageField getInstanceMessageFields[] = 
 135           {
 136               {MFT_POINTER,offsetof(GetInstanceReq, nameSpace),0,0},
 137               {MFT_INSTANCE,offsetof(GetInstanceReq, instanceName),offsetof(GetInstanceReq, packedInstanceNamePtr),offsetof(GetInstanceReq, packedInstanceNameSize)},
 138               {MFT_END_OF_LIST, 0, 0, 0}
 139           };
 140           
 141           static const MessageField postInstanceMessageFields[] = 
 142           {
 143               {MFT_INSTANCE,offsetof(PostInstanceMsg, instance),offsetof(PostInstanceMsg, packedInstancePtr),offsetof(PostInstanceMsg, packedInstanceSize)},
 144               {MFT_END_OF_LIST, 0, 0, 0}
 145           };
 146           
 147           static const MessageField enumerateInstancesMessageFields[] = 
 148 mike  1.1 {
 149               {MFT_POINTER,offsetof(EnumerateInstancesReq, nameSpace),0,0},
 150               {MFT_POINTER,offsetof(EnumerateInstancesReq, className),0,0},
 151               {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, requestClassName),0,0},
 152               {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryLanguage),0,0},
 153               {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryExpression),0,0},
 154               {MFT_END_OF_LIST, 0, 0, 0}
 155           };
 156           
 157           static const MessageField invokeMessageFields[] = 
 158           {
 159               {MFT_POINTER,offsetof(InvokeReq, nameSpace),0,0},
 160               {MFT_POINTER,offsetof(InvokeReq, function),0,0},
 161               {MFT_POINTER_OPT,offsetof(InvokeReq, className),0,0},
 162               {MFT_INSTANCE_OPT,offsetof(InvokeReq, instance),offsetof(InvokeReq, packedInstancePtr),offsetof(InvokeReq, packedInstanceSize)},
 163               {MFT_INSTANCE_OPT,offsetof(InvokeReq, instanceParams),offsetof(InvokeReq, packedInstanceParamsPtr),offsetof(InvokeReq, packedInstanceParamsSize)},
 164               {MFT_END_OF_LIST, 0, 0, 0}
 165           };
 166           
 167           static const MessageField associatorsOfMessageFields[] = 
 168           {
 169 mike  1.1     {MFT_POINTER,offsetof(AssociatorsOfReq, nameSpace),0,0},
 170               {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, className),0,0},
 171               {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, assocClass),0,0},
 172               {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultClass),0,0},
 173               {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, role),0,0},
 174               {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultRole),0,0},
 175               {MFT_INSTANCE,offsetof(AssociatorsOfReq, instance),offsetof(AssociatorsOfReq, packedInstancePtr),offsetof(AssociatorsOfReq, packedInstanceSize)},
 176               {MFT_END_OF_LIST, 0, 0, 0}
 177           };
 178           
 179           static const MessageField referencesOfMessageFields[] = 
 180           {
 181               {MFT_POINTER,offsetof(ReferencesOfReq, nameSpace),0,0},
 182               {MFT_POINTER_OPT,offsetof(ReferencesOfReq, className),0,0},
 183               {MFT_POINTER_OPT,offsetof(ReferencesOfReq, assocClass),0,0},
 184               {MFT_POINTER_OPT,offsetof(ReferencesOfReq, role),0,0},
 185               {MFT_INSTANCE,offsetof(ReferencesOfReq, instance),offsetof(ReferencesOfReq, packedInstancePtr),offsetof(ReferencesOfReq, packedInstanceSize)},
 186               {MFT_END_OF_LIST, 0, 0, 0}
 187           };
 188           
 189           static const MessageField subscribeRequestMessageFields[] = 
 190 mike  1.1 {
 191               {MFT_POINTER,offsetof(SubscribeReq, nameSpace),0,0},
 192               {MFT_POINTER,offsetof(SubscribeReq, className),0,0},
 193               {MFT_POINTER,offsetof(SubscribeReq, filter),0,0},
 194               {MFT_POINTER,offsetof(SubscribeReq, language),0,0},
 195               {MFT_END_OF_LIST, 0, 0, 0}
 196           };
 197           
 198           static const MessageField subscribeResponseMessageFields[] = 
 199           {
 200               {MFT_POINTER,offsetof(SubscribeRes, subscriptionID),0,0},
 201               {MFT_END_OF_LIST, 0, 0, 0}
 202           };
 203           
 204           static const MessageField deleteInstanceMessageFields[] = 
 205           {
 206               {MFT_POINTER,offsetof(DeleteInstanceReq, nameSpace),0,0},
 207               {MFT_INSTANCE,offsetof(DeleteInstanceReq, instanceName),offsetof(DeleteInstanceReq, packedInstanceNamePtr),offsetof(DeleteInstanceReq, packedInstanceNameSize)},
 208               {MFT_END_OF_LIST, 0, 0, 0}
 209           };
 210           
 211 mike  1.1 static const MessageField createInstanceMessageFields[] = 
 212           {
 213               {MFT_POINTER,offsetof(CreateInstanceReq, nameSpace),0,0},
 214               {MFT_INSTANCE,offsetof(CreateInstanceReq, instance),offsetof(CreateInstanceReq, packedInstancePtr),offsetof(CreateInstanceReq, packedInstanceSize)},
 215               {MFT_END_OF_LIST, 0, 0, 0}
 216           };
 217           
 218           static const MessageField modifyInstanceMessageFields[] = 
 219           {
 220               {MFT_POINTER,offsetof(ModifyInstanceReq, nameSpace),0,0},
 221               {MFT_INSTANCE,offsetof(ModifyInstanceReq, instance),offsetof(ModifyInstanceReq, packedInstancePtr),offsetof(ModifyInstanceReq, packedInstanceSize)},
 222               {MFT_END_OF_LIST, 0, 0, 0}
 223           };
 224           
 225           static const MessageField binProtocolNotificationFields[] = 
 226           {
 227               {MFT_POINTER_OPT,offsetof(BinProtocolNotification, user),0,0},
 228               {MFT_POINTER_OPT,offsetof(BinProtocolNotification, password),0,0},
 229               {MFT_POINTER_OPT,offsetof(BinProtocolNotification, authFile),0,0},
 230               {MFT_END_OF_LIST, 0, 0, 0}
 231           };
 232 mike  1.1 
 233           /* Entries in this array corresponds to MessageTag values:
 234               GetInstanceReqTag = 1,
 235               PostInstanceMsgTag = 2,
 236               EnumerateInstancesReqTag = 3,
 237               PostResultMsgTag = 4,
 238               NoOpReqTag = 5,
 239               NoOpRspTag = 6,
 240               DispResultMsgTag = 7,
 241               InvokeReqTag = 8,
 242               AssociatorsOfReqTag = 9,
 243               ReferencesOfReqTag = 10,
 244               SubscribeReqTag = 11,
 245               SubscribeResTag = 12,
 246               DeleteInstanceReqTag = 13,
 247               CreateInstanceReqTag = 14,
 248               ModifyInstanceReqTag = 15,
 249               BinProtocolNotificationTag = 16
 250           */
 251           typedef struct _MessageDeclaration
 252           {
 253 mike  1.1     const MessageField* fields;
 254               size_t              size;
 255               MI_Boolean          cloneRequired;
 256           }
 257           MessageDeclaration;
 258           
 259           static const MessageDeclaration allMessages[] = {
 260               {baseMessageFields,                 0,                       MI_FALSE},
 261               {getInstanceMessageFields,          sizeof(GetInstanceReq),   MI_TRUE},
 262               {postInstanceMessageFields,         sizeof(PostInstanceMsg),        MI_TRUE},
 263               {enumerateInstancesMessageFields,   sizeof(EnumerateInstancesReq),      MI_FALSE},
 264               {emptyMessageFields,                sizeof(PostResultMsg),      MI_FALSE},
 265               {emptyMessageFields,                sizeof(NoOpReq),        MI_FALSE},
 266               {emptyMessageFields,                sizeof(NoOpRsp),        MI_FALSE},
 267               {emptyMessageFields,                sizeof(DispResultMsg),      MI_FALSE},
 268               {invokeMessageFields,               sizeof(InvokeReq),      MI_TRUE},
 269               {associatorsOfMessageFields,        sizeof(AssociatorsOfReq),       MI_TRUE},
 270               {referencesOfMessageFields,         sizeof(ReferencesOfReq),        MI_TRUE},
 271               {subscribeRequestMessageFields,     sizeof(SubscribeReq),       MI_FALSE},
 272               {subscribeResponseMessageFields,    sizeof(SubscribeRes),       MI_FALSE},
 273               {deleteInstanceMessageFields,       sizeof(DeleteInstanceReq),      MI_TRUE},
 274 mike  1.1     {createInstanceMessageFields,       sizeof(CreateInstanceReq),      MI_TRUE},
 275               {modifyInstanceMessageFields,       sizeof(ModifyInstanceReq),      MI_TRUE},
 276               {binProtocolNotificationFields,     sizeof(BinProtocolNotification),MI_FALSE}
 277           };  
 278               
 279           /*
 280           **==============================================================================
 281           **
 282           ** Public definitions
 283           **
 284           **==============================================================================
 285           */
 286           
 287           Message* __Message_New(
 288               MessageTag tag,
 289               size_t structSize,
 290               MI_Uint64 msgID,
 291               MI_Uint32 flags)
 292           {
 293               Batch *batch;
 294               Message* self;
 295 mike  1.1 
 296               batch = Batch_New(BATCH_MAX_PAGES);
 297           
 298               if (!batch)
 299                   return NULL;
 300           
 301               /* Allocate heap space for message */
 302               self = Batch_Get(batch, structSize);
 303           
 304               if (!self)
 305                   return NULL;
 306           
 307               /* Clear all fields */
 308               memset(self, 0, structSize);
 309           
 310               /* Set the tag */
 311               self->tag = tag;
 312           
 313               /* Set the message id and flags */
 314               self->msgID = msgID;
 315               self->flags = flags;
 316 mike  1.1 
 317               /* ref-counter is set to 1, to balance NewMessage/Release Message pair*/
 318               self->refCounter = 1;
 319           
 320               /* Copy batch onto message (released by delete method) */
 321               self->batch = batch;
 322           
 323               return self;
 324           }
 325           
 326           /*
 327               Decrements message's ref-counter and destroys
 328               mesage if last reference was released
 329               Parameters:
 330               self - message to decref/release
 331           */
 332           void Message_Release(
 333               Message* self)
 334           {
 335               if (AtomicDec(&self->refCounter))
 336               {
 337 mike  1.1         /* Call destructor */
 338                   if (self->dtor)
 339                       (*self->dtor)(self, self->dtorData);
 340           
 341                   /* Release linked request */
 342                   if (self->request)
 343                       Message_Release(self->request);
 344           
 345                   Batch_Destroy(self->batch);
 346               }
 347           }
 348           
 349           static void _Message_Print(
 350               const void* msg, 
 351               FILE* os, 
 352               const char* structName,
 353               const Field fields[])
 354           {
 355               size_t i;
 356           
 357               fprintf(os, "%s\n", structName);
 358 mike  1.1     fprintf(os, "{\n");
 359           
 360               for (i = 0; fields[i].name; i++)
 361               {
 362                   const Field* f = &fields[i];
 363           
 364                   /* Print name */
 365                   fprintf(os, "    %s=", f->name);
 366           
 367                   /* Print value */
 368                   switch (f->type)
 369                   {
 370                       case FT_UINT32:
 371                       {
 372                           MessageTag* p = (MessageTag*)((char*)msg + f->off);
 373                           fprintf(os, "%u", *p);
 374                           break;
 375                       }
 376                       case FT_RESULT:
 377                       {
 378                           MI_Result* p = (MI_Result*)((char*)msg + f->off);
 379 mike  1.1                 Fzprintf(os, MI_T("%u [%s]"),*p, Result_ToString(*p));
 380           
 381                           break;
 382                       }
 383                       case FT_ATOMIC:
 384                       {
 385                           AtomicInt* p = (AtomicInt*)((char*)msg + f->off);
 386                           Fzprintf(os, MI_T("%d"),(int)(*p));
 387           
 388                           break;
 389                       }
 390                       case FT_UINT64:
 391                       {
 392                           MI_Uint64* p = (MI_Uint64*)((char*)msg + f->off);
 393                           fprintf(os, UINT64_FMT, *p);
 394                           break;
 395                       }
 396                       case FT_BOOLEAN:
 397                       {
 398                           MI_Boolean* p = (MI_Boolean*)((char*)msg + f->off);
 399                           fprintf(os, "%s", *p ? "TRUE" : "FALSE");
 400 mike  1.1                 break;
 401                       }
 402                       case FT_STRING:
 403                       {
 404                           MI_Char** p = (MI_Char**)((char*)msg + f->off);
 405           
 406                           if (*p)
 407                               Fzprintf(os, MI_T("\"%s\""), *p);
 408                           else
 409                               fprintf(os, "NULL");
 410                           break;
 411                       }
 412                       case FT_STRINGA:
 413                       {
 414                           StringArray** p = (StringArray**)((char*)msg + f->off);
 415           
 416                           if (*p)
 417                               StringArray_Print(*p, os);
 418                           else
 419                               fprintf(os, "NULL");
 420                           break;
 421 mike  1.1             }
 422                       case FT_INSTANCE:
 423                       {
 424                           MI_Instance** p = (MI_Instance**)((char*)msg + f->off);
 425           
 426                           if (*p)
 427                           {
 428                               fputc('\n', os);
 429                               MI_Instance_Print(*p, os, 1);
 430                           }
 431                           else
 432                               fprintf(os, "NULL\n");
 433                           break;
 434                       }
 435                       default:
 436                           break;
 437                   }
 438           
 439                   if (f->type != FT_INSTANCE)
 440                       fputc('\n', os);
 441               }
 442 mike  1.1 
 443               fprintf(os, "}\n");
 444           }
 445           
 446           void MessagePrint(const Message* msg, FILE* os)
 447           {
 448               switch ( msg->tag )
 449               {
 450                   case GetInstanceReqTag:
 451                       {
 452                           const GetInstanceReq* m = (const GetInstanceReq*)msg;
 453                           GetInstanceReq_Print(m, os);
 454                       }
 455                       break;
 456           
 457                   case PostInstanceMsgTag:
 458                       {
 459                           const PostInstanceMsg* m = (const PostInstanceMsg*)msg;
 460                           PostInstanceMsg_Print(m, os);
 461                       }
 462                       break;
 463 mike  1.1 
 464                   case EnumerateInstancesReqTag:
 465                       {
 466                           const EnumerateInstancesReq* m = (const EnumerateInstancesReq*)msg;
 467                           EnumerateInstancesReq_Print(m, os);
 468                       }
 469                       break;
 470           
 471                   case PostResultMsgTag:
 472                       {
 473                           const PostResultMsg* m = (const PostResultMsg*)msg;
 474                           PostResultMsg_Print(m, os);
 475                       }
 476                       break;
 477           
 478                   case NoOpReqTag:
 479                       {
 480                           const NoOpReq* m = (const NoOpReq*)msg;
 481                           NoOpReq_Print(m, os);
 482                       }
 483                       break;
 484 mike  1.1 
 485                   case NoOpRspTag:
 486                       {
 487                           const NoOpRsp* m = (const NoOpRsp*)msg;
 488                           NoOpRsp_Print(m, os);
 489                       }
 490                       break;
 491           
 492                   case DispResultMsgTag:
 493                       {
 494                           const DispResultMsg* m = (const DispResultMsg*)msg;
 495                           DispResultMsg_Print(m, os);
 496                       }
 497                       break;
 498           
 499                   case InvokeReqTag:
 500                       {
 501                           const InvokeReq* m = (const InvokeReq*)msg;
 502                           InvokeReq_Print(m, os);
 503                       }
 504                       break;
 505 mike  1.1 
 506                   case AssociatorsOfReqTag:
 507                       {
 508                           const AssociatorsOfReq* m = (const AssociatorsOfReq*)msg;
 509                           AssociatorsOfReq_Print(m, os);
 510                       }
 511                       break;
 512           
 513                   case ReferencesOfReqTag:
 514                       {
 515                           const ReferencesOfReq* m = (const ReferencesOfReq*)msg;
 516                           ReferencesOfReq_Print(m, os);
 517                       }
 518                       break;
 519           
 520                   case SubscribeReqTag:
 521                       {
 522                           const SubscribeReq* m = (const SubscribeReq*)msg;
 523                           SubscribeReq_Print(m, os);
 524                       }
 525                       break;
 526 mike  1.1 
 527                   case SubscribeResTag:
 528                       {
 529                           const SubscribeRes* m = (const SubscribeRes*)msg;
 530                           SubscribeRes_Print(m, os);
 531                       }
 532                       break;
 533           
 534                   case DeleteInstanceReqTag:
 535                       {
 536                           const DeleteInstanceReq* m = (const DeleteInstanceReq*)msg;
 537                           DeleteInstanceReq_Print(m, os);
 538                       }
 539                       break;
 540           
 541                   case CreateInstanceReqTag:
 542                       {
 543                           const CreateInstanceReq* m = (const CreateInstanceReq*)msg;
 544                           CreateInstanceReq_Print(m, os);
 545                       }
 546                       break;
 547 mike  1.1 
 548                   case ModifyInstanceReqTag:
 549                       {
 550                           const ModifyInstanceReq* m = (const ModifyInstanceReq*)msg;
 551                           ModifyInstanceReq_Print(m, os);
 552                       }
 553                       break;
 554           
 555                   case BinProtocolNotificationTag:
 556                       {
 557                           const BinProtocolNotification* m = (const BinProtocolNotification*)msg;
 558                           BinProtocolNotification_Print(m, os);
 559                       }
 560                       break;
 561           
 562                   default:
 563                       fprintf(os, "unknown message tag %d\n", msg->tag);
 564                       break;
 565           
 566               }
 567           }
 568 mike  1.1 
 569           /*
 570           **==============================================================================
 571           **
 572           ** Field information.
 573           **
 574           **==============================================================================
 575           */
 576           
 577           void GetInstanceReq_Print(const GetInstanceReq* msg, FILE* os)
 578           {
 579               typedef GetInstanceReq Self;
 580               static const Field fields[] =
 581               {
 582                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 583                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 584                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 585                   {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
 586                   {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
 587                   {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
 588                   {NULL, 0, 0},
 589 mike  1.1     };
 590               _Message_Print(msg, os, "GetInstanceReq", fields);
 591           }
 592           
 593           void CreateInstanceReq_Print(const CreateInstanceReq* msg, FILE* os)
 594           {
 595               typedef CreateInstanceReq Self;
 596               static const Field fields[] =
 597               {
 598                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 599                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 600                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 601                   {"instanceName", FT_INSTANCE, offsetof(Self, instance)},
 602                   {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
 603                   {NULL, 0, 0},
 604               };
 605               _Message_Print(msg, os, "CreateInstanceReq", fields);
 606           }
 607           
 608           void ModifyInstanceReq_Print(const ModifyInstanceReq* msg, FILE* os)
 609           {
 610 mike  1.1     typedef ModifyInstanceReq Self;
 611               static const Field fields[] =
 612               {
 613                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 614                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 615                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 616                   {"instanceName", FT_INSTANCE, offsetof(Self, instance)},
 617                   {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
 618                   {NULL, 0, 0},
 619               };
 620               _Message_Print(msg, os, "ModifyInstanceReq", fields);
 621           }
 622           
 623           void DeleteInstanceReq_Print(const DeleteInstanceReq* msg, FILE* os)
 624           {
 625               typedef DeleteInstanceReq Self;
 626               static const Field fields[] =
 627               {
 628                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 629                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 630                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 631 mike  1.1         {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
 632                   {NULL, 0, 0},
 633               };
 634               _Message_Print(msg, os, "DeleteInstanceReq", fields);
 635           }
 636           
 637           void InvokeReq_Print(const InvokeReq* msg, FILE* os)
 638           {
 639               typedef InvokeReq Self;
 640               static const Field fields[] =
 641               {
 642                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 643                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 644                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 645                   {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
 646                   {"className", FT_STRING, offsetof(Self, className)},
 647                   {"function", FT_STRING, offsetof(Self, function)},
 648                   {"instance", FT_INSTANCE, offsetof(Self, instance)},
 649                   {"instanceParams", FT_INSTANCE, offsetof(Self, instanceParams)},
 650                   {NULL, 0, 0},
 651               };
 652 mike  1.1     _Message_Print(msg, os, "InvokeReq", fields);
 653           }
 654           
 655           void AssociatorsOfReq_Print(const AssociatorsOfReq* msg, FILE* os)
 656           {
 657               typedef AssociatorsOfReq Self;
 658               static const Field fields[] =
 659               {
 660                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 661                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 662                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 663                   {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
 664                   {"assocClass", FT_STRING, offsetof(Self, assocClass)},
 665                   {"resultClass", FT_STRING, offsetof(Self, resultClass)},
 666                   {"role", FT_STRING, offsetof(Self, role)},
 667                   {"resultRole", FT_STRING, offsetof(Self, resultRole)},
 668                   {"instance", FT_INSTANCE, offsetof(Self, instance)},
 669                   {NULL, 0, 0},
 670               };
 671               _Message_Print(msg, os, "AssociatorsOfReq", fields);
 672           }
 673 mike  1.1 
 674           void ReferencesOfReq_Print(const ReferencesOfReq* msg, FILE* os)
 675           {
 676               typedef ReferencesOfReq Self;
 677               static const Field fields[] =
 678               {
 679                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 680                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 681                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 682                   {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
 683                   {"assocClass", FT_STRING, offsetof(Self, assocClass)},
 684                   {"role", FT_STRING, offsetof(Self, role)},
 685                   {"instance", FT_INSTANCE, offsetof(Self, instance)},
 686                   {NULL, 0, 0},
 687               };
 688               _Message_Print(msg, os, "ReferencesOfReq", fields);
 689           }
 690           
 691           void PostInstanceMsg_Print(const PostInstanceMsg* msg, FILE* os)
 692           {
 693               typedef PostInstanceMsg Self;
 694 mike  1.1     static const Field fields[] =
 695               {
 696                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 697                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 698                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 699                   {"instance", FT_INSTANCE, offsetof(Self, instance)},
 700                   {NULL, 0, 0},
 701               };
 702               _Message_Print(msg, os, "PostInstanceMsg", fields);
 703           }
 704           
 705           void PostResultMsg_Print(const PostResultMsg* msg, FILE* os)
 706           {
 707               typedef PostResultMsg Self;
 708               static const Field fields[] =
 709               {
 710                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 711                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 712                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 713                   {"result", FT_RESULT, offsetof(Self, result)},
 714                   {NULL, 0, 0},
 715 mike  1.1     };
 716               _Message_Print(msg, os, "PostResultMsg", fields);
 717           }
 718           
 719           void DispResultMsg_Print(const DispResultMsg* msg, FILE* os)
 720           {
 721               typedef DispResultMsg Self;
 722               static const Field fields[] =
 723               {
 724                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 725                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 726                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 727                   {"result", FT_RESULT, offsetof(Self, result)},
 728                   {"requestCounter", FT_ATOMIC, offsetof(Self, requestCounter)},
 729                   {NULL, 0, 0},
 730               };
 731               _Message_Print(msg, os, "DispResultMsg", fields);
 732           }
 733           
 734           void EnumerateInstancesReq_Print(
 735               const EnumerateInstancesReq* msg, 
 736 mike  1.1     FILE* os)
 737           {
 738               typedef EnumerateInstancesReq Self;
 739               static const Field fields[] =
 740               {
 741                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 742                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 743                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 744                   {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
 745                   {"className", FT_STRING, offsetof(Self, className)},
 746                   {"requestClassName", FT_STRING, offsetof(Self, requestClassName)},
 747                   {"deepInheritance", FT_BOOLEAN, offsetof(Self, deepInheritance)},
 748                   {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
 749                   {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
 750                   {"queryLanguage", FT_STRING, offsetof(Self, queryLanguage)},
 751                   {"queryExpression", FT_STRING, offsetof(Self, queryExpression)},
 752                   {NULL, 0, 0},
 753               };
 754               _Message_Print(msg, os, "EnumerateInstancesReq", fields);
 755           }
 756           
 757 mike  1.1 void SubscribeReq_Print(const SubscribeReq* msg, FILE* os)
 758           {
 759               typedef SubscribeReq Self;
 760               static const Field fields[] =
 761               {
 762                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 763                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 764                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 765                   {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
 766                   {"className", FT_STRING, offsetof(Self, className)},
 767                   {"filter", FT_STRING, offsetof(Self, filter)},
 768                   {"language", FT_STRING, offsetof(Self, language)},
 769                   {NULL, 0, 0},
 770               };
 771               _Message_Print(msg, os, "SubscribeReq", fields);
 772           }
 773           
 774           void SubscribeRes_Print(const SubscribeRes* msg, FILE* os)
 775           {
 776               typedef SubscribeRes Self;
 777               static const Field fields[] =
 778 mike  1.1     {
 779                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 780                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 781                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 782                   {"subscriptionID", FT_STRING, offsetof(Self, subscriptionID)},
 783                   {NULL, 0, 0},
 784               };
 785               _Message_Print(msg, os, "SubscribeRes", fields);
 786           }
 787           
 788           void NoOpReq_Print(const NoOpReq* msg, FILE* os)
 789           {
 790               typedef NoOpReq Self;
 791               static const Field fields[] =
 792               {
 793                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 794                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 795                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 796                   {NULL, 0, 0},
 797               };
 798               _Message_Print(msg, os, "NoOpReq", fields);
 799 mike  1.1 }
 800           
 801           void NoOpRsp_Print(const NoOpRsp* msg, FILE* os)
 802           {
 803               typedef NoOpRsp Self;
 804               static const Field fields[] =
 805               {
 806                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 807                   {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 808                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 809                   {NULL, 0, 0},
 810               };
 811               _Message_Print(msg, os, "NoOpRsp", fields);
 812           }
 813           
 814           void BinProtocolNotification_Print(const BinProtocolNotification* msg, FILE* os)
 815           {
 816               typedef BinProtocolNotification Self;
 817               static const Field fields[] =
 818               {
 819                   {"tag", FT_UINT32, offsetof(Self, base.tag)},
 820 mike  1.1         {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
 821                   {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
 822                   {NULL, 0, 0},
 823               };
 824               _Message_Print(msg, os, "BinProtocolNotification", fields);
 825           }
 826           
 827           static MI_Boolean _UnpackInstance(
 828               Batch* batch,
 829               void* ptr,
 830               MI_Uint32 size,
 831               MI_Instance** instanceOut)
 832           {
 833               MI_Result r;
 834               Buf buf = BUF_INITIALIZER;
 835           
 836               /* borrow pointer for unpacking, leaving it in the batch */
 837               buf.data = ptr;
 838               buf.size = size;
 839           
 840               r = Instance_Unpack(instanceOut, &buf, batch, MI_FALSE);
 841 mike  1.1     return r == MI_RESULT_OK;
 842           }
 843           
 844           static MI_Result _RestoreMessage(
 845               Message* msg,
 846               const Header_BatchInfoItem* ptrAdjustmentInfo,
 847               size_t ptrAdjustmentInfoCount,
 848               MI_Boolean skipInstanceUnpack,
 849               const MessageField* messageFields)
 850           {
 851               char* chunk = (char*)msg;
 852               Batch* batch = msg->batch;
 853           
 854               while (messageFields->type != MFT_END_OF_LIST)
 855               {
 856                   void** ptr = (void**)(chunk + messageFields->off);
 857                   switch (messageFields->type)
 858                   {
 859                   case MFT_POINTER_SET_NULL:
 860                       *ptr = 0;
 861                       break;
 862 mike  1.1 
 863                   case MFT_POINTER_OPT:
 864                   case MFT_POINTER:
 865                       if (*ptr)
 866                       {
 867                           if (!Batch_FixPointer(
 868                               batch,
 869                               ptrAdjustmentInfo,
 870                               ptrAdjustmentInfoCount,
 871                               ptr))
 872                                   return MI_RESULT_INVALID_PARAMETER;
 873                       }
 874                       else if (messageFields->type == MFT_POINTER)
 875                           return MI_RESULT_INVALID_PARAMETER;
 876           
 877                       break;
 878           
 879                   case MFT_INSTANCE:
 880                   case MFT_INSTANCE_OPT:
 881                       {
 882                           void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
 883 mike  1.1                 MI_Uint32 packedSize = * (const MI_Uint32*)(chunk + messageFields->offPackedSize);
 884           
 885                           *ptr = 0;
 886           
 887                           if (*ptrPacked)
 888                           {
 889                               if (!Batch_FixPointer(
 890                                   batch,
 891                                   ptrAdjustmentInfo,
 892                                   ptrAdjustmentInfoCount,
 893                                   ptrPacked))
 894                                   return MI_RESULT_INVALID_PARAMETER;
 895           
 896                               if (!skipInstanceUnpack && !_UnpackInstance(
 897                                   batch,
 898                                   *ptrPacked,
 899                                   packedSize,
 900                                   (MI_Instance**)ptr))
 901                                   return MI_RESULT_INVALID_PARAMETER;
 902                           }
 903                           else if (messageFields->type == MFT_INSTANCE)
 904 mike  1.1                     return MI_RESULT_INVALID_PARAMETER;
 905           
 906                       }
 907                       
 908                       break;
 909           
 910                   default:
 911                       break;
 912                   }
 913           
 914                   messageFields++;
 915               }
 916           
 917               return MI_RESULT_OK;
 918           }
 919           
 920           static MI_Result _Clone(
 921               const Message* msgSrc,
 922               Message* msg,
 923               const MessageField* messageFields,
 924               size_t size)
 925 mike  1.1 {
 926               char* chunk = (char*)msg;
 927               Batch* batch = msg->batch;
 928               const char* chunkSrc = (const char*)msgSrc;
 929           
 930               /* copy all primitve data first */
 931               memcpy(chunk + sizeof(Message), chunkSrc + sizeof(Message), size - sizeof(Message));
 932           
 933               while (messageFields->type != MFT_END_OF_LIST)
 934               {
 935                   void** ptr = (void**)(chunk + messageFields->off);
 936                   void** ptrSrc = (void**)(chunkSrc + messageFields->off);
 937           
 938                   switch (messageFields->type)
 939                   {
 940                   case MFT_POINTER_SET_NULL:
 941                   default:
 942                       break;
 943           
 944                   case MFT_POINTER_OPT:
 945                   case MFT_POINTER:
 946 mike  1.1             if (*ptrSrc)
 947                       {
 948                           *ptr = Batch_Strdup2(batch, (const char*)*ptrSrc);
 949           
 950                           if (!*ptr)
 951                               return MI_RESULT_FAILED;
 952                       }
 953                       else if (messageFields->type == MFT_POINTER)
 954                           return MI_RESULT_INVALID_PARAMETER;
 955           
 956                       break;
 957           
 958                   case MFT_INSTANCE:
 959                   case MFT_INSTANCE_OPT:
 960                       {
 961                           void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
 962                           MI_Uint32* packedSize =  (MI_Uint32*)(chunk + messageFields->offPackedSize);
 963                           const void* ptrPackedSrc = *(void**)(chunkSrc + messageFields->offPackedPtr);
 964                           MI_Uint32 packedSizeSrc =  *(MI_Uint32*)(chunkSrc + messageFields->offPackedSize);
 965           
 966                           *ptr = 0;
 967 mike  1.1 
 968                           if (ptrPackedSrc)
 969                           {
 970                               /* Take existing packed instance if exist (received from binary protocol */
 971                               *packedSize = packedSizeSrc;
 972                               *ptrPacked = Batch_Get(batch, packedSizeSrc);
 973           
 974                               if (!*ptrPacked)
 975                                   return MI_RESULT_FAILED;
 976           
 977                               memcpy(*ptrPacked, ptrPackedSrc, packedSizeSrc);
 978                           }
 979                           else if (*ptrSrc)
 980                           {
 981                               /* Pack instance in binary buffer (received form wsman) */
 982                               if (MI_RESULT_OK != InstanceToBatch(
 983                                   (const MI_Instance*)(*ptrSrc), 
 984                                   NULL, /* filterProperties */
 985                                   NULL, /* filterPropertiesData */
 986                                   batch, 
 987                                   ptrPacked, packedSize))
 988 mike  1.1                         return MI_RESULT_FAILED;
 989                           }
 990                           else if (messageFields->type == MFT_INSTANCE)
 991                               /* Return error if non-optional parameter is missing */
 992                               return MI_RESULT_INVALID_PARAMETER;
 993                       }
 994                       
 995                       break;
 996                   }
 997           
 998                   messageFields++;
 999               }
1000           
1001               return MI_RESULT_OK;
1002           }
1003           MI_Result MessageFromBatch(
1004               Batch* batch,
1005               void* originalMsgPtr,
1006               const Header_BatchInfoItem* ptrAdjustmentInfo,
1007               size_t ptrAdjustmentInfoCount,
1008               MI_Boolean skipInstanceUnpack,
1009 mike  1.1     Message** msgOut)
1010           {
1011               Message* msg = originalMsgPtr;
1012               MI_Uint32 index;
1013           
1014               if (!Batch_FixPointer(
1015                   batch,
1016                   ptrAdjustmentInfo,
1017                   ptrAdjustmentInfoCount,
1018                   (void*)&msg))
1019                   return MI_RESULT_INVALID_PARAMETER;
1020           
1021               /* fix base part of message */
1022               msg->batch = batch;
1023               msg->refCounter = 1;
1024           
1025               if (MI_RESULT_OK != _RestoreMessage(
1026                   msg,
1027                   ptrAdjustmentInfo,
1028                   ptrAdjustmentInfoCount,
1029                   skipInstanceUnpack,
1030 mike  1.1         baseMessageFields))
1031                   return MI_RESULT_INVALID_PARAMETER;
1032           
1033               index = (MI_Uint32)msg->tag;
1034           
1035               if (index >= MI_COUNT(allMessages))
1036                   return MI_RESULT_INVALID_PARAMETER;
1037           
1038               if (MI_RESULT_OK != _RestoreMessage(
1039                   msg,
1040                   ptrAdjustmentInfo,
1041                   ptrAdjustmentInfoCount,
1042                   skipInstanceUnpack,
1043                   allMessages[index].fields))
1044                   return MI_RESULT_INVALID_PARAMETER;
1045           
1046               *msgOut = msg;
1047               return MI_RESULT_OK;
1048           }
1049           
1050           MI_Result MessagePackCloneForBinarySending(
1051 mike  1.1     Message* msgSrc,
1052               Message** msgOut)
1053           {
1054               Message* msg = msgSrc;
1055               MI_Uint32 index;
1056           
1057               index = (MI_Uint32)msg->tag;
1058           
1059               if (index >= MI_COUNT(allMessages))
1060                   return MI_RESULT_INVALID_PARAMETER;
1061           
1062               if (!allMessages[index].cloneRequired)
1063               {
1064                   *msgOut = msg;
1065                   Message_AddRef(msg);
1066                   return MI_RESULT_OK;
1067               }
1068           
1069               /* create a copy */
1070               msg = __Message_New(msgSrc->tag, allMessages[index].size, msgSrc->msgID, msgSrc->flags);
1071           
1072 mike  1.1     if (!msg)
1073                   return MI_RESULT_FAILED;
1074           
1075               msg->clientID = msgSrc->clientID;
1076           
1077               if (MI_RESULT_OK != _Clone(msgSrc, msg, allMessages[index].fields, allMessages[index].size))
1078               {
1079                   Message_Release(msg);
1080                   return MI_RESULT_FAILED;
1081               }
1082           
1083               *msgOut = msg;
1084               return MI_RESULT_OK;
1085           }

ViewCVS 0.9.2