Changeset 7:bafe58db1509 in xplra


Ignore:
Timestamp:
01/04/13 12:50:45 (11 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Added support for setting values

Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • misc/client.py

    r6 r7  
    1616               "fa" : 0x11,
    1717               "ia" : 0x12,
    18                "ba" : 0x13 }
     18               "ba" : 0x13,
     19               "s"  : 0x13 }
     20
     21    @staticmethod
     22    def _splitArgs(args):
     23        """Split the given argument string into a list of words."""
     24        words = []
     25        word = ""
     26        inQuote = False
     27        for c in args:
     28            if c.isspace() and not inQuote:
     29                if word:
     30                    words.append(word)
     31                    word = ""
     32            elif c=="\"" and (not word or inQuote):
     33                inQuote = not inQuote
     34            else:
     35                word += c
     36        if word:
     37            words.append(word)
     38        return words
    1939
    2040    @staticmethod
     
    5777    def do_get(self, args):
    5878        """Handle the 'get' command"""
    59         words = args.split()
     79        words = self._splitArgs(args)
    6080        if len(words)<2:
    6181            print >> sys.stderr, "Missing parameters"
     
    85105        result = self._readU8()
    86106        if result==0:
    87             value = None
    88             if type=="i":
    89                 value = self._readS32()
    90             elif type=="f":
    91                 value = self._readFloat()
    92             elif type=="d":
    93                 value = self._readDouble()
    94             elif type=="fa":
    95                 length = self._readS32()
    96                 if length>0:
    97                     value = [self._readFloat() for i in range(0, length)]
    98             elif type=="ia":
    99                 length = self._readS32()
    100                 if length>0:
    101                     value = [self._readS32() for i in range(0, length)]
    102             elif type=="ba":
    103                 length = self._readS32()
    104                 if length>0:
    105                     bytes = [self._readU8() for i in range(0, length)]
    106                     value = ""
    107                     for b in bytes:
    108                         if b==0: break
    109                         value += chr(b)
    110                     #value = bytes
    111 
    112             print value
     107            print self._readValue(type)
    113108        else:
    114             print "Result code:", result
     109            print "Error code:", result
     110
     111    def do_set(self, args):
     112        """Handle the 'set' command"""
     113        words = self._splitArgs(args)
     114        if len(words)<3:
     115            print >> sys.stderr, "Missing parameters"
     116            return False
     117
     118        name = words[0]
     119
     120        type = words[1]
     121        if type not in self._types:
     122            print >> sys.stderr, "Invalid type"
     123            return False
     124
     125        value = words[2]
     126
     127        length = None
     128        offset = None
     129        if len(words)>4:
     130            length = int(words[3])
     131            offset = int(words[4])
     132
     133        self._writeU8(0x02)
     134        self._writeString(name)
     135        self._writeU8(self._types[type])
     136        if length is not None:
     137            self._writeS32(length)
     138            self._writeS32(offset)
     139        self._writeValue(type, value, length)
     140
     141        self._flush()
     142
     143        result = self._readU8()
     144        if result!=0:
     145            print "Error code:", result
    115146
    116147    def _writeU8(self, x):
     
    121152        """Write the given value as a signed, 32-bit value."""
    122153        self._stream.write(struct.pack("i", x))
     154
     155    def _writeFloat(self, x):
     156        """Write the given value as a single-precision floating point."""
     157        self._stream.write(struct.pack("f", x))
     158
     159    def _writeDouble(self, x):
     160        """Write the given value as a double-precision floating point."""
     161        self._stream.write(struct.pack("d", x))
    123162
    124163    def _writeLength(self, length):
     
    164203                return length
    165204
    166     @staticmethod
    167205    def _readString(self):
    168206        """Read a string from our stream."""
     
    170208        return self._stream.read(length)
    171209
     210    def _readValue(self, type):
     211        """Read the value of the given type from the stream."""
     212        if type=="i":
     213            return self._readS32()
     214        elif type=="f":
     215            return self._readFloat()
     216        elif type=="d":
     217            return self._readDouble()
     218        elif type in ["fa", "ia", "ba", "s"]:
     219            length = self._readS32()
     220            if length>8192:
     221                print "Very big length:", length
     222                return None
     223            elif length>0:
     224                if type=="fa":
     225                    return [self._readFloat() for i in range(0, length)]
     226                elif type=="ia":
     227                    return [self._readS32() for i in range(0, length)]
     228                elif type=="ba" or type=="s":
     229                    bytes = [self._readU8() for i in range(0, length)]
     230                    if type=="ba":
     231                        return bytes
     232                    else:
     233                        string = ""
     234                        for b in bytes:
     235                            if b==0: break
     236                            string += chr(b)
     237                        return string
     238            elif length==0:
     239                return []
     240            else:
     241                return None
     242
     243    def _writeValue(self, type, value, length = None):
     244        """Write the given value of the given type to the stream."""
     245        if type=="i":
     246            self._writeS32(int(value))
     247        elif type=="f":
     248            self._writeFloat(float(value))
     249        elif type=="d":
     250            self._writeDouble(float(value))
     251        elif type in ["fa", "ia", "ba", "s"]:
     252            if type=="s":
     253                values = [ord(c) for c in value]
     254            else:
     255                words = [word.strip() for word in value.split(",")]
     256                values = [float(word) if type=="fa" else int(word)
     257                          for word in words]
     258            if len(values)<length:
     259                values += [0.0 if type=="fa" else 0] * (length-len(values))
     260            elif len(values)>length:
     261                values = values[:length]
     262            for value in values:
     263                if type=="fa":
     264                    self._writeFloat(value)
     265                elif type=="ia":
     266                    self._writeS32(value)
     267                else:
     268                    self._writeU8(value)
     269
    172270#------------------------------------------------------------------------------
    173271
  • misc/test1.sh

    r6 r7  
    1111get sim/flightmodel/position/latitude d
    1212get sim/flightmodel/position/longitude d
    13 get sim/aircraft/view/acf_descrip ba -1 0
     13get sim/aircraft/view/acf_descrip s -1 0
    1414get sim/aircraft/prop/acf_en_type ia -1 0
    1515get sim/aircraft/prop/acf_prop_dir fa -1 0
  • src/xplra/GetDataRefTask.cc

    r6 r7  
    6969        if (!stream) return 0;
    7070
     71        if (length>Protocol::MAX_LENGTH) {
     72            result = Protocol::RESULT_INVALID_LENGTH;
     73            return 0;
     74        }
     75        if (offset<0) {
     76            result = Protocol::RESULT_INVALID_OFFSET;
     77            return 0;
     78        }
     79
    7180        if (type==Protocol::TYPE_FLOAT_ARRAY) {
    7281            return new GetFloatArrayDataRefTask(name, length, offset);
  • src/xplra/Makefile.am

    r6 r7  
    3030        TaskRequest.cc          \
    3131        DataRefTask.cc          \
    32         GetDataRefTask.cc
     32        GetDataRefTask.cc       \
     33        SetDataRefTask.cc
    3334
    3435libxplra_la_LIBADD=$(LIBXPLCOMMON_LIBS)
     
    4344        TaskRequest.h           \
    4445        DataRefTask.h           \
    45         GetDataRefTask.h
     46        GetDataRefTask.h        \
     47        SetDataRefTask.h
  • src/xplra/Protocol.h

    r6 r7  
    4545     */
    4646    static const uint8_t COMMAND_GET_SINGLE = 0x01;
     47
     48    /**
     49     * Command: set the value of a single dataref.
     50     */
     51    static const uint8_t COMMAND_SET_SINGLE = 0x02;
    4752
    4853    /**
     
    97102
    98103    /**
     104     * Result code: invalid length
     105     */
     106    static const uint8_t RESULT_INVALID_LENGTH = 0x04;
     107
     108    /**
     109     * Result code: invalid offset
     110     */
     111    static const uint8_t RESULT_INVALID_OFFSET = 0x05;
     112
     113    /**
    99114     * Result code: other error
    100115     */
    101116    static const uint8_t RESULT_OTHER_ERROR = 0xff;
     117
     118    /**
     119     * The maximal length we accept (in order to protect ourselves).
     120     */
     121    static const int MAX_LENGTH = 2048;
    102122};
    103123
  • src/xplra/ServerThread.cc

    r6 r7  
    3434#include "Protocol.h"
    3535#include "GetDataRefTask.h"
     36#include "SetDataRefTask.h"
    3637#include "TaskRequest.h"
    3738
     
    111112
    112113        if (command==Protocol::COMMAND_GET_SINGLE) {
    113             if (!handleGetSingle(stream)) break;
     114            if (!handleGetSingle()) break;
     115        } else if (command==Protocol::COMMAND_SET_SINGLE) {
     116            if (!handleSetSingle()) break;
    114117        } else {
    115118            stream.writeU8(Protocol::RESULT_INVALID_COMMAND);
     
    123126//------------------------------------------------------------------------------
    124127
    125 bool ServerThread::handleGetSingle(xplcommon::DataStream& stream)
     128bool ServerThread::handleGetSingle()
    126129{
    127130    uint8_t result = Protocol::RESULT_OK;
    128 
    129131    GetDataRefTask* task = GetDataRefTask::create(result, stream);
    130132
    131133    if (!stream) return false;
    132134    else if (task==0) {
    133         stream.writeU8(Protocol::RESULT_INVALID_TYPE);
     135        stream.writeU8(result);
    134136        return true;
    135137    }
     
    150152//------------------------------------------------------------------------------
    151153
     154bool ServerThread::handleSetSingle()
     155{
     156    uint8_t result = Protocol::RESULT_OK;
     157    SetDataRefTask* task = SetDataRefTask::create(result, stream);
     158
     159    if (!stream) return false;
     160    else if (task==0) {
     161        stream.writeU8(result);
     162        return true;
     163    }
     164
     165    TaskRequest request(task);
     166    if (!requestQueue.execute(&request)) return false;
     167
     168    stream.writeU8(task->isValid() ? Protocol::RESULT_OK :
     169                   Protocol::RESULT_UNKNOWN_DATAREF);
     170    return true;
     171}
     172
     173//------------------------------------------------------------------------------
     174
    152175// Local Variables:
    153176// mode: C++
  • src/xplra/ServerThread.h

    r6 r7  
    129129     * @return true, if we can continue, false if the thread should quit
    130130     */
    131     bool handleGetSingle(xplcommon::DataStream& stream);
     131    bool handleGetSingle();
     132
     133    /**
     134     * Handle the COMMAND_SET_SINGLE command
     135     *
     136     * @return true, if we can continue, false if the thread should quit
     137     */
     138    bool handleSetSingle();
    132139};
    133140
Note: See TracChangeset for help on using the changeset viewer.