blob: 21707d2db5d0fade6633b9737b8cd0a40c08ef4e [file] [log] [blame]
Qiuhan Ding0cfc1512015-02-17 17:44:11 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 *
5 * BSD license, See the LICENSE file for more information
6 *
7 * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
8 */
9
10#include "chat-message.hpp"
11
12namespace chronochat {
13
14BOOST_CONCEPT_ASSERT((ndn::WireEncodable<ChatMessage>));
15BOOST_CONCEPT_ASSERT((ndn::WireDecodable<ChatMessage>));
16
17ChatMessage::ChatMessage()
18{
19}
20
21ChatMessage::ChatMessage(const Block& chatMsgWire)
22{
23 this->wireDecode(chatMsgWire);
24}
25
26template<bool T>
27size_t
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070028ChatMessage::wireEncode(ndn::EncodingImpl<T>& encoder) const
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080029{
30 // ChatMessage := CHAT-MESSAGE-TYPE TLV-LENGTH
31 // Nick
32 // ChatroomName
33 // ChatMessageType
34 // ChatData
35 // Timestamp
36 //
37 // Nick := NICK-NAME-TYPE TLV-LENGTH
38 // String
39 //
40 // ChatroomName := CHATROOM-NAME-TYPE TLV-LENGTH
41 // String
42 //
43 // ChatMessageType := CHAT-MESSAGE-TYPE TLV-LENGTH
44 // nonNegativeInteger
45 //
46 // ChatData := CHAT-DATA-TYPE TLV-LENGTH
47 // String
48 //
49 // Timestamp := TIMESTAMP-TYPE TLV-LENGTH
50 // VarNumber
51 //
52 size_t totalLength = 0;
53
54 // Timestamp
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070055 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::Timestamp, m_timestamp);
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080056
57 // ChatData
58 if (m_msgType == CHAT) {
59 const uint8_t* dataWire = reinterpret_cast<const uint8_t*>(m_data.c_str());
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070060 totalLength += encoder.prependByteArrayBlock(tlv::ChatData, dataWire, m_data.length());
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080061 }
62
63 // ChatMessageType
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070064 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::ChatMessageType, m_msgType);
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080065
66 // ChatroomName
67 const uint8_t* chatroomWire = reinterpret_cast<const uint8_t*>(m_chatroomName.c_str());
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070068 totalLength += encoder.prependByteArrayBlock(tlv::ChatroomName, chatroomWire,
69 m_chatroomName.length());
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080070
71 // Nick
72 const uint8_t* nickWire = reinterpret_cast<const uint8_t*>(m_nick.c_str());
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070073 totalLength += encoder.prependByteArrayBlock(tlv::Nick, nickWire, m_nick.length());
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080074
75 // Chat Message
Alexander Afanasyev28eb9092015-06-29 20:15:11 -070076 totalLength += encoder.prependVarNumber(totalLength);
77 totalLength += encoder.prependVarNumber(tlv::ChatMessage);
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080078
79 return totalLength;
80}
81
82const Block&
83ChatMessage::wireEncode() const
84{
85 ndn::EncodingEstimator estimator;
86 size_t estimatedSize = wireEncode(estimator);
87
88 ndn::EncodingBuffer buffer(estimatedSize, 0);
89 wireEncode(buffer);
90
91 m_wire = buffer.block();
92 m_wire.parse();
93
94 return m_wire;
95}
96
97void
98ChatMessage::wireDecode(const Block& chatMsgWire)
99{
100 m_wire = chatMsgWire;
101 m_wire.parse();
102
103 if (m_wire.type() != tlv::ChatMessage)
104 throw Error("Unexpected TLV number when decoding chat message packet");
105
106 Block::element_const_iterator i = m_wire.elements_begin();
107 if (i == m_wire.elements_end() || i->type() != tlv::Nick)
108 throw Error("Expect Nick but get ...");
109 m_nick = std::string(reinterpret_cast<const char* >(i->value()),
110 i->value_size());;
111 i++;
112
113 if (i == m_wire.elements_end() || i->type() != tlv::ChatroomName)
114 throw Error("Expect Chatroom Name but get ...");
115 m_chatroomName = std::string(reinterpret_cast<const char* >(i->value()),
116 i->value_size());;
117 i++;
118
119 if (i == m_wire.elements_end() || i->type() != tlv::ChatMessageType)
120 throw Error("Expect Chat Message Type but get ...");
121 m_msgType = static_cast<ChatMessageType>(readNonNegativeInteger(*i));
122 i++;
123
124 if (m_msgType != CHAT)
125 m_data = "";
126 else {
127 if (i == m_wire.elements_end() || i->type() != tlv::ChatData)
128 throw Error("Expect Chat Data but get ...");
129 m_data = std::string(reinterpret_cast<const char* >(i->value()),
130 i->value_size());;
131 i++;
132 }
133
134 if (i == m_wire.elements_end() || i->type() != tlv::Timestamp)
135 throw Error("Expect Timestamp but get ...");
136 m_timestamp = static_cast<time_t>(readNonNegativeInteger(*i));
137 i++;
138
139 if (i != m_wire.elements_end()) {
140 throw Error("Unexpected element");
141 }
142
143}
144
145void
146ChatMessage::setNick(const std::string& nick)
147{
148 m_wire.reset();
149 m_nick = nick;
150}
151
152void
153ChatMessage::setChatroomName(const std::string& chatroomName)
154{
155 m_wire.reset();
156 m_chatroomName = chatroomName;
157}
158
159void
160ChatMessage::setMsgType(const ChatMessageType msgType)
161{
162 m_wire.reset();
163 m_msgType = msgType;
164}
165
166void
167ChatMessage::setData(const std::string& data)
168{
169 m_wire.reset();
170 m_data = data;
171}
172
173void
174ChatMessage::setTimestamp(const time_t timestamp)
175{
176 m_wire.reset();
177 m_timestamp = timestamp;
178}
179
180}// namespace chronochat