📄 xmlrpc.c
字号:
/****f* VALUE/XMLRPC_GetValueBase64 * NAME * XMLRPC_GetValueBase64 * SYNOPSIS * const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value) * FUNCTION * retrieve binary value * INPUTS * XMLRPC_VALUE of type xmlrpc_base64 * RESULT * pointer to binary value or 0 if value is not valid. * SEE ALSO * XMLRPC_SetValueBase64 () * XMLRPC_CreateValueBase64 () * NOTES * Call XMLRPC_GetValueStringLen() to retrieve real length of binary data. strlen() * will not be accurate, as returned data may contain embedded nulls. * SOURCE */const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value) { return ((value && value->type == xmlrpc_base64) ? value->str.str : 0);}/*******//****f* VALUE/XMLRPC_GetValueDateTime * NAME * XMLRPC_GetValueDateTime * SYNOPSIS * time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value) * FUNCTION * retrieve time_t value * INPUTS * XMLRPC_VALUE of type xmlrpc_datetime * RESULT * time_t value or 0 if value is not valid datetime. * NOTES * use XMLRPC_GetValueType() to be sure if 0 is real value or not * SEE ALSO * XMLRPC_SetValueDateTime () * XMLRPC_GetValueDateTime_ISO8601 () * XMLRPC_CreateValueDateTime () * SOURCE */time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value) { return (time_t)((value && value->type == xmlrpc_datetime) ? value->i : 0);}/*******//****f* VALUE/XMLRPC_GetValueDateTime_IOS8601 * NAME * XMLRPC_GetValueDateTime_IOS8601 * SYNOPSIS * const char* XMLRPC_GetValueDateTime_IOS8601(XMLRPC_VALUE value) * FUNCTION * retrieve ISO8601 formatted time value * INPUTS * XMLRPC_VALUE of type xmlrpc_datetime * RESULT * const char* value or 0 if value is not valid datetime. * SEE ALSO * XMLRPC_SetValueDateTime_IOS8601 () * XMLRPC_GetValueDateTime () * XMLRPC_CreateValueDateTime_IOS8601 () * SOURCE */const char* XMLRPC_GetValueDateTime_ISO8601(XMLRPC_VALUE value) { return ((value && value->type == xmlrpc_datetime) ? value->str.str : 0);}/*******//* Get ID (key) of value or NULL *//****f* VALUE/XMLRPC_GetValueID * NAME * XMLRPC_GetValueID * SYNOPSIS * const char* XMLRPC_GetValueID(XMLRPC_VALUE value) * FUNCTION * retrieve id (key) of value * INPUTS * XMLRPC_VALUE of any type * RESULT * const char* pointer to id of value, or NULL * NOTES * SEE ALSO * XMLRPC_SetValueID() * XMLRPC_CreateValueEmpty() * SOURCE */const char* XMLRPC_GetValueID(XMLRPC_VALUE value) { return (const char*)((value && value->id.len) ? value->id.str : 0);}/*******//****f* VECTOR/XMLRPC_VectorSize * NAME * XMLRPC_VectorSize * SYNOPSIS * int XMLRPC_VectorSize(XMLRPC_VALUE value) * FUNCTION * retrieve size of vector * INPUTS * XMLRPC_VALUE of type xmlrpc_vector * RESULT * count of items in vector * NOTES * This is a cheap operation even on large vectors. Vector size is * maintained by queue during add/remove ops. * SEE ALSO * XMLRPC_AddValueToVector () * SOURCE */int XMLRPC_VectorSize(XMLRPC_VALUE value) { int size = 0; if(value && value->type == xmlrpc_vector && value->v) { size = Q_Size(value->v->q); } return size;}/*******//****f* VECTOR/XMLRPC_VectorRewind * NAME * XMLRPC_VectorRewind * SYNOPSIS * XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value) * FUNCTION * reset vector to first item * INPUTS * XMLRPC_VALUE of type xmlrpc_vector * RESULT * first XMLRPC_VALUE in list, or NULL if empty or error. * NOTES * Be careful to rewind any vector passed in to you if you expect to * iterate through the entire list. * SEE ALSO * XMLRPC_VectorNext () * SOURCE */XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value) { XMLRPC_VALUE xReturn = NULL; if(value && value->type == xmlrpc_vector && value->v) { xReturn = (XMLRPC_VALUE)Q_Head(value->v->q); } return xReturn;}/*******//****f* VECTOR/XMLRPC_VectorNext * NAME * XMLRPC_VectorNext * SYNOPSIS * XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value) * FUNCTION * Iterate vector to next item in list. * INPUTS * XMLRPC_VALUE of type xmlrpc_vector * RESULT * Next XMLRPC_VALUE in vector, or NULL if at end. * NOTES * SEE ALSO * XMLRPC_VectorRewind () * SOURCE */XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value) { XMLRPC_VALUE xReturn = NULL; if(value && value->type == xmlrpc_vector && value->v) { xReturn = (XMLRPC_VALUE)Q_Next(value->v->q); } return xReturn;}/*******//****f* VALUE/XMLRPC_GetValueType * NAME * XMLRPC_GetValueType * SYNOPSIS * XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value) * FUNCTION * determine data type of the XMLRPC_VALUE * INPUTS * XMLRPC_VALUE target of query * RESULT * data type of value as enumerated by XMLRPC_VALUE_TYPE * NOTES * all values are of type xmlrpc_empty until set. * Deprecated for public use. See XMLRPC_GetValueTypeEasy * SEE ALSO * XMLRPC_SetValue* * XMLRPC_CreateValue* * XMLRPC_Append* * XMLRPC_GetValueTypeEasy () * SOURCE */XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value) { return value ? value->type : xmlrpc_empty;}/*******//* Vector type accessor *//****f* VALUE/XMLRPC_GetVectorType * NAME * XMLRPC_GetVectorType * SYNOPSIS * XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value) * FUNCTION * determine vector type of the XMLRPC_VALUE * INPUTS * XMLRPC_VALUE of type xmlrpc_vector * RESULT * vector type of value as enumerated by XMLRPC_VECTOR_TYPE. * xmlrpc_none if not a value. * NOTES * xmlrpc_none is returned if value is not a vector * Deprecated for public use. See XMLRPC_GetValueTypeEasy * SEE ALSO * XMLRPC_SetIsVector () * XMLRPC_GetValueType () * XMLRPC_GetValueTypeEasy () * SOURCE */XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value) { return(value && value->v) ? value->v->type : xmlrpc_none;}/*******//****f* VALUE/XMLRPC_GetValueTypeEasy * NAME * XMLRPC_GetValueTypeEasy * SYNOPSIS * XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy(XMLRPC_VALUE value) * FUNCTION * determine data type of the XMLRPC_VALUE. includes vector types. * INPUTS * XMLRPC_VALUE target of query * RESULT * data type of value as enumerated by XMLRPC_VALUE_TYPE_EASY * xmlrpc_type_none if not a value. * NOTES * all values are of type xmlrpc_type_empty until set. * SEE ALSO * XMLRPC_SetValue* * XMLRPC_CreateValue* * XMLRPC_Append* * SOURCE */XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy (XMLRPC_VALUE value) { if (value) { switch (value->type) { case xmlrpc_vector: switch (value->v->type) { case xmlrpc_vector_none: return xmlrpc_type_none; case xmlrpc_vector_struct: return xmlrpc_type_struct; case xmlrpc_vector_mixed: return xmlrpc_type_mixed; case xmlrpc_vector_array: return xmlrpc_type_array; } default: /* evil cast, but we know they are the same */ return(XMLRPC_VALUE_TYPE_EASY) value->type; } } return xmlrpc_none;}/*******//*-******************** Begin Server Funcs **********************//****f* VALUE/XMLRPC_ServerCreate * NAME * XMLRPC_ServerCreate * SYNOPSIS * XMLRPC_SERVER XMLRPC_ServerCreate() * FUNCTION * Allocate/Init XMLRPC Server Resources. * INPUTS * none * RESULT * newly allocated XMLRPC_SERVER * NOTES * SEE ALSO * XMLRPC_ServerDestroy () * XMLRPC_GetGlobalServer () * SOURCE */XMLRPC_SERVER XMLRPC_ServerCreate() { XMLRPC_SERVER server = calloc(1, sizeof(STRUCT_XMLRPC_SERVER)); if(server) { Q_Init(&server->methodlist); Q_Init(&server->docslist); /* register system methods */ xsm_register(server); } return server;}/*******//* Return global server. Not locking! Not Thread Safe! *//****f* VALUE/XMLRPC_GetGlobalServer * NAME * XMLRPC_GetGlobalServer * SYNOPSIS * XMLRPC_SERVER XMLRPC_GetGlobalServer() * FUNCTION * Allocates a global (process-wide) server, or returns pointer if pre-existing. * INPUTS * none * RESULT * pointer to global server, or 0 if error. * NOTES * ***WARNING*** This function is not thread safe. It is included only for the very lazy. * Multi-threaded programs that use this may experience problems. * BUGS * There is currently no way to cleanup the global server gracefully. * SEE ALSO * XMLRPC_ServerCreate () * SOURCE */XMLRPC_SERVER XMLRPC_GetGlobalServer() { static XMLRPC_SERVER xsServer = 0; if(!xsServer) { xsServer = XMLRPC_ServerCreate(); } return xsServer;}/*******//****f* VALUE/XMLRPC_ServerDestroy * NAME * XMLRPC_ServerDestroy * SYNOPSIS * void XMLRPC_ServerDestroy(XMLRPC_SERVER server) * FUNCTION * Free Server Resources * INPUTS * server The server to be free'd * RESULT * void * NOTES * This frees the server struct and any methods that have been added. * SEE ALSO * XMLRPC_ServerCreate () * SOURCE */void XMLRPC_ServerDestroy(XMLRPC_SERVER server) { if(server) { doc_method* dm = Q_Head(&server->docslist); server_method* sm = Q_Head(&server->methodlist); while( dm ) { my_free(dm); dm = Q_Next(&server->docslist); } while( sm ) { if(sm->name) { my_free(sm->name); } if(sm->desc) { XMLRPC_CleanupValue(sm->desc); } my_free(sm); sm = Q_Next(&server->methodlist); } if(server->xIntrospection) { XMLRPC_CleanupValue(server->xIntrospection); } Q_Destroy(&server->methodlist); Q_Destroy(&server->docslist); my_free(server); }}/*******//****f* VALUE/XMLRPC_ServerRegisterMethod * NAME * XMLRPC_ServerRegisterMethod * SYNOPSIS * void XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) * FUNCTION * Register new XMLRPC method with server * INPUTS * server The XMLRPC_SERVER to register the method with * name public name of the method * cb C function that implements the method * RESULT * int - 1 if success, else 0 * NOTES * A C function must be registered for every "method" that the server recognizes. The * method name is equivalent to <methodCall><name> method name </name></methodCall> in the * XML syntax. * SEE ALSO * XMLRPC_ServerFindMethod () * XMLRPC_ServerCallMethod () * SOURCE */int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) { if(server && name && cb) { server_method* sm = malloc(sizeof(server_method)); if(sm) { sm->name = strdup(name); sm->method = cb; sm->desc = NULL; return Q_PushTail(&server->methodlist, sm); } } return 0;}/*******/server_method* find_method(XMLRPC_SERVER server, const char* name) { server_method* sm; q_iter qi = Q_Iter_Head_F(&server->methodlist); while( qi ) { sm = Q_Iter_Get_F(qi); if(sm && !strcmp(sm->name, name)) { return sm; } qi = Q_Iter_Next_F(qi); } return NULL;}const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype) { switch(type) { case xmlrpc_none: return "none"; case xmlrpc_empty: return "empty"; case xmlrpc_base64: return "base64"; case xmlrpc_boolean: return "boolean"; case xmlrpc_datetime: return "datetime"; case xmlrpc_double: return "double"; case xmlrpc_int: return "int"; case xmlrpc_string: return "string"; case xmlrpc_vector: switch(vtype) { case xmlrpc_vector_none: return "none"; case xmlrpc_vector_array: return "array"; case xmlrpc_vector_mixed: return "mixed vector (struct)"; case xmlrpc_vector_struct: return "struct"; } } return "unknown";}/****f* VALUE/XMLRPC_ServerFindMethod * NAME * XMLRPC_ServerFindMethod * SYNOPSIS * XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -