loading
 
getVariables error
Padraig from Ireland  [9 posts]
3 years
I've noted the following problem when I request a variable using the API in C#, but the problem applies to the API in general.
If the variable requested has a value of 0 in roborealm, then the string returned via the API contains the correct variable name but the value field contains zero bytes, rather than a single byte of '0' as I would expect.

A typical response would be like this "<response><myvariable></myvariable></response>"

This results in the parser code returning a null, as if no response was received.
When reading a single variable I can work around this problem, but if multiple variable are requested the response contains fewer values than expected and there is no way to tell which is missing.
Steven Gentner from United States  [1371 posts] 3 years
Padraig,

The result is as expected. Within the RR scripting modules the GetVariable really means Get Variable As Integer which for a null or empty result the best representation is zero. That's the reason the GetStrVariable function exists. That will return empty string in that case.

When using the API, one should be able to detect an empty value in both single and multiple cases. The multiple case *should* specify an entry for each variable even if it is null. For an array, you should receive at least a comma per entry.

I think the change that is warranted is probably within the CSharp version of the API and how it deals with null entries. Would the addition to that code of a getIntVariable solve your immediate problem? Or what function are you specifically using?

This would be functionally similar to the GetDimension function which assumes an int and uses xml.getInt function included in the Program.cs source code in the examples download.

STeven.

Padraig from Ireland  [9 posts] 3 years
STeven,
Perhaps I didn't explain the problem correctly. The issue I'm having is the opposite to what you describe i.e. I'm requesting a variable which is an integer, when the value of the integer in roborealm is zero I would expect the response to be a string containing a single character '0'. Surely that is the most logical response for a value of zero which is a valid integer, but I'm getting no characters i.e. and empty string.

The C# API routines you provide then parse the response and because there is nothing in the value filed of the response it does not register any value for that variable.

If I read a single variable I can workaround the null response, its not ideal as the null could be due to a timeout or other issue, but I can deal with that. However if I request three integer variables, lets say the values of which are 1, 0, and 3, the API function  responds with only two values 1 and 3 so I have no way of knowing which is which or what variable is missing. If two values are zero I will get only one value returned, and if all are zero I get none.

Below is the string I'm seeing right now inside the API function "public bool parse(String s, Dictionary<string, string> h, List<string> v)" after I request three variables which are all zero in roborealm:    s =    "<response><FOCUS_VALUE></FOCUS_VALUE><first_x></first_x><first_y></first_y></response>"

Roborealm is clearly send back empty strings for integer values of zero!
Regards,
Padraig
Steven Gentner from United States  [1371 posts] 3 years
Padraig,

The assumption you are making are that the values are integers. RoboRealm variables are loosely typed so they can change type as needed (yes, very annoying for programmers but ideal for an easy to use system). Often, modules will simply remove a variable entirely to signal a zero value.

Perhaps you can post the robofile that you are using that is generating these variables? Note, internally if the value is zero, empty string, or non-existent the value is considered the same.

So in your example, RR is probably sending back empty strings for variables that simply don't exist ... they are not integer or float or string in that case.

The correction is what I suggested last time, its in the parsing of the XML coming back. An XML entry of zero or empty string should be considered the same.

To solve this problem, you need to update the Parse routine in your CSharp application to the following. This will ensure a zero value exists for those empty variables which should hopefully solve your issue.

Just copy and paste this over the existing function. The API download has also been updated with this.

        public bool parse(String s, Dictionary<string,string> h, List<string> v)
        {
            bool isEndTag;
            byte[] txt = Encoding.ASCII.GetBytes(s);
            int i, j;
            int len = s.Length;
            StringBuilder[] keys = new StringBuilder[10];
            StringBuilder value = new StringBuilder();
            for (i=0;i<10;i++)
              keys[i] = new StringBuilder();
            int keyTop=-1;
            bool valueAdded = false;

            for (i=0;i<len;)
            {
              // read in key
              if (txt[i]=='<')
              {
                i++;
                if (txt[i] == '/')
                {
                  isEndTag = true;
                  i++;
                }
                else
                {
                  isEndTag = false;
                  valueAdded = false;
                }

                keyTop++;
                keys[keyTop].Length =0;
                while ((i<len)&&(txt[i]!='>'))
                {
                  keys[keyTop].Append((char)txt[i]);
                  i++;
                }
                if (txt[i++]!='>')
                {
                  Console.WriteLine("Missing close > tag");
                  return false;
                }

                if (isEndTag)
                {
                  if (!keys[keyTop].ToString().Equals(keys[keyTop-1].ToString()))
                  {
                    Console.WriteLine("Mismatched XML tags " + keys[keyTop] + " -> " + keys[keyTop - 1]);
                    return false;
                  }
                  if (!valueAdded)
                  {
                    if (h != null) h.Add(keys[keyTop].ToString(), "0");
                    if (v != null) v.Add("0");
                  }
                  keyTop -= 2;
                }
              }
              else
              {
                // read in value
                value.Length = 0;

                while ((i<len)&&(txt[i]!='<'))
                {
                  value.Append((char)txt[i]);
                  i++;
                }

                StringBuilder key = new StringBuilder();
                for (j=0;j<=keyTop;j++)
                {
                  if (j>0) key.Append('.');
                  key.Append(keys[j]);
                }

                String escapedValue = unescape(value.ToString());
                if (h!=null) h.Add(key.ToString(), escapedValue);
                if (v!=null) v.Add(escapedValue);
                valueAdded = true;
              }
            }

            return true;
        }

This forum thread has been closed due to inactivity (more than 4 months) or number of replies (more than 50 messages). Please start a New Post and enter a new forum thread with the appropriate title.

 New Post   Forum Index