/* **============================================================================== ** ** 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. ** **============================================================================== */ #ifndef _omi_wsman_buffer_h #define _omi_wsman_buffer_h #include "config.h" #include #include //#include #include #include #if defined(_MSC_VER) /* warning C4204: nonstandard extension used : non-constant aggregate initializer */ # pragma warning(disable : 4204) #endif /* _MSC_VER */ BEGIN_EXTERNC typedef enum _WSBUF_FAULT_CODE { WSBUF_FAULT_INTERNAL_ERROR, WSBUF_FAULT_NOT_SUPPORTED, WSBUF_FAULT_NOT_UNDERSTOOD, WSBUF_FAULT_DESTINATION_UNREACHABLE, WSBUF_FAULT_ACCESS_DENIED, WSBUF_FAULT_ENCODING_LIMIT } WSBUF_FAULT_CODE; typedef struct _WS_Buffer { Page* page; MI_Uint32 position; } WS_Buffer; MI_Result WSBuf_Init( WS_Buffer* buf, MI_Uint32 initialSize); MI_Result WSBuf_Destroy( WS_Buffer* buf); MI_Result __WSBuf_AddLit( WS_Buffer* buf, const MI_Char* str, MI_Uint32 size); /* add literal string to the buffer; * skip encoding of special characters; * length of the string is provided; * see LIT() macro */ INLINE MI_Result WSBuf_AddLit( WS_Buffer* buf, const MI_Char* str, MI_Uint32 size) { MI_Uint32 n; /* If enough capacity, add string inline */ n = size * sizeof(MI_Char); if (n + buf->position < buf->page->u.s.size) { char* data = (char*)(buf->page + 1) + buf->position; memcpy(data, str, n); ((MI_Char*)data)[size] = 0; buf->position += n; return MI_RESULT_OK; } /* Expand buffer and add string */ return __WSBuf_AddLit(buf, str, size); } /* add string to the buffer; skip encoding of special characters typically used with const strings or already encoded values */ INLINE MI_Result WSBuf_AddStringNoEncoding( WS_Buffer* buf, const MI_Char* str) { return WSBuf_AddLit(buf, str, (MI_Uint32)Zlen(str)); } INLINE MI_Result WSBuf_AddLit1( WS_Buffer* buf, MI_Char c1) { const MI_Uint32 SIZE = sizeof(c1); if (SIZE + buf->position < buf->page->u.s.size) { MI_Char* data = (MI_Char*)(((char*)(buf->page + 1)) + buf->position); data[0] = c1; data[1] = '\0'; buf->position += SIZE; return MI_RESULT_OK; } else { return __WSBuf_AddLit(buf, &c1, 1); } } INLINE MI_Result WSBuf_AddLit2( WS_Buffer* buf, MI_Char c1, MI_Char c2) { const MI_Uint32 SIZE = 2 * sizeof(c1); if (SIZE + buf->position < buf->page->u.s.size) { MI_Char* data = (MI_Char*)(((char*)(buf->page + 1)) + buf->position); data[0] = c1; data[1] = c2; data[2] = '\0'; buf->position += SIZE; return MI_RESULT_OK; } else { MI_Char str[2]; str[0] = c1; str[1] = c2; return __WSBuf_AddLit(buf, str, 2); } } INLINE MI_Result WSBuf_AddLit3( WS_Buffer* buf, MI_Char c1, MI_Char c2, MI_Char c3) { const MI_Uint32 SIZE = 3 * sizeof(c1); if (SIZE + buf->position < buf->page->u.s.size) { MI_Char* data = (MI_Char*)(((char*)(buf->page + 1)) + buf->position); data[0] = c1; data[1] = c2; data[2] = c3; data[3] = '\0'; buf->position += SIZE; return MI_RESULT_OK; } else { MI_Char str[3]; str[0] = c1; str[1] = c2; str[2] = c3; return __WSBuf_AddLit(buf, str, 3); } } INLINE MI_Result WSBuf_AddLit4( WS_Buffer* buf, MI_Char c1, MI_Char c2, MI_Char c3, MI_Char c4) { const MI_Uint32 SIZE = 4 * sizeof(c1); if (SIZE + buf->position < buf->page->u.s.size) { MI_Char* data = (MI_Char*)(((char*)(buf->page + 1)) + buf->position); data[0] = c1; data[1] = c2; data[2] = c3; data[3] = c4; data[4] = '\0'; buf->position += SIZE; return MI_RESULT_OK; } else { MI_Char str[4]; str[0] = c1; str[1] = c2; str[2] = c3; str[3] = c4; return __WSBuf_AddLit(buf, str, 4); } } MI_Result WSBuf_AddString( WS_Buffer* buf, const MI_Char* str); #if (MI_CHAR_TYPE == 1) #define WSBuf_AddCharStringNoEncoding WSBuf_AddStringNoEncoding #define WSBuf_AddCharLit WSBuf_AddLit #else /* */ MI_Result WSBuf_AddCharStringNoEncoding( WS_Buffer* buf, const char* str); MI_Result WSBuf_AddCharLit( WS_Buffer* buf, const char* str, MI_Uint32 size); #endif MI_Result WSBuf_AddUint32( WS_Buffer* buf, MI_Uint32 n); Page* WSBuf_StealPage( WS_Buffer* buf); /* Converts static/dynamic instance into wsman-xml, suitable for concatenating WS-soap xml-response. If successful, result buffer page is attached to the batch. Parameters: instance - instance to convert castToClassDecl [opt] - class-decl of output. Used only for deep enumeration with 'base-property-only' flag set. If set, this parameter must point to a valid base class. batch - batch to borrow memory from flags - flags to control instance encoding mode (EPR/Object) ptrOut - pointer to result buffer (single string with xml fragment) sizeOut - size of result buffer Returns: OK, FAILED (out of memory) */ MI_Result WSBuf_InstanceToBuf( const MI_Instance* instance, MI_Boolean (*filterProperty)(const MI_Char* name, void* data), void* filterPropertyData, const MI_ClassDecl* castToClassDecl, Batch* batch, MI_Uint32 flags, void** ptrOut, MI_Uint32* sizeOut); /* Utility */ #define WS_MSG_ID_SIZE 42 void WSBuf_GenerateMessageID( MI_Char msgID[WS_MSG_ID_SIZE]); /* Maps CIMM error to the most relevant WS fault; Retuns description of CIM error (can be used as fault description) */ WSBUF_FAULT_CODE WSBuf_CIMErrorToWSFault( MI_Uint32 cimErrorCode, const MI_Char** description ); /* Helper function to create a fault repsonse */ Page* WSBuf_CreateFaultResponsePage( WSBUF_FAULT_CODE faultCode, const char* notUnderstoodTag, const char* requestMessageID, const MI_Char* descriptionText); Page* WSBuf_CreateReleaseResponsePage( const char* requestMessageID); /* Creates soap header with provided action. Funciotn leaves header open so extra header fields can be added */ MI_Result WSBuf_CreateSoapResponseHeader( WS_Buffer *buf, const MI_Char* action, MI_Uint32 actionSize, const char* relatesTo); #define LIT(str) str,(sizeof(str)/sizeof(str[0])-1) END_EXTERNC #endif /* _omi_wsman_buffer_h */