| /* |
| * $id$ |
| * |
| * © Copyright IBM Corp. 2013 |
| * |
| * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE |
| * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE |
| * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT. |
| * |
| * You can obtain a current copy of the Eclipse Public License from |
| * http://www.opensource.org/licenses/eclipse-1.0.php |
| * |
| * Author: Sven Schuetz <sven@de.ibm.com> (created file) |
| * all content by Adrian Schuur |
| * |
| * Description: |
| * |
| * CIM XML parser helper functions |
| * |
| */ |
| |
| #include <string.h> |
| #include <stdlib.h> |
| #include <ctype.h> |
| |
| #include "parserUtil.h" |
| #include "cimXmlParser.h" |
| #include "sfcUtil/utilft.h" |
| |
| static int ct = 0; |
| static int dontLex = 0; |
| |
| extern CMPIConstClass * native_new_CMPIConstClass ( char *cn, CMPIStatus * rc ); |
| extern int addClassProperty( CMPIConstClass * ccls, char * name, |
| CMPIValue * value, CMPIType type, |
| CMPIValueState state); |
| extern CMPIType guessType(char *val); |
| extern int addInstPropertyQualifier( CMPIInstance* ci, char * pname, |
| char *qname, CMPIValue * value, |
| CMPIType type); |
| extern int addClassPropertyQualifier( CMPIConstClass* cc, char * pname, |
| char *qname, CMPIValue * value, |
| CMPIType type); |
| extern int addClassQualifier( CMPIConstClass* cc, char * name, |
| CMPIValue * value, |
| CMPIType type); |
| extern int addClassMethod( CMPIConstClass* cc, char * mname, |
| CMPIValue * value, CMPIType type, |
| CMPIValueState state); |
| extern int addClassMethodQualifier( CMPIConstClass* cc, char * mname, |
| char *qname, CMPIValue * value, |
| CMPIType type); |
| extern int addClassMethodParameter( CMPIConstClass* cc, char * mname, |
| char *pname, |
| CMPIType type); |
| extern char *XmlToAsciiStr(char *XmlStr); |
| |
| #if DEBUG |
| extern int do_debug; |
| #endif |
| |
| static inline int isBoolean(CMPIData data) |
| { |
| if (data.type == CMPI_chars) { |
| if (strcasecmp(data.value.chars,"true") == 0) return 0xffff; |
| if (strcasecmp(data.value.chars,"false") == 0) return 0; |
| } |
| return -1; |
| } |
| |
| void createPath(CMPIObjectPath **op, XtokInstanceName *p) |
| { |
| int i; |
| CMPIValue val,*valp; |
| CMPIType type; |
| XtokKeyBinding *b; |
| |
| *op = newCMPIObjectPath(NULL, p->className, NULL); |
| for (b = p->bindings.first; b; b = b->next) { |
| valp = getKeyValueTypePtr(b->type, |
| b->val.keyValue.value, |
| &b->val.ref, |
| &val, &type); |
| CMAddKey(*op, b->name, valp, type); |
| if (type == CMPI_ref) { |
| CMRelease(valp->ref); |
| } |
| } |
| } |
| |
| void setInstProperties(CMPIInstance *ci, XtokProperties *ps) |
| { |
| XtokProperty *np = NULL,*p = ps ? ps->first : NULL; |
| CMPIValue val; |
| CMPIObjectPath *op; |
| CMPIStatus status; |
| CMPIType type = CMPI_null; |
| XtokQualifier *nq = NULL,*q; |
| XtokQualifiers *qs; |
| int rc, n, setq; |
| |
| while (p) { |
| setq=1; |
| switch (p->propType) { |
| case typeProperty_Value: |
| type = p->valueType; |
| if (p->val.value.data.value != NULL && p->val.null==0) { |
| if (type == CMPI_string || type == CMPI_chars) { |
| char *charsStr = XmlToAsciiStr(p->val.value.data.value); |
| val = str2CMPIValue(type, charsStr, NULL); |
| free (charsStr); |
| } |
| else |
| val = str2CMPIValue(type, p->val.value.data.value, NULL); |
| CMSetProperty(ci, p->name, &val, type); |
| native_release_CMPIValue(type, &val); |
| } |
| else { |
| CMSetProperty(ci, p->name, NULL, type); |
| setq = 0; |
| } |
| break; |
| case typeProperty_Reference: |
| val=str2CMPIValue(CMPI_ref, NULL, &p->val.ref); |
| CMSetProperty(ci, p->name, &val.ref, CMPI_ref); |
| CMRelease(val.ref); |
| break; |
| case typeProperty_Array: |
| type = p->valueType; |
| if (p->val.array.next > 0) { |
| CMPIArray *arr = newCMPIArray(0, type, &status); |
| if (p->val.array.max > 0) { |
| int i; |
| for (i = 0; i < p->val.array.next; ++i) |
| { |
| char *valStr = p->val.array.values[i]; |
| if (type == CMPI_string || type == CMPI_chars) { |
| char *charsStr = XmlToAsciiStr(valStr); |
| val = str2CMPIValue(type, charsStr, NULL); |
| free (charsStr); |
| } |
| else |
| val = str2CMPIValue(type, valStr, NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type, &val); |
| } |
| } |
| val.array = arr; |
| CMSetProperty(ci, p->name, &val, type | CMPI_ARRAY); |
| CMRelease(arr); /* cloned in property */ |
| } |
| else { |
| CMSetProperty(ci, p->name, NULL, p->valueType | CMPI_ARRAY); |
| setq = 0; |
| } |
| break; |
| } |
| |
| if (setq) { |
| qs=&p->val.qualifiers; |
| q=qs ? qs->first : NULL; |
| n=0; |
| while (q) { |
| if (q->type & CMPI_ARRAY) { |
| CMPIArray *arr = NULL; |
| arr = newCMPIArray(0, type, NULL); |
| type = q->type & ~CMPI_ARRAY; |
| int i; |
| if (q->data.array.max) { |
| for (i = 0; i < q->data.array.next; ++i) { |
| val = str2CMPIValue(type, q->data.array.values[i], NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type,&val); |
| } |
| } |
| rc = addInstPropertyQualifier(ci, p->name, q->name, |
| (CMPIValue *)&arr, q->type); |
| native_release_CMPIValue(q->type,(CMPIValue*)&arr); |
| } |
| else { |
| val = str2CMPIValue(q->type, q->data.value.data.value, NULL); |
| rc= addInstPropertyQualifier(ci, p->name, q->name, &val, q->type); |
| native_release_CMPIValue(q->type,&val); |
| } |
| nq = q->next; |
| q = nq; |
| } |
| } |
| |
| np = p->next; |
| p = np; |
| |
| } |
| |
| if (ps) |
| ps->first = ps->last = NULL; |
| } |
| |
| void setInstQualifiers(CMPIInstance *ci, XtokQualifiers *qs) |
| { |
| XtokQualifier *nq = NULL,*q = qs ? qs->first : NULL; |
| CMPIValue val; |
| int rc; |
| |
| while (q) { |
| if (q->type & CMPI_ARRAY) { |
| CMPIType type=q->type&~CMPI_ARRAY; |
| CMPIArray *arr = newCMPIArray(0, type, NULL); |
| int i; |
| if (q->data.array.max) { |
| for (i = 0; i < q->data.array.next; ++i) { |
| val = str2CMPIValue(type, q->data.array.values[i], NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type,&val); |
| } |
| rc = addInstQualifier(ci, q->name, (CMPIValue*)&arr, q->type); |
| native_release_CMPIValue(q->type,(CMPIValue*)&arr); |
| } |
| } |
| else { |
| val = str2CMPIValue(q->type, q->data.value.data.value, NULL); |
| rc = addInstQualifier(ci, q->name, &val, q->type); |
| native_release_CMPIValue( q->type,&val); |
| } |
| nq = q->next; |
| q = nq; |
| } |
| if (qs) { |
| qs->first = qs->last = NULL; |
| } |
| } |
| |
| void setClassMethods(CMPIConstClass *cls, XtokMethods *ms) |
| { |
| XtokMethod *nm = NULL,*m = ms ? ms->first : NULL; |
| CMPIValue val; |
| CMPIArray *arr = NULL; |
| XtokQualifier *nq,*q; |
| XtokQualifiers *qs; |
| XtokParam *np,*p; |
| XtokParams *ps; |
| int rc, n; |
| |
| val.uint64=0l; |
| while (m) { |
| addClassMethod(cls, m->name, &val, m->type, CMPI_nullValue); |
| |
| qs=&m->qualifiers; |
| q=qs ? qs->first : NULL; |
| n=0; |
| while (q) { |
| if (q->type & CMPI_ARRAY) { |
| CMPIType type=q->type&~CMPI_ARRAY; |
| arr = newCMPIArray(0, type, NULL); |
| int i; |
| if (q->data.array.max) { |
| for (i = 0; i < q->data.array.next; ++i) { |
| val = str2CMPIValue(type, q->data.array.values[i], NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type,&val); |
| } |
| } |
| val.array = arr; |
| rc = addClassMethodQualifier(cls, m->name, q->name, &val, q->type); |
| native_release_CMPIValue(q->type,(CMPIValue*)&arr); |
| } |
| else { |
| val = str2CMPIValue(q->type, q->data.value.data.value, NULL); |
| rc= addClassMethodQualifier(cls, m->name, q->name, &val, q->type); |
| native_release_CMPIValue(q->type,&val); |
| } |
| nq = q->next; |
| q = nq; |
| } |
| |
| ps=&m->params; |
| p=ps ? ps->first : NULL; |
| n=0; |
| while (p) { |
| rc= addClassMethodParameter(cls, m->name, p->name, p->type); |
| np = p->next; |
| p = np; |
| } |
| |
| nm = m->next; |
| m = nm; |
| } |
| if (ms) ms->first = ms->last = NULL; |
| } |
| |
| void setClassProperties(CMPIConstClass *cls, XtokProperties *ps) |
| { |
| XtokProperty *np = NULL,*p = ps ? ps->first : NULL; |
| CMPIValue val; |
| CMPIArray *arr = NULL; |
| XtokQualifier *nq,*q; |
| XtokQualifiers *qs; |
| int rc, n; |
| |
| val.uint64=0l; |
| while (p) { |
| switch (p->propType) { |
| case typeProperty_Value: |
| addClassProperty(cls, p->name, &val, p->valueType, CMPI_nullValue); |
| break; |
| case typeProperty_Reference: |
| addClassProperty(cls, p->name, &val, CMPI_ref, CMPI_nullValue); |
| break; |
| case typeProperty_Array: |
| val.array = arr; |
| addClassProperty(cls, p->name, &val, |
| p->valueType | CMPI_ARRAY, CMPI_nullValue); |
| break; |
| } |
| |
| qs=&p->val.qualifiers; |
| q=qs ? qs->first : NULL; |
| n=0; |
| while (q) { |
| if (q->type & CMPI_ARRAY) { |
| CMPIType type=q->type&~CMPI_ARRAY; |
| arr = newCMPIArray(0, type, NULL); |
| int i; |
| if (q->data.array.max) { |
| for (i = 0; i < q->data.array.next; ++i) { |
| val = str2CMPIValue(type, q->data.array.values[i], NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type,&val); |
| } |
| } |
| val.array = arr; |
| rc = addClassPropertyQualifier(cls, p->name, q->name, &val, q->type); |
| native_release_CMPIValue(q->type,(CMPIValue*)&arr); |
| } |
| else { |
| val = str2CMPIValue(q->type, q->data.value.data.value, NULL); |
| rc= addClassPropertyQualifier(cls, p->name, q->name, &val, q->type); |
| native_release_CMPIValue(q->type,&val); |
| } |
| nq = q->next; |
| q = nq; |
| } |
| |
| np = p->next; |
| p = np; |
| } |
| if (ps) ps->first = ps->last = NULL; |
| } |
| |
| void setClassQualifiers(CMPIConstClass *cls, XtokQualifiers *qs) |
| { |
| XtokQualifier *nq = NULL,*q = qs ? qs->first : NULL; |
| CMPIValue val; |
| int rc; |
| |
| while (q) { |
| if (q->type & CMPI_ARRAY) { |
| CMPIType type=q->type&~CMPI_ARRAY; |
| CMPIArray *arr = newCMPIArray(0, type, NULL); |
| int i; |
| if (q->data.array.max > 0) { |
| for (i = 0; i < q->data.array.next; ++i) { |
| char *valStr = q->data.array.values[i]; |
| if (type == CMPI_string || type == CMPI_chars) |
| { |
| char *charsStr = XmlToAsciiStr(valStr); |
| val = str2CMPIValue(type, charsStr, NULL); |
| free (charsStr); |
| } |
| else |
| val = str2CMPIValue(type, valStr, NULL); |
| CMSetArrayElementAt(arr, i, &val, type); |
| native_release_CMPIValue(type,&val); |
| } |
| rc = addClassQualifier(cls, q->name, (CMPIValue*)&arr, q->type); |
| native_release_CMPIValue(q->type,(CMPIValue*)&arr); |
| } |
| } |
| else { |
| char *valStr = q->data.value.data.value; |
| if (q->type == CMPI_string || q->type == CMPI_chars) |
| { |
| char *charsStr = XmlToAsciiStr(valStr); |
| val = str2CMPIValue(q->type, charsStr, NULL); |
| free (charsStr); |
| } |
| else |
| val = str2CMPIValue(q->type, valStr, NULL); |
| rc = addClassQualifier(cls, q->name, &val, q->type); |
| native_release_CMPIValue( q->type,&val); |
| } |
| nq = q->next; |
| q = nq; |
| } |
| if (qs) { |
| qs->first = qs->last = NULL; |
| } |
| } |
| |
| |
| void addProperty(ParserControl *parm, XtokProperties *ps, XtokProperty *p) |
| { |
| XtokProperty *np; |
| np = (XtokProperty*)PARSER_MALLOC(sizeof(XtokProperty)); |
| memcpy(np, p, sizeof(XtokProperty)); |
| np->next = NULL; |
| if (ps->last) ps->last->next = np; |
| else ps->first = np; |
| ps->last = np; |
| } |
| |
| void addParamValue(ParserControl *parm, XtokParamValues *vs, XtokParamValue *v) |
| { |
| XtokParamValue *nv; |
| nv = (XtokParamValue*)PARSER_MALLOC(sizeof(XtokParamValue)); |
| memcpy(nv, v, sizeof(XtokParamValue)); |
| nv->next = NULL; |
| if (vs->last) |
| vs->last->next = nv; |
| else |
| vs->first = nv; |
| vs->last = nv; |
| } |
| |
| void addKeyBinding(ParserControl *parm, XtokKeyBindings *ks, XtokKeyBinding *k) |
| { |
| XtokKeyBinding *nk; |
| nk = (XtokKeyBinding*)PARSER_MALLOC(sizeof(XtokKeyBinding)); |
| memcpy(nk, k, sizeof(XtokKeyBinding)); |
| nk->next = NULL; |
| if (ks->last) ks->last->next = nk; |
| else ks->first = nk; |
| ks->last = nk; |
| } |
| |
| void addQualifier(ParserControl *parm, XtokQualifiers *qs, XtokQualifier *q) |
| { |
| XtokQualifier *nq; |
| nq = (XtokQualifier*)PARSER_MALLOC(sizeof(XtokQualifier)); |
| memcpy(nq, q, sizeof(XtokQualifier)); |
| nq->next = NULL; |
| if (qs->last) qs->last->next = nq; |
| else qs->first = nq; |
| qs->last = nq; |
| } |
| |
| void addMethod(ParserControl *parm, XtokMethods *ms, XtokMethod *m) |
| { |
| XtokMethod *nm; |
| nm = (XtokMethod*)PARSER_MALLOC(sizeof(XtokMethod)); |
| memcpy(nm, m, sizeof(XtokMethod)); |
| nm->next = NULL; |
| if (ms->last) |
| ms->last->next = nm; |
| else |
| ms->first = nm; |
| ms->last = nm; |
| } |
| |
| void addParam(ParserControl *parm, XtokParams *ps, XtokParam *p) |
| { |
| XtokParam *np; |
| np = (XtokParam*)PARSER_MALLOC(sizeof(XtokParam)); |
| memcpy(np, p, sizeof(XtokParam)); |
| np->next = NULL; |
| if (ps->last) |
| ps->last->next = np; |
| else |
| ps->first = np; |
| ps->last = np; |
| } |
| |
| void setError(ParserControl *parm, XtokErrorResp *e) |
| { |
| #if DEBUG |
| if (do_debug) |
| fprintf(stderr, "error:: code:%s description:%s\n", |
| e->code, e->description); |
| #endif |
| parm->respHdr.errCode = atoi(e->code); |
| parm->respHdr.description = XmlToAsciiStr(e->description); |
| } |
| |
| void setReturnArgs(ParserControl *parm, XtokParamValues *ps) |
| { |
| CMPIValue value; |
| XtokParamValue *outParam=NULL; |
| CMPIArgs *args = NULL; |
| |
| /* Process OUT parameters */ |
| outParam = ps->first; |
| |
| if (outParam) { |
| args = newCMPIArgs(NULL); |
| |
| while (outParam) { |
| value = str2CMPIValue(outParam->type, outParam->data.value.data.value, &outParam->data.valueRef); |
| |
| /* Add it to the args list */ |
| args->ft->addArg ( args, outParam->name, &value, outParam->type); |
| native_release_CMPIValue(outParam->type,&value); |
| outParam = outParam->next; |
| } |
| parm->respHdr.outArgs = args; |
| /* Note : Freeing of list will be done by |
| * parser_heap_term() routine. |
| */ |
| } |
| } |