aboutsummaryrefslogtreecommitdiff
path: root/vendor/voclient/libsamp/libxrpc/xrValues.c
blob: 72c4935f14a22638a97cecec56c6d79c99389590 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/**
 *  XRVALUES.C
 *
 *  Methods to handle XML-RPC values.
 *
 *                 xr_initValues  ()
 *               v = xr_newValue  (int type, void *v)
 *               v = xr_tmpValue  (int type, void *v)
 *                  xr_freeValue  (int index)
 *
 *        snum = xr_appendStruct  (int snum, char *key, int value)
 *         anum = xr_appendArray  (int anum, char *key, int value)
 *
 *             xr_getStructValue  (int snum, char *key, void *value)
 *              xr_getArrayValue  (int anum, int index, void *value)
 *
 *
 *  @brief      Methods to handle XML-RPC values.
 *
 *  @file       xrValues.c
 *  @author     Mike Fitzpatrick
 *  @date       6/10/09
 */


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h>

#include "xrpcP.h"



#define MAX_XVALUES	128

#define V_FIRST		5
#define V_LAST		MAX_XVALUES

#define V_TMPVAL	0			/* temp value		*/
#define V_CPARAM	1			/* client-side params	*/
#define V_CRESULT	2			/* client-side results	*/
#define V_MPARAM	3			/* method-side params	*/
#define V_MRESULT	4			/* method-side results	*/


typedef struct {
    xmlrpc_value  *val;                         /* xmlrpc value         */
    int    in_use;

} XValue, *XValueP;


int     nx_values       = -1;
XValue  xValues[MAX_XVALUES];

xmlrpc_env env;                                 /* local env            */


static  xmlrpc_value *xr_gval (int type, void *value);
static  int xr_sval (int type, xmlrpc_value *v, void *uval);





/* XR_INTIVALUES -- Globally initialize the XValues array.
*/
void
xr_initValues ()
{
    memset (&xValues[0], 0, MAX_XVALUES * sizeof(XValue) );
    nx_values = -1;
}


/* XR_NEWVALUE -- 'Allocate' a new dynamic value to be used.
*/
int
xr_newValue (int type, void *v)
{
    int    i;
    int    *iv  = (int *) v;
    double *dv  = (double *) v;
    const char   *str = (const char *) v;
    XValue *xv;


    if (nx_values < 0)           /* initialize the value array */
        memset (&xValues[0], 0, MAX_XVALUES * sizeof(XValue) );

    nx_values++;
    for (i=V_FIRST; i < V_LAST; i++) {
        xv = &xValues[i];
        if (! xv->in_use) {

    	    if ( (xv->val = xr_gval (type, v)) ) {
        	xv->in_use = TRUE;
        	return (i); 
	    } else
		break;
        }
    }

    return (-1);

}


/*  XR_TMPVAL -- Return a temp xmlrc_value.  This is distinguished from other
**  XValues by the fact that this is a static value that might be overwritten
**  by some later call.  This will always be the xmlrpc_value in the zero
**  position of the XValues array, any procedure that requests a new value
**  on this XValue position will destroy the value before a new one is
**  allocated.
*/
int
xr_tmpValue (int type, void *v)
{
    int    i;
    int    *iv  = (int *) v;
    double *dv  = (double *) v;
    const char   *str = (const char *) v;
    XValue *xv;

    xv = &xValues[V_TMPVAL];

    if (! xv->in_use) 
	xmlrpc_DECREF(xv->val);

    if ( (xv->val = xr_gval (type, v)) ) {
        xv->in_use = TRUE;
        return (V_TMPVAL); 
    } else
	return (-1);

}



/* XR_FREEVALUE -- 'Deallocate' a new value in use.
*/
void
xr_freeValue (int index)
{
    XValue *xv = &xValues[index];
            
    if (xv->in_use) {
        xmlrpc_DECREF (xv->val);
        memset (&xValues[index], 0, sizeof(XValue) );
        nx_values--;
    }
}


/*  Compound objects.
**
*/
int
xr_appendStruct (int snum, char *key, int value)
{
    XValue *x1 = &xValues[snum];	/* struct to be appended	*/
    XValue *x2 = &xValues[value];	/* value to be appended		*/

    xmlrpc_struct_set_value (&env, x1->val, key, x2->val);
}


int
xr_appendArray (int anum, char *key, int value)
{
    XValue *x1 = &xValues[anum];	/* array to be appended	*/
    XValue *x2 = &xValues[value];	/* value to be appended		*/

    xmlrpc_array_append_item (&env, x1->val, x2->val);
}




/*  Get methods.
*/

void
xr_getStructValue (int snum, char *key, void *value)
{
    XValue *xv = &xValues[snum];		/* struct object	*/
    xmlrpc_value *s = xv->val;
    xmlrpc_value *v = (xmlrpc_value *) NULL;

    if (xmlrpc_struct_has_key (&env, s, (const char *) key)) {
        xmlrpc_struct_find_value (&env, s, (const char *)key, &v);

	value = (void *)v;
    }
}


void
xr_getArrayValue (int anum, int index, void *value)
{

    XValue *xv = &xValues[anum];		/* array object		*/
    xmlrpc_value *tmp;

    xmlrpc_array_read_item (&env, xv->val, index, &tmp);

    /*  FIXME  */

/*
    switch (type) {
    case TY_INT: 	
	
        xmlrpc_read_int (&env, tmp, &ival);
	break;
    }
*/
}



/************************************************************************
**  PRIVATE PROCEDURES
**
*/


/*  GVAL -- Given a user-defined value, convert it to an xmlrpc_value.
*/
static xmlrpc_value *
xr_gval (int type, void *v)
{
    int    *iv  = (int *) v;
    double *dv  = (double *) v;
    const char   *str = (const char *) v;

    switch (type) {
    case TY_INT: 	return ( xmlrpc_int_new (&env, *iv) );
    case TY_DOUBLE: 	return ( xmlrpc_double_new (&env, *dv) );
    case TY_BOOL: 	return ( xmlrpc_bool_new (&env, (xmlrpc_bool)*iv) );
    case TY_STRING: 	return ( xmlrpc_string_new (&env, str) );
    case TY_DATETIME: 	return ( xmlrpc_datetime_new_str (&env, str) );
    case TY_ARRAY: 	return ( xmlrpc_array_new (&env) );
    case TY_STRUCT: 	return ( xmlrpc_struct_new (&env) );
    }
    return (xmlrpc_value *) NULL;
}


/*  SVAL -- Scan a user-type value from an xmlrpc_value.  Note we cannot
**  use this for compound objects such as arrays and structs, we assume
**  the caller has already allocated the uval pointer.
*/
static int
xr_sval (int type, xmlrpc_value *v, void *uval)
{
    size_t len;
    int    *iv  = (int *) uval;
    double *dv  = (double *) uval;
    const char   *str = (const char *) uval;
    xmlrpc_bool  bv;


    switch (type) {
    case TY_INT:
	xmlrpc_read_int (&env, v, iv);
	uval = (void *)&iv;
	break;
    case TY_DOUBLE:
	xmlrpc_read_double (&env, v, dv);
	uval = (void *)&dv;
	break;
    case TY_BOOL:
	xmlrpc_read_bool (&env, v, &bv);
	uval = (void *)&bv;
	break;
    case TY_STRING:
	xmlrpc_read_string_lp (&env, v, &len, &str);
	uval = (void *)&str;
	break;
    case TY_DATETIME:
	xmlrpc_read_datetime_str (&env, v, &str);
	uval = (void *)&str;
	break;
    }

    return ( ((env.fault_occurred) ? ERR : OK) );
}