1 // Copyright (c) 2015-2017 Josh Blum
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #pragma once
5 #include "SoapyRemoteConfig.hpp"
6 #include <SoapySDR/Types.hpp>
7 #include <vector>
8 #include <complex>
9 #include <string>
10 
11 class SoapyRPCSocket;
12 
13 /*!
14  * The unpacker object receives a complete RPC message,
15  * and unpacks the message into primitive Soapy SDR types.
16  */
17 class SOAPY_REMOTE_API SoapyRPCUnpacker
18 {
19 public:
20     SoapyRPCUnpacker(SoapyRPCSocket &sock, const bool autoRecv = true, const long timeoutUs = 30000000);
21 
22     ~SoapyRPCUnpacker(void);
23 
24     //! Receive a complete RPC message
25     void recv(void);
26 
27     //! Unpack a binary blob of known size
28     void unpack(void *buff, const size_t length);
29 
30     //! Copy-less version of unpack
31     void *unpack(const size_t length);
32 
33     //! Unpack a single byte
unpack(void)34     char unpack(void)
35     {
36         char byte = _message[_offset];
37         _offset++;
38         return byte;
39     }
40 
41     //! Done when no data is left to unpack
42     bool done(void) const;
43 
44     //! View the next type without consuming
peekType(void) const45     SoapyRemoteTypes peekType(void) const
46     {
47         return SoapyRemoteTypes(_message[_offset]);
48     }
49 
50     //! Unpack the call
51     void operator&(SoapyRemoteCalls &value);
52 
53     //! Unpack the type
operator &(SoapyRemoteTypes & value)54     void operator&(SoapyRemoteTypes &value)
55     {
56         value = SoapyRemoteTypes(this->unpack());
57     }
58 
59     //! Unpack a character
60     void operator&(char &value);
61 
62     //! Unpack a boolean
63     void operator&(bool &value);
64 
65     //! Unpack a 32-bit integer
66     void operator&(int &value);
67 
68     //! Unpack a 64-bit integer
69     void operator&(long long &value);
70 
71     //! Unpack a double float
72     void operator&(double &value);
73 
74     //! Unpack a complex double float
75     void operator&(std::complex<double> &value);
76 
77     //! Unpack a string
78     void operator&(std::string &value);
79 
80     //! Unpack a range
81     void operator&(SoapySDR::Range &value);
82 
83     //! Unpack a list of ranges
84     void operator&(SoapySDR::RangeList &value);
85 
86     //! Unpack a list of strings
87     void operator&(std::vector<std::string> &value);
88 
89     //! Unpack a list of double floats
90     void operator&(std::vector<double> &value);
91 
92     //! Unpack a kwargs dictionary
93     void operator&(SoapySDR::Kwargs &value);
94 
95     //! Unpack a list of kwargs
96     void operator&(SoapySDR::KwargsList &value);
97 
98     //! Unpack a list of sizes
99     void operator&(std::vector<size_t> &value);
100 
101     //! Unpack an arg info structure
102     void operator&(SoapySDR::ArgInfo &value);
103 
104     //! Unpack a list of arg infos
105     void operator&(SoapySDR::ArgInfoList &value);
106 
107     //! Get the received RPC version number
remoteRPCVersion(void) const108     unsigned int remoteRPCVersion(void) const
109     {
110         return _remoteRPCVersion;
111     }
112 
113 private:
114 
115     void ensureSpace(const size_t length);
116 
117     SoapyRPCSocket &_sock;
118     char *_message;
119     size_t _offset;
120     size_t _capacity;
121     unsigned int _remoteRPCVersion;
122 };
123