summaryrefslogtreecommitdiff
path: root/digital/ucoolib/ucoolib/arch/host/mex/mex_msg.hh
blob: d717f18b7bd10ad334e36ece895f9193e82e4b08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef ucoolib_arch_host_mex_mex_msg_hh
#define ucoolib_arch_host_mex_mex_msg_hh
// ucoolib - Microcontroller object oriented library. {{{
//
// Copyright (C) 2012 Nicolas Schodet
//
// APBTeam:
//        Web: http://apbteam.org/
//      Email: team AT apbteam DOT org
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// }}}
#include "ucoolib/common.hh"

#include "ucoolib/arch/host/mex/mex.hh"

#include <vector>

namespace ucoo {
namespace mex {

class MsgPusher;
class MsgPoper;
class MsgReader;
class MsgWriter;

/// Mex message.
///
/// Format used for payload push and pop:
///  - b: 8 bits.
///  - h: 16 bits.
///  - l: 32 bits.
/// Uppercase is used for unsigned.
class Msg
{
  public:
    /// New message with the given MTYPE.
    explicit Msg (mtype_t mtype);
    /// Read a new message.
    explicit Msg (MsgReader &reader);
    /// Write a message.
    void write (MsgWriter &writer);
    /// Add data to the message payload.  FMT string describes the provided
    /// data.  Return a pusher which will do the actual push, using the
    /// operator<<.
    MsgPusher push (const char *fmt);
    /// Add data to the message payload from a buffer.
    void push (const char *buffer, int size);
    /// Extract data from the message payload.  FMT string describes the
    /// requested data.  Return a poper which will do the actual pop, using
    /// the operator>>.
    MsgPoper pop (const char *fmt);
    /// Pop buffer of given size.  Data is kept valid as long as this object
    /// is alive.
    const char *pop (int size);
    /// Encapsulate a message in another one, adding header data.  Return a
    /// pusher which will do the actual header data push, using the
    /// operator<<.
    MsgPusher encapsulate (mtype_t mtype, const char *fmt);
    /// Decapsulate a message from payload.  The current payload becomes the
    /// full message.
    void decapsulate ();
    /// Get remaining length.
    int len () const;
    /// Get message type.
    mtype_t mtype () const { return mtype_; }
  private:
    /// Message payload, not including message type.
    std::vector<char> payload_;
    /// Unused space at head of payload.
    int head_skip_;
    /// Message type.
    mtype_t mtype_;
};

/// Helper used to push data to message.
class MsgPusher
{
  public:
    /// Push an integer.
    MsgPusher &operator<< (int32_t v);
    /// Push an unsigned integer, used when an int is not enough.
    MsgPusher &operator<< (uint32_t v);
  private:
    MsgPusher (std::vector<char>::iterator out, const char *fmt);
    void push (int64_t v);
  private:
    friend class Msg;
    std::vector<char>::iterator out_;
    const char *fmt_;
};

/// Helper used to pop data from message.
class MsgPoper
{
  public:
    /// Pop for each supported types.
    MsgPoper &operator>> (int32_t &v);
    MsgPoper &operator>> (uint32_t &v);
    MsgPoper &operator>> (int16_t &v);
    MsgPoper &operator>> (uint16_t &v);
    MsgPoper &operator>> (int8_t &v);
    MsgPoper &operator>> (uint8_t &v);
  private:
    MsgPoper (std::vector<char>::const_iterator in, const char *fmt);
    uint32_t pop_bytes (int bytes);
    int64_t pop (int bits, bool sign);
  private:
    friend class Msg;
    std::vector<char>::const_iterator in_;
    const char *fmt_;
};

/// Abstract Msg reader.
class MsgReader
{
  public:
    /// Get message size.
    virtual int size () = 0;
    /// Read message bytes to provided buffer.
    virtual void read (char *buf) = 0;
};

/// Abstract Msg writer.
class MsgWriter
{
  public:
    /// Write COUNT bytes from provided buffer.
    virtual void write (const char *buf, int count) = 0;
};

} // namespace mex
} // namespace ucoo

#endif // ucoolib_arch_host_mex_mex_msg_hh