/*
**==============================================================================
**
** 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 <string.h>
#include <common.h>
//#include <base/messages.h>
#include <base/batch.h>
#include <base/strings.h>
#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 */