📄 xmlrpc.c
字号:
* RESULT * int 1 if successful, 0 otherwise * SEE ALSO * XMLRPC_GetValueType () * XMLRPC_GetVectorType () * XMLRPC_VALUE * XMLRPC_VECTOR_TYPE * XMLRPC_VALUE_TYPE * SOURCE */int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type) { int bSuccess = 0; if (value) { /* we can change the type so long as nothing is currently stored. */ if(value->type == xmlrpc_vector) { if(value->v) { if(!Q_Size(value->v->q)) { value->v->type = type; } } } else { value->v = calloc(1, sizeof(STRUCT_XMLRPC_VECTOR)); if(value->v) { value->v->q = (queue*)malloc(sizeof(queue)); if(value->v->q) { Q_Init(value->v->q); value->v->type = type; value->type = xmlrpc_vector; bSuccess = 1; } } } } return bSuccess;}/*******//****f* VECTOR/XMLRPC_CreateVector * NAME * XMLRPC_CreateVector * SYNOPSIS * XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type) * FUNCTION * Create a new vector and optionally set an id. * INPUTS * id The id of the vector, or NULL * type New type of vector as enumerated by XMLRPC_VECTOR_TYPE * RESULT * XMLRPC_VALUE The new vector, or NULL on failure. * SEE ALSO * XMLRPC_CreateValueEmpty () * XMLRPC_SetIsVector () * XMLRPC_GetValueType () * XMLRPC_GetVectorType () * XMLRPC_VALUE * XMLRPC_VECTOR_TYPE * XMLRPC_VALUE_TYPE * SOURCE */XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type) { XMLRPC_VALUE val = NULL; val = XMLRPC_CreateValueEmpty(); if(val) { if(XMLRPC_SetIsVector(val, type)) { if(id) { const char *pSVI = NULL; pSVI = XMLRPC_SetValueID(val, id, 0); if(NULL == pSVI) { val = NULL; } } } else { val = NULL; } } return val;}/*******//* Not yet implemented. * * This should use a hash to determine if a given target id has already * been appended. * * Alternately, it could walk the entire vector, but that could be quite * slow for very large lists. */static int isDuplicateEntry(XMLRPC_VALUE target, XMLRPC_VALUE source) { return 0;}/****f* VECTOR/XMLRPC_AddValueToVector * NAME * XMLRPC_AddValueToVector * SYNOPSIS * int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source) * FUNCTION * Add (append) an existing XMLRPC_VALUE to a vector. * INPUTS * target The target vector * source The source value to append * RESULT * int 1 if successful, else 0 * SEE ALSO * XMLRPC_AddValuesToVector () * XMLRPC_VectorGetValueWithID_Case () * XMLRPC_VALUE * NOTES * The function will fail and return 0 if an attempt is made to add * a value with an ID into a vector of type xmlrpc_vector_array. Such * values can only be added to xmlrpc_vector_struct. * SOURCE */int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source) { if(target && source) { if(target->type == xmlrpc_vector && target->v && target->v->q && target->v->type != xmlrpc_vector_none) { /* guard against putting value of unknown type into vector */ switch(source->type) { case xmlrpc_empty: case xmlrpc_base64: case xmlrpc_boolean: case xmlrpc_datetime: case xmlrpc_double: case xmlrpc_int: case xmlrpc_string: case xmlrpc_vector: /* Guard against putting a key/val pair into an array vector */ if( !(source->id.len && target->v->type == xmlrpc_vector_array) ) { if (isDuplicateEntry (target, source) || Q_PushTail (target->v->q, XMLRPC_CopyValue (source))) { return 1; } } else { fprintf (stderr, "xmlrpc: attempted to add key/val pair to vector of type array\n"); } break; default: fprintf (stderr, "xmlrpc: attempted to add value of unknown type to vector\n"); break; } } } return 0;}/*******//****f* VECTOR/XMLRPC_AddValuesToVector * NAME * XMLRPC_AddValuesToVector * SYNOPSIS * XMLRPC_AddValuesToVector ( target, val1, val2, val3, val(n), 0 ) * XMLRPC_AddValuesToVector( XMLRPC_VALUE, ... ) * FUNCTION * Add (append) a series of existing XMLRPC_VALUE to a vector. * INPUTS * target The target vector * ... The source value(s) to append. The last item *must* be 0. * RESULT * int 1 if successful, else 0 * SEE ALSO * XMLRPC_AddValuesToVector () * XMLRPC_VectorGetValueWithID_Case () * XMLRPC_VALUE * NOTES * This function may actually return failure after it has already modified * or added items to target. You can not trust the state of target * if this function returns failure. * SOURCE */int XMLRPC_AddValuesToVector(XMLRPC_VALUE target, ...) { int iRetval = 0; if(target) { if(target->type == xmlrpc_vector) { XMLRPC_VALUE v = NULL; va_list vl; va_start(vl, target); do { v = va_arg(vl, XMLRPC_VALUE); if(v) { if(!XMLRPC_AddValueToVector(target, v)) { iRetval = 0; break; } } } while (v); va_end(vl); if(NULL == v) { iRetval = 1; } } } return iRetval;}/*******//****f* VECTOR/XMLRPC_VectorGetValueWithID_Case * NAME * XMLRPC_VectorGetValueWithID_Case * SYNOPSIS * XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case(XMLRPC_VALUE vector, const char* id, XMLRPC_CASE_COMPARISON id_case) * FUNCTION * Get value from vector matching id (key) * INPUTS * vector The source vector * id The key to find * id_case Rule for how to match key * RESULT * int 1 if successful, else 0 * SEE ALSO * XMLRPC_SetValueID_Case () * XMLRPC_VALUE * XMLRPC_CASE_COMPARISON * SOURCE */XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case (XMLRPC_VALUE vector, const char *id, XMLRPC_CASE_COMPARISON id_case) { if(vector && vector->v && vector->v->q) { q_iter qi = Q_Iter_Head_F(vector->v->q); while(qi) { XMLRPC_VALUE xIter = Q_Iter_Get_F(qi); if(xIter && xIter->id.str) { if(id_case == xmlrpc_case_sensitive) { if(!strcmp(xIter->id.str, id)) { return xIter; } } else if(id_case == xmlrpc_case_insensitive) { if(!strcasecmp(xIter->id.str, id)) { return xIter; } } } qi = Q_Iter_Next_F(qi); } } return NULL;}/*******/int XMLRPC_VectorRemoveValue(XMLRPC_VALUE vector, XMLRPC_VALUE value) { if(vector && vector->v && vector->v->q && value) { q_iter qi = Q_Iter_Head_F(vector->v->q); while(qi) { XMLRPC_VALUE xIter = Q_Iter_Get_F(qi); if(xIter == value) { XMLRPC_CleanupValue(xIter); Q_Iter_Del(vector->v->q, qi); return 1; } qi = Q_Iter_Next_F(qi); } } return 0;}/****f* VALUE/XMLRPC_CreateValueString * NAME * XMLRPC_CreateValueString * SYNOPSIS * XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len) * FUNCTION * Create an XMLRPC_VALUE, and assign a string to it * INPUTS * id The id of the value, or NULL * val The desired new string val. * len length of val string if known, or 0 if unknown. * RESULT * newly allocated XMLRPC_VALUE, or NULL * SEE ALSO * XMLRPC_GetValueString () * XMLRPC_CreateValueEmpty () * XMLRPC_VALUE * XMLRPC_VALUE_TYPE * SOURCE */XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len) { XMLRPC_VALUE value = NULL; if(val) { value = XMLRPC_CreateValueEmpty(); if(value) { XMLRPC_SetValueString(value, val, len); if(id) { XMLRPC_SetValueID(value, id, 0); } } } return value;}/*******//****f* VALUE/XMLRPC_CreateValueInt * NAME * XMLRPC_CreateValueInt * SYNOPSIS * XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i) * FUNCTION * Create an XMLRPC_VALUE, and assign an int to it * INPUTS * id The id of the value, or NULL * i The desired new int val. * RESULT * newly allocated XMLRPC_VALUE, or NULL * SEE ALSO * XMLRPC_GetValueInt () * XMLRPC_CreateValueEmpty () * XMLRPC_VALUE * XMLRPC_VALUE_TYPE * SOURCE */XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i) { XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); if(val) { XMLRPC_SetValueInt(val, i); if(id) { XMLRPC_SetValueID(val, id, 0); } } return val;}/*******//****f* VALUE/XMLRPC_CreateValueBoolean * NAME * XMLRPC_CreateValueBoolean * SYNOPSIS * XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i) * FUNCTION * Create an XMLRPC_VALUE, and assign an int to it * INPUTS * id The id of the value, or NULL * i The desired new int val. * RESULT * newly allocated XMLRPC_VALUE, or NULL * SEE ALSO * XMLRPC_GetValueBoolean () * XMLRPC_CreateValueEmpty () * XMLRPC_VALUE * XMLRPC_VALUE_TYPE * SOURCE */XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i) { XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); if(val) { XMLRPC_SetValueBoolean(val, i); if(id) { XMLRPC_SetValueID(val, id, 0); } } return val;}/*******//****f* VALUE/XMLRPC_CleanupValue * NAME * XMLRPC_CleanupValue * SYNOPSIS * void XMLRPC_CleanupValue(XMLRPC_VALUE value) * FUNCTION * Frees all memory allocated for an XMLRPC_VALUE and any of its children (if a vector) * INPUTS * value The id of the value to be cleaned up. * RESULT * void * NOTES * Normally this function will be called for the topmost vector, thus free-ing * all children. If a child of a vector is free'd first, results are undefined. * Failure to call this function *will* cause memory leaks. * * Also, this function is implemented using reference counting. Thus a value * may be added and freed from multiple parents so long as a reference is added * first using XMLRPC_CopyValue() * SEE ALSO * XMLRPC_RequestFree () * XMLRPC_CreateValueEmpty () * XMLRPC_CopyValue() * XMLRPC_VALUE * SOURCE */void XMLRPC_CleanupValue(XMLRPC_VALUE value) { if(value) { if(value->iRefCount > 0) { value->iRefCount --; }#ifdef XMLRPC_DEBUG_REFCOUNT if(value->id.str) { printf ("decremented refcount of %s, now %i\n", value->id.str, value->iRefCount); } else { printf ("decremented refcount of 0x%x, now %i\n", value, value->iRefCount); }#endif if(value->type == xmlrpc_vector) { if(value->v) { if(value->iRefCount == 0) { XMLRPC_VALUE cur = (XMLRPC_VALUE)Q_Head(value->v->q); while( cur ) { XMLRPC_CleanupValue(cur); /* Make sure some idiot didn't include a vector as a child of itself * and thus it would have already free'd these. */ if(value->v && value->v->q) { cur = Q_Next(value->v->q); } else { break; } } Q_Destroy(value->v->q); my_free(value->v->q); my_free(value->v); } } } if(value->iRefCount == 0) { /* guard against freeing invalid types */ switch(value->type) { case xmlrpc_empty: case xmlrpc_base64: case xmlrpc_boolean: case xmlrpc_datetime: case xmlrpc_double: case xmlrpc_int: case xmlrpc_string: case xmlrpc_vector:#ifdef XMLRPC_DEBUG_REFCOUNT if(value->id.str) { printf("free'd %s\n", value->id.str); } else { printf("free'd 0x%x\n", value); }#endif simplestring_free(&value->id); simplestring_free(&value->str); memset(value, 0, sizeof(STRUCT_XMLRPC_VALUE)); my_free(value); break; default: fprintf (stderr, "xmlrpc: attempted to free value of invalid type\n"); break; } } }}/*******//****f* VALUE/XMLRPC_SetValueDateTime
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -