binaryDecode with variable number of parameters

Mark Wieder mwieder at ahsoftware.net
Sun Feb 19 22:05:02 EST 2012


Len-

Sunday, February 19, 2012, 5:23:11 PM, you wrote:


> Related to my problem with reading binary data from a socket, how do I
> handle a variable number of numbers that will come in with binaryDecode?

>>> To explain, I get a number in the packet header that tells me there are
>>> x number of bytes to follow in this packet.  I know the first byte is a
>>> remote ID and the second is a function code.  Based on the function
>>> code, the number of two byte integers that follows is going to be (the
>>> number of bytes in the message / 2) - 1 (for the function code and
>>> remote ID).  One time there might be 2 integers to follow, another there
>>> might be 10.  There is a "number of words" number that is part of the
>>> command so I know how many words there will be but the binaryDecode
>>> function requires that I specify a name for each variable that is going
>>> to get a value.
>>> Ideally, I'd like to put all of these words in an array so I can process
>>> them, but this doesn't seem to be an option for the binaryDecode
>>> command.  Should I build up a string that has
>>> "...,var[0],var[1],...,var[x] in it to account for all the variables and
>>> then use a "do" or "dispatch" to actually do the binaryDecode?
>>> Also, if I use var[0], var[1], etc., do I need to create ALL of the
>>> indexes first (for binaryDecode) or will just creating the first one
>>> (var[0]) be sufficient?
>> I think I'd do something like:
>>
>> read from socket for 1 bytes
>> put it into tRemoteID
>> read from socket for 1 bytes
>> put it into tFunctionCode
>> switch tFunctionCode
>>    case kFunc1
>>      put 2 into tWordCount
>>      break
>>    case kFunc2
>>      put 10 into tWordCount
>>      break
>>    case -- ok - you get the idea
>>      break
>> end switch
>> read from socket for (2*tWordCount) bytes
>> put it into tData
>> put binaryDecode("m3", tData, tSeq, tProto, tBytes) into tActual
>> if tActual is not tWordCount then
>>    -- oops
>> end if
>>
>> ...and yes, you do need to have the maximum number of variables
>> already defined. There's no penalty for having extra compartments in
>> the binaryDecode line, but you don't want to have too few.
>>
> Thanks for the reply Mark but it's not quite the problem.  The order
> that the data comes in is:
> tSequence, tProto, tBytes (all 16 bit), tRemoteID, tFunctionCode, xxxxx

> After the function code, if you are doing a "write multiple registers"
> for example, you will have a beginning register, and the count of 
> registers, followed by the actual data you are trying to write.  This is
> where things start to fall down for me because of this variable number
> of items and the requirement to have a predefined variable for each 
> possible answer.  I know when I get to the data portion exactly how many
> registers I'm going to have to read (and therefore how many variables
> I'm going to need).  Based on your last paragraph though, it appears
> that I'll have to either have a separate case for each possible number
> of data words, or read them one at a time in a loop and assign them to a
> variable in the loop.  Neither of those is the optimal way to go but one
> must do what one must do.  :-)

So by the time you get to tFunctionCode you know how many bytes will
be coming in the stream, right? That's the xxxxx data? I still think
something like this is the easiest and most maintainable way to go.
How many functionCodes are you dealing with?

local tData1, tData2, tData3, tData4, ...

read from socket for 6 bytes
put it into tData
get binaryDecode("m3", tData, tSequence, tProto, tBytes)
read from socket for 1 byte
put it into tRemoteID
read from socket for 1 byte
put it into tFunctionCode

switch tFunctionCode
    case kFunc1
      put 2 into tWordCount
      break
    case kFunc3
    case kFunc4
      put 3 into tWordCount
      break
    case kFunc2
      put 10 into tWordCount
      break
    case -- ok - you get the idea
      break
end switch
read from socket for (2*tWordCount) bytes
put it into tData
put binaryDecode("m3", tData, tData1, tData2, tData3, tData4, etc.) into tActual
if tActual is not tWordCount then
    -- oops
end if

-- 
-Mark Wieder
 mwieder at ahsoftware.net





More information about the use-livecode mailing list