Forum OpenACS Q&A: Response to Tcl function call to remote AOLserver via xmlrpc ?

Dave, yep, that fixed it. But now that I can actually make rpc calls, I've run into some other issues.

The server messes up whenever it needs to return any string (including lists) with whitespace in it - it returns only the last non-whitspace item. Is this a bug?

It also doesn't play nice with using the optional parameters of ad_proc. The following code fails in xmlrpc_construct with the error: no value for option "abc" (see below for my test proc):

[xmlrpc_call $url bb_rpc_string -quotes_p 1 abc]

Also, the XML-RPC spec. defines scalars (of different types), structs, and arrays. Structs have key value pairs like Tcl arrays and do not preserve order, but (unlike Tcl arrays) struct values may themselves be scalars, structs, or arrays. Arrays contain values only (not key value pairs), and each value may be also be a scalar, struct, or array. I assume arrays preserve order, although the spec. doesn't say.

So, I guess Tcl arrays should be represented as XML-RPC structs, and Tcl lists could be represented by either scalar strings or XML-RPC arrays. If the client and server are both using Tcl, I just using the Tcl string representation of lists might be most convenient, but XML-RPC arrays would be correct cross-language way to represent lists.

I don't think ns_xmlrpc is attempting to do any magic to automatically convert Tcl data structures to XML-RPC data structures. So, I assume I'm supposed to write a wrapper around each of my procedures to do these data structure conversions for me? Are there any good examples somewhere of doing that?

validator.tcl has a lot of stuff like this:

set struct(times10) [expr $number * 10]
return "-struct [list [array get struct]]"
And it looks to me like the xmlrpc_construct proc expects to get all data as a Tcl list containing values, plus those little "what type of data structure or scalar value is this?" prefix tags, like -struct, -array, or -date.

So, am I on the right track here? I have to write wrappers that explicitly specify all my data types in XML-RPC terms? Has anyone considered or tried having ns_xmlrpc automagically convert Tcl to XML-RPC data structures and back, instead?

Here are some examples showing the whitespace and parsing of '-' (like in ad_proc) bugs:

ad_proc bb_rpc_list_1 {{}} {} {
   return [list a b c d]
}
ad_proc bb_rpc_list_2 {{}} {} {
   return ""[list a b c d]""
}

ad_proc bb_rpc_string_1 {{}} {} {
   return {"a b c d"}
}
ad_proc bb_rpc_string_2 {{}} {} {
   return {a b c d}
}

ad_proc bb_rpc_string {{
   -quotes_p 0
} str } {} {
   if { $quotes_p } {
      return ""$str""
   } else {
      return $str
   }
}

append body "
local:  [bb_rpc_list_1]  	remote:  [xmlrpc_call $url bb_rpc_list_1]
local:  [bb_rpc_list_2]  	remote:  [xmlrpc_call $url bb_rpc_list_2]
                           
local:  [bb_rpc_string_1]  	remote:  [xmlrpc_call $url bb_rpc_string_1]
local:  [bb_rpc_string_2]  	remote:  [xmlrpc_call $url bb_rpc_string_2]

local:  [bb_rpc_string {a b c}]  	remote:  [xmlrpc_call $url bb_rpc_string {a b c}]
local:  [bb_rpc_string {abc}]    	remote:  [xmlrpc_call $url bb_rpc_string {abc}]

local:  [bb_rpc_string -quotes_p 1 {abc}]    	remote:  FAILS
"

## Fails in xmlrpc_construct with:  no value for option "abc"
#[xmlrpc_call $url bb_rpc_string -quotes_p 1 {abc}]

ns_return 200 text/plain $body

And here are my results from the commands immediately above:

local:  a b c d    remote:  d
local:  "a b c d"  remote:  a b c d
                      
local:  "a b c d"  remote:  a b c d
local:  a b c d    remote:  d

local:  a b c      remote:  c
local:  abc        remote:  abc

local:  "abc"      remote:  FAILS