1 saw 1.1 /*-----------------------------------------------------------------------------
2 * Copyright (c) 1993 Southeastern Universities Research Association,
3 * Continuous Electron Beam Accelerator Facility
4 *
5 * This software was developed under a United States Government license
6 * described in the NOTICE file included as part of this distribution.
7 *
8 * Stephen A. Wood, 12000 Jefferson Ave., Newport News, VA 23606
9 * Email: saw@cebaf.gov Tel: (804) 249-7367 Fax: (804) 249-5800
10 *-----------------------------------------------------------------------------
11 *
12 * Description:
13 * Handlers for RPC services.
14 *
15 * Author: Stephen Wood, CEBAF Hall C
16 *
17 * Revision History:
18 * $Log: daVarHandlers.c,v $
19 * Revision 1.7 1995/01/09 15:59:53 saw
20 * Move location of kill_trailing function in the file
21 *
22 saw 1.1 * Revision 1.6 1994/11/07 14:13:49 saw
23 * Finish name change by include daVarHandlers.h instead of daVarServ.h
24 *
25 * Revision 1.5 1994/10/16 21:37:57 saw
26 * Add RPC support for Fortran strings
27 * Change name from daVarServ to daVarHandlers
28 *
29 * Revision 1.4 1994/06/03 21:04:45 saw
30 * Add RPC support for doubles
31 *
32 * Revision 1.3 1993/08/12 15:03:49 saw
33 * Add #include <rpc/rpc.h>
34 *
35 * Revision 1.2 1993/05/10 21:05:05 saw
36 * Fix description
37 *
38 * Revision 1.1 1993/05/10 21:02:55 saw
39 * Initial revision
40 *
41 */
42
43 saw 1.1 /*
44 If an index is put on a variable for a read, just that array element is read.
45 If an index is put on a variable for a write, that array element is used as
46 the starting point for however long a list of values is contained in the
47 write call. If the write would go past the end of the array, nothing is
48 written and an error is returned.
49
50 A write of a string to a value (of the type string) will be allowed if the
51 string to be written has a length <= to the allocated size specified in
52 the ->size.
53
54 If a string is written to a title, the existing string will be free'd and
55 the new string written. The new string may be any size.
56
57 */
58
59 #include <string.h>
60 #include <rpc/rpc.h>
61
62 #include "daVar.h"
63 #include "daVarRpc.h"
64 saw 1.1 #include "daVarHandlers.h"
65
66 char *daVarRAtrList[]={"value","title","size","flag","type","watr","ratr",0};
67 char *daVarWAtrList[]={"value","title",0};
68
69
70 daVarStatus daVarClassFind(char *name, daVarStruct **varp);
71 daVarStatus daVarAttributeFind(char *name, daVarStruct *varclass,
72 daVarStruct **varp, char **attribute,
73 int *index);
74 void daVarRhandler(char *name, daVarStruct *varclass, any *retval);
75 daVarStatus daVarWhandler(char *name,daVarStruct *varclass,any *setval);
76 char *daVarMakeRAtrList();
77 char *daVarMakeWAtrList();
78 void daVarCopyAlist(char *nllist,char **list);
79
80 static char *kill_trailing(char *s, char t)
81 {
82 char *e;
83 e = s + strlen(s);
84 if (e>s) { /* Need this to handle NULL string.*/
85 saw 1.1 while (e>s && *--e==t); /* Don't follow t's past beginning. */
86 e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
87 }
88 return s;
89 }
90
91 daVarStatus daVarWriteVar(char *name, any *setval)
92 {
93 daVarStruct *varclass;
94
95 if(daVarClassFind(name,&varclass)!=S_SUCCESS){
96 return(S_FAILURE);
97
98 }
99 if(varclass->whook){
100 return((varclass->whook)(name,varclass,setval));
101 } else {
102 return(daVarWhandler(name,varclass,setval));
103 }
104 }
105
106 saw 1.1
107 void daVarReadVar(char *name, any *retval)
108 {
109 daVarStruct *varclass;
110
111 if(daVarClassFind(name,&varclass)!=S_SUCCESS){
112 retval->valtype = DAVARERROR_RPC;
113 retval->any_u.error = S_FAILURE;
114 return;
115 }
116 if(varclass->rhook){
117 (varclass->rhook)(name,varclass,retval);
118 } else {
119 daVarRhandler(name,varclass,retval);
120 }
121 }
122
123 daVarStatus daVarWhandler(char *name,daVarStruct *varclass,any *setval)
124 /* The default Write handler */
125 {
126 daVarStruct *varp;
127 saw 1.1 char *attribute;
128 daVarStatus status;
129 int index;
130
131 status = daVarAttributeFind(name, varclass, &varp, &attribute, &index);
132 if(status == S_SUCCESS)
133 status = daVarRegWatr(varp, attribute, index, setval);
134 /* A special handler would check more attributes if status != SUCCESS */
135 return(status);
136 }
137
138 void daVarRhandler(char *name, daVarStruct *varclass, any *retval)
139 /* The default Read handler */
140 {
141 daVarStruct *varp;
142 char *attribute;
143 daVarStatus status;
144 int index;
145
146 status = daVarAttributeFind(name, varclass, &varp, &attribute, &index);
147 status = daVarRegRatr(varp, attribute, index, retval);
148 saw 1.1 /* A special handler would check more attributes if status != SUCCESS */
149 return;
150 }
151
152 daVarStatus daVarRegRatr(daVarStruct *varp, char *attribute
153 ,int index, any *retval)
154 /* Regular Read Attribute routine. Returns failure if attribute is not
155 of the standard set. */
156 {
157 int i;
158
159 if(*attribute == '\0' || strcasecmp(attribute,DAVAR_VALUE) == 0){
160 if(varp->type == DAVARINT){
161 retval->valtype = DAVARINT_RPC;
162 if(index == DAVAR_NOINDEX) {
163 retval->any_u.i.i_len = varp->size;
164 retval->any_u.i.i_val = (int *) malloc(varp->size*sizeof(int));
165 for(i=0;i<varp->size;i++) {
166 retval->any_u.i.i_val[i] = ((DAINT *)varp->varptr)[i];
167 /* printf("%d %d\n",i,retval->any_u.i.i_val[i]);*/
168 }
169 saw 1.1 } else {
170 retval->any_u.i.i_len = 1;
171 retval->any_u.i.i_val = (int *) malloc(sizeof(int));
172 retval->any_u.i.i_val[0] = ((DAINT *)varp->varptr)[index];
173 }
174 } else if(varp->type == DAVARFLOAT){
175 retval->valtype = DAVARFLOAT_RPC;
176 if(index == DAVAR_NOINDEX) {
177 retval->any_u.r.r_len = varp->size;
178 retval->any_u.r.r_val = (float *) malloc(varp->size*sizeof(float));
179 for(i=0;i<varp->size;i++) {
180 retval->any_u.r.r_val[i] = ((DAFLOAT *)varp->varptr)[i];
181 /* printf("%d %f\n",i,retval->any_u.r.r_val[i]);*/
182 }
183 } else {
184 retval->any_u.r.r_len = 1;
185 retval->any_u.r.r_val = (float *) malloc(sizeof(float));
186 retval->any_u.r.r_val[0] = ((DAFLOAT *)varp->varptr)[index];
187 }
188 } else if(varp->type == DAVARDOUBLE){
189 /* Return a float type for now since doubles don't work with our RPC */
190 saw 1.1 retval->valtype = DAVARFLOAT_RPC;
191 if(index == DAVAR_NOINDEX) {
192 retval->any_u.r.r_len = varp->size;
193 retval->any_u.r.r_val = (float *) malloc(varp->size*sizeof(float));
194 for(i=0;i<varp->size;i++) {
195 retval->any_u.r.r_val[i] = ((DADOUBLE *)varp->varptr)[i];
196 /* printf("%d %f\n",i,retval->any_u.r.r_val[i]);*/
197 }
198 } else {
199 retval->any_u.r.r_len = 1;
200 retval->any_u.r.r_val = (float *) malloc(sizeof(float));
201 retval->any_u.r.r_val[0] = ((DADOUBLE *)varp->varptr)[index];
202 }
203 } else if(varp->type == DAVARSTRING && index == DAVAR_NOINDEX){
204 /* indices to strings not supported */
205 retval->valtype = DAVARSTRING_RPC;
206 retval->any_u.s = (char *) malloc(strlen((char *)varp->varptr) + 1);
207 strcpy(retval->any_u.s,(char *)varp->varptr);
208 /* printf("%s\n",retval->any_u.s);*/
209 } else if(varp->type == DAVARFSTRING && index == DAVAR_NOINDEX){
210 retval->valtype = DAVARSTRING_RPC;
211 saw 1.1 retval->any_u.s = (char *) malloc(varp->size+1);
212 strncpy(retval->any_u.s,(char *)varp->varptr,varp->size);
213 retval->any_u.s[varp->size] = '\0';
214 kill_trailing(retval->any_u.s,' ');
215 } else {
216 retval->valtype = DAVARERROR_RPC;
217 retval->any_u.error = S_SUCCESS;
218 }
219 return(S_SUCCESS);
220 } else if(strcasecmp(attribute,DAVAR_TITLE) == 0){
221 retval->valtype = DAVARSTRING_RPC;
222 retval->any_u.s = (char *) malloc(strlen(varp->title) + 1);
223 strcpy(retval->any_u.s,varp->title);
224 /* printf("%s\n",retval->any_u.s);*/
225 return(S_SUCCESS);
226 } else if(strcasecmp(attribute,DAVAR_SIZE) == 0){
227 retval->valtype = DAVARINT_RPC;
228 retval->any_u.i.i_len = 1;
229 retval->any_u.i.i_val = (int *) malloc(sizeof(int));
230 retval->any_u.i.i_val[0] = varp->size;
231 return(S_SUCCESS);
232 saw 1.1 } else if(strcasecmp(attribute,DAVAR_TYPE) == 0){
233 retval->valtype = DAVARINT_RPC;
234 retval->any_u.i.i_len = 1;
235 retval->any_u.i.i_val = (int *) malloc(sizeof(int));
236 retval->any_u.i.i_val[0] = varp->type;
237 return(S_SUCCESS);
238 } else if(strcasecmp(attribute,DAVAR_FLAG) == 0){
239 retval->valtype = DAVARINT_RPC;
240 retval->any_u.i.i_len = 1;
241 retval->any_u.i.i_val = (int *) malloc(sizeof(int));
242 retval->any_u.i.i_val[0] = varp->flag;
243 return(S_SUCCESS);
244 } else if(strcasecmp(attribute,DAVAR_WATR) == 0){
245 retval->valtype = DAVARSTRING_RPC;
246 retval->any_u.s = daVarMakeWAtrList();
247 return(S_SUCCESS);
248 } else if(strcasecmp(attribute,DAVAR_RATR) == 0){
249 retval->valtype = DAVARSTRING_RPC;
250 retval->any_u.s = daVarMakeRAtrList();
251 return(S_SUCCESS);
252 } else {
253 saw 1.1 retval->valtype = DAVARERROR_RPC;
254 retval->any_u.error = S_DAVAR_UNKATTR; /* Why success??? */
255 return(S_DAVAR_UNKATTR);
256 }
257 }
258
259 char *daVarMakeRAtrList()
260 /* Caller must free up the allocated memory */
261 {
262 static int listsize=0;
263 char *nllist;
264
265 if(listsize==0) listsize=daVarGetAListSize(daVarRAtrList);
266 nllist = (char *) malloc(listsize+1);
267 daVarCopyAlist(nllist,daVarRAtrList); /* Copy to \n delineated list */
268 return(nllist);
269 }
270 char *daVarMakeWAtrList()
271 /* Caller must free up the allocated memory */
272 {
273 static int listsize=0;
274 saw 1.1 char *nllist;
275
276 if(listsize==0) listsize=daVarGetAListSize(daVarWAtrList);
277 nllist = (char *) malloc(listsize+1);
278 daVarCopyAlist(nllist,daVarWAtrList);
279 return(nllist);
280 }
281 int daVarGetAListSize(char **list)
282 {
283 int len;
284 len = 0;
285 while(*list) len += strlen(*list++)+1;
286 return(len);
287 }
288 void daVarCopyAlist(char *nllist,char **list)
289 {
290 char *nlp;
291 char *lp;
292
293 nlp = nllist;
294 while(lp=*list++){
295 saw 1.1 while(*nlp = *lp++) nlp++;
296 *nlp++ = '\n';
297 }
298 *nlp = '\0';
299 }
300
301 daVarStatus daVarRegWatr(daVarStruct *varp, char *attribute
302 , int index, any *setval)
303 /* Regular Write Attribute routine. Returns failure if attribute is not
304 of the standard set. */
305 {
306 int i;
307
308
309 if(*attribute == '\0' || strcasecmp(attribute,DAVAR_VALUE) == 0){
310 if(index == DAVAR_NOINDEX) index = 0;
311 if(setval->valtype == DAVARINT_RPC) {
312 if(varp->size >= setval->any_u.i.i_len+index){
313 if(varp->type == DAVARINT){
314 for(i=0;i<setval->any_u.i.i_len;i++){
315 ((DAINT *)varp->varptr)[i+index] = setval->any_u.i.i_val[i];
316 saw 1.1 }
317 } else if(varp->type == DAVARFLOAT){
318 for(i=0;i<setval->any_u.i.i_len;i++){
319 ((DAFLOAT *)varp->varptr)[i+index] = setval->any_u.i.i_val[i];
320 }
321 } else if(varp->type == DAVARDOUBLE){
322 for(i=0;i<setval->any_u.i.i_len;i++){
323 ((DADOUBLE *)varp->varptr)[i+index] = setval->any_u.i.i_val[i];
324 }
325 } else
326 return(S_DAVAR_ILLCONV);
327 } else
328 return(S_DAVAR_TOOMANY);
329 } else if(setval->valtype == DAVARFLOAT_RPC) {
330 if(varp->size >= setval->any_u.r.r_len+index){
331 if(varp->type == DAVARINT){
332 for(i=0;i<setval->any_u.r.r_len;i++){
333 ((DAINT *)varp->varptr)[i+index] = floatToLong(setval->any_u.r.r_val[i]);
334 }
335 } else if(varp->type == DAVARFLOAT){
336 for(i=0;i<setval->any_u.r.r_len;i++){
337 saw 1.1 ((DAFLOAT *)varp->varptr)[i+index] = setval->any_u.r.r_val[i];
338 }
339 } else if(varp->type == DAVARDOUBLE){
340 for(i=0;i<setval->any_u.r.r_len;i++){
341 ((DADOUBLE *)varp->varptr)[i+index] = setval->any_u.r.r_val[i];
342 }
343 } else
344 return(S_DAVAR_TOOMANY);
345
346 } else
347 return(S_DAVAR_ILLCONV);
348 }
349 #ifdef DOUBLERPC
350 else if(setval->valtype == DAVARDOUBLE_RPC) {
351 if(varp->size >= setval->any_u.d.d_len+index){
352 if(varp->type == DAVARINT){
353 for(i=0;i<setval->any_u.d.d_len;i++){
354 ((DAINT *)varp->varptr)[i+index] = floatToLong(setval->any_u.d.d_val[i]);
355 }
356 } else if(varp->type == DAVARFLOAT){
357 for(i=0;i<setval->any_u.d.d_len;i++){
358 saw 1.1 ((DAFLOAT *)varp->varptr)[i+index] = setval->any_u.d.d_val[i];
359 }
360 } else if(varp->type == DAVARDOUBLE){
361 for(i=0;i<setval->any_u.d.d_len;i++){
362 ((DADOUBLE *)varp->varptr)[i+index] = setval->any_u.d.d_val[i];
363 }
364 } else
365 return(S_DAVAR_TOOMANY);
366 } else
367 return(S_DAVAR_ILLCONV);
368 }
369 #endif
370 else if(setval->valtype == DAVARSTRING_RPC) {
371 if(varp->type == DAVARSTRING) {
372 if(varp->size < strlen(setval->any_u.s)+index) {
373 return(S_DAVAR_TOOMANY); /* Maybe we should truncate strings??? */
374 }
375 strcpy(((char *) varp->varptr)+index, setval->any_u.s);
376 } else if(varp->type == DAVARFSTRING) {
377 int in_len;
378 int blanks;
379 saw 1.1 char *p;
380 in_len = strlen(setval->any_u.s);
381 /* printf("|%s|\n",setval->any_u.s);*/
382 if(varp->size < in_len+index) {
383 return(S_DAVAR_TOOMANY);
384 }
385 strncpy(((char *) varp->varptr)+index,
386 setval->any_u.s,in_len);
387 blanks = varp->size - index - in_len;
388 p = ((char *) varp->varptr) + index + in_len;
389 while(blanks-- > 0) *p++ = ' '; /* Blank pad */
390 } else
391 return(S_DAVAR_ILLCONV);
392 } else
393 return(S_FAILURE);
394 } else if(strcasecmp(attribute,DAVAR_TITLE) == 0){
395 /* Index ignored for title attribute */
396 /* printf("setval->valtype = %d\n",setval->valtype);*/
397 if(setval->valtype == DAVARSTRING_RPC) {
398 varp->title = (char *) realloc(varp->title,strlen(setval->any_u.s) + 1);
399 /* printf("Writing string %s\n",setval->any_u.s);*/
400 saw 1.1 strcpy(varp->title,setval->any_u.s);
401 } else
402 return(S_DAVAR_ILLCONV);
403 } else {
404 return(S_DAVAR_UNKATTR);
405 }
406 return(S_SUCCESS);
407 }
408
409 daVarStatus daVarClassFind(char *name, daVarStruct **varp)
410 /* Pass ptr to name of full variable.
411 Name is of form a.b.c.d.e..., searches for variable "a", then "a.b"
412 and so on until a registered variable is found.
413 varp is the pointer to the structure of the registered variable.
414
415 Must have write access to the string name (even though it will be left
416 unchanged.)
417
418 */
419 {
420 char c, *s, *t, *end;
421 saw 1.1
422 s = name;
423
424 end = s + strlen(s);
425 if((t=strchr(s,'('))) if(t<end) end = t; /* ) (to keep c-mode happy) */
426 if((t=strchr(s,'['))) if(t<end) end = t; /* ] (to keep c-mode happy) */
427 c = *end;
428 *end = '\0';
429
430 while((t=strchr(s,'.'))){
431 *t = 0;
432 if(daVarLookupP(name, varp) == S_SUCCESS) {
433 *t = '.';
434 *end = c;
435 return(S_SUCCESS);
436 }
437 *t = '.';
438 s = t + 1;
439 }
440 if(daVarLookupP(name, varp) == S_SUCCESS) {
441 *end = c;
442 saw 1.1 return(S_SUCCESS);
443 }
444 *end = c;
445 return(S_FAILURE);
446 }
447 daVarStatus daVarAttributeFind(char *name, daVarStruct *varclass,
448 daVarStruct **varp, char **attribute, int *index)
449 /* Return DAVAR_NOINDEX for index if none specified. */
450 {
451 char *atptr; /* Pointer to attribute string */
452 daVarStatus status;
453 char *end, *pptr, parenchar;
454
455 end = name + strlen(name);
456 if((status=thGetIndex(name, index, &pptr)) == S_SUCCESS) {
457 parenchar = *pptr;
458 } else if(status == S_DAVAR_NOINDEX) {
459 parenchar = *pptr;
460 *index = DAVAR_NOINDEX;
461 } else /* Failed */
462 return(S_FAILURE);
463 saw 1.1
464 *pptr = '\0';
465 atptr = pptr;
466
467
468 if(strcasecmp(name,varclass->name) == 0){ /* Lookup alread done */
469 *varp = varclass;
470 *attribute = end; /* Point to null */
471 } else if(daVarLookupP(name, varp) == S_SUCCESS){ /* Fullly qualified name?*/
472 *attribute = end; /* Point to null */
473 } else { /* Start striping attributes off pptr */
474 int clnamlen;
475 clnamlen = strlen(varclass->name);
476 atptr--;
477 *varp = varclass;
478 while((atptr - name) > clnamlen) { /* Stop before "class" name */
479 if(*atptr == '.'){
480 *atptr = '\0';
481 if(daVarLookupP(name, varp) == S_SUCCESS){
482 *atptr = '.';
483 break;
484 saw 1.1 *attribute = atptr + 1;
485 } else
486 *atptr-- = '.';
487 } else
488 atptr--;
489 }
490 *attribute = atptr + 1;
491 }
492 /* *pptr = parenchar; Leave name null terminated at the left paren */
493 return(S_SUCCESS);
494 }
|