in Unix/wsman/wsmanparser.c [821:1191]
int WS_GetInstance(
XML* xml,
XML_Elem *start,
Batch* dynamicBatch,
MI_Instance** dynamicInstanceParams,
MI_Uint32 rqtAction)
{
XML_Elem e;
const TChar* propNameA = 0;
MI_Value valueA;
MI_Type typeA = MI_BOOLEAN;
const TChar* propNamePrev = 0;
MI_Value valuePrev;
MI_Type typePrev = MI_BOOLEAN;
memset(&valueA, 0, sizeof(valueA));
/* extract all parameters */
for (;;)
{
#ifndef DISABLE_SHELL
MI_Instance *embeddedShellInstance = NULL;
#endif
if (GetNextSkipCharsAndComments(xml, &e) != 0)
RETURN(-1);
/* Look for closing instance element */
if (e.type == XML_END && Tcscmp(e.data.data, start->data.data) == 0)
{
break;
}
/* skip possible comments */
if (e.type != XML_START)
continue;
/* allocate new instance if needed */
if (!*dynamicInstanceParams)
{
MI_Result r;
TChar* cn = NULL;
// We are trying to parse an Instance, The type of the instance may be specified
// as a attribute Type or it is same as the element name. We'll attempt to get the
// type from attribute ... if not we'll use the element name.
// TODO: At this time we don't have the NS support in the XML parser, so using hardcoded
// 'xsi:type (good for windows client) once we get the NS support this code should be
// updated.
const TChar* typeName = XML_Elem_GetAttr(start, PAL_T('x'), PAL_T("type"));
if(typeName)
{
TChar* typeStart;
cn = Batch_Tcsdup(dynamicBatch, typeName);
if (!cn)
{
trace_BatchTcsDup_Failed();
RETURN(-1);
}
// Trim the _Type from the name.
typeStart = Tcsrchr(cn, '_');
if( typeStart )
{
*typeStart = PAL_T('\0');
/* trim namespace start too */
{
TChar* afterColon;
afterColon = Tcschr(cn, PAL_T(':'));
if (afterColon)
{
afterColon++;
cn = afterColon;
}
}
}
else
{
trace_XsiTypeInvalidValue( cn );
RETURN(-1);
// cn is allocated on the batch, so it will be release along with it anyway
}
}
else
{
cn = Batch_Tcsdup(dynamicBatch, start->data.data);
if (!cn)
{
trace_BatchTcsDup_Failed();
RETURN(-1);
}
}
r = Instance_NewDynamic(
dynamicInstanceParams,
cn,
MI_FLAG_CLASS,
dynamicBatch);
if (MI_RESULT_OK != r)
RETURN(-1);
#ifndef DISABLE_SHELL
if (rqtAction == WSMANTAG_ACTION_SHELL_COMMAND)
{
/* If this is the shell Receive Response then we have optional CommandId attribute that
* needs to be extracted and put in
* the instance
*/
const TChar* commandId = XML_Elem_GetAttr(start, 0, PAL_T("CommandId"));
if (commandId)
{
MI_Value value;
value.string = (TChar*) commandId;
if (__MI_Instance_AddElement(*dynamicInstanceParams, MI_T("CommandId"), &value, MI_STRING, 0) != MI_RESULT_OK)
{
RETURN(-1);
}
}
}
#endif
}
#ifndef DISABLE_SHELL
if (rqtAction == WSMANTAG_ACTION_SHELL_RECEIVE_RESPONSE)
{
MI_Result r;
const TChar *tmpStr;
/* Stream and Command State are both embedded instances that require multiple
* attributes to get extracted
*/
r = Instance_NewDynamic(
&embeddedShellInstance,
e.data.data,
MI_FLAG_CLASS,
dynamicBatch);
if (MI_RESULT_OK != r)
RETURN(-1);
/* Both parameters have optional commandId's */
tmpStr = XML_Elem_GetAttr(&e, 0, PAL_T("CommandId"));
if (tmpStr)
{
MI_Value value;
value.string = (TChar*) tmpStr;
if (__MI_Instance_AddElement(embeddedShellInstance, MI_T("CommandId"), &value, MI_STRING, 0) != MI_RESULT_OK)
{
RETURN(-1);
}
}
if (Tcscmp(e.data.data, MI_T("Stream")) == 0)
{
tmpStr = XML_Elem_GetAttr(&e, 0, PAL_T("Name"));
if (tmpStr)
{
MI_Value value;
value.string = (TChar*) tmpStr;
if (__MI_Instance_AddElement(embeddedShellInstance, MI_T("streamName"), &value, MI_STRING, 0) != MI_RESULT_OK)
{
RETURN(-1);
}
}
tmpStr = XML_Elem_GetAttr(&e, 0, PAL_T("End"));
if (tmpStr && (Tcscmp(tmpStr, MI_T("true")) == 0 || Tcscmp(tmpStr, MI_T("1")) == 0))
{
MI_Value value;
value.boolean = 1;
if (__MI_Instance_AddElement(embeddedShellInstance, MI_T("endOfStream"), &value, MI_BOOLEAN, 0) != MI_RESULT_OK)
{
RETURN(-1);
}
}
}
else if (Tcscmp(e.data.data, MI_T("CommandState")) == 0)
{
tmpStr = XML_Elem_GetAttr(&e, 0, PAL_T("State"));
if (tmpStr)
{
MI_Value value;
value.string = (TChar*) tmpStr;
if (__MI_Instance_AddElement(embeddedShellInstance, MI_T("State"), &value, MI_STRING, 0) != MI_RESULT_OK)
{
RETURN(-1);
}
}
}
}
#endif
/* add next property to the instance */
if (e.data.size > 0) /* element name should have some data in it */
{
MI_Result r;
MI_Value value;
MI_Type type = MI_BOOLEAN;
const TChar* propNameChar;
const TChar* propName;
MI_Boolean null;
propNameChar = e.data.data;
/* Position propName one beyond ':' character */
propName = Batch_Tcsdup(dynamicBatch, propNameChar);
if (!propName)
{
trace_BatchTcsDup_Failed();
RETURN(-1);
}
type = MI_BOOLEAN;
if (_GetSingleProperty(
xml,
&e,
dynamicBatch,
e.data.namespaceId,
propNameChar,
&value,
&type,
&null,
rqtAction) != 0)
{
trace_GetSingleProperty_Failed( tcs(propNameChar) );
RETURN(-1);
}
#ifndef DISABLE_SHELL
if (rqtAction == WSMANTAG_ACTION_SHELL_RECEIVE_RESPONSE)
{
if (Tcscmp(propName, MI_T("Stream")) == 0)
{
/* Add the data into the embedded object */
r = MI_Instance_AddElement(embeddedShellInstance, MI_T("data"), &value, type, MI_FLAG_BORROW);
if (MI_RESULT_OK != r)
RETURN(-1);
}
/* Now make our embedded instance become the real data to add */
value.instance = embeddedShellInstance;
type = MI_INSTANCE;
null = MI_FALSE;
}
#endif
if (null)
{
/* Skip null attributes */
continue;
}
/* Did we collect array's items? */
if (propNameA)
{
/* if we have array and new property matches array - add new item to the array */
if (0 == Tcscmp(propNameA, propName))
{
if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type))
RETURN(-1);
}
else
{
r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA,
typeA, MI_FLAG_BORROW);
if (MI_RESULT_OK != r)
RETURN(-1);
/* Clear array prop name */
propNameA = 0;
propNamePrev = propName;
valuePrev = value;
typePrev = type;
}
}
else if (propNamePrev)
{
/* Check if name is the same and we need to create an array */
if (0 == Tcscmp(propNamePrev, propName))
{
/* create array */
valueA.array.size = 0;
valueA.array.data = 0;
typeA = type | MI_ARRAY_BIT;
propNameA = propName;
if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &valuePrev, typePrev))
RETURN(-1);
if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type))
RETURN(-1);
}
else
{
r = MI_Instance_AddElement(
*dynamicInstanceParams,
propNamePrev,
&valuePrev,
typePrev,
MI_FLAG_BORROW);
/* Note that the MI_RESULT_ALREADY_EXISTS error is okay
* for key properties added when the selector set was
* parsed earlier.
*/
if (r != MI_RESULT_OK && r != MI_RESULT_ALREADY_EXISTS)
{
RETURN(-1);
}
propNamePrev = propName;
valuePrev = value;
typePrev = type;
}
}
else
{
/* collecting first item */
propNamePrev = propName;
valuePrev = value;
typePrev = type;
}
}
}
/* if last property was array - add it */
if (propNameA)
{
MI_Result r;
r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA,
typeA, MI_FLAG_BORROW);
if (MI_RESULT_OK != r)
RETURN(-1);
}
else if (propNamePrev)
{
MI_Result r;
r = MI_Instance_AddElement(*dynamicInstanceParams, propNamePrev, &valuePrev,
typePrev, MI_FLAG_BORROW);
/* Note that the MI_RESULT_ALREADY_EXISTS error is okay
* for key properties added when the selector set was
* parsed earlier.
*/
if (r != MI_RESULT_OK && r != MI_RESULT_ALREADY_EXISTS)
{
RETURN(-1);
}
}
/* check closing tag */
if (Tcscmp(e.data.data, start->data.data) != 0)
RETURN(-1);
return 0;
}