blob: aa8efcc9d60cd9bfdeb8bbf9b6320d04ef332ef7 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Yingdi Yu
*
* BSD license, See the LICENSE file for more information
*
* Author: Mengjin Yan <jane.yan0129@gmail.com>
* Yingdi Yu <yingdi@cs.ucla.edu>
* Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#include "chatroom-info.hpp"
namespace chronochat {
BOOST_CONCEPT_ASSERT((ndn::WireEncodable<ChatroomInfo>));
BOOST_CONCEPT_ASSERT((ndn::WireDecodable<ChatroomInfo>));
ChatroomInfo::ChatroomInfo()
{
}
ChatroomInfo::ChatroomInfo(const Block& chatroomWire)
{
this->wireDecode(chatroomWire);
}
template<ndn::encoding::Tag T>
size_t
ChatroomInfo::wireEncode(ndn::EncodingImpl<T>& encoder) const
{
size_t totalLength = 0;
// ChatroomInfo := CHATROOM-INFO-TYPE TLV-LENGTH
// ChatroomName
// TrustModel
// ChatroomPrefix
// ManagerPrefix
// Participants
//
// ChatroomName := CHATROOM-NAME-TYPE TLV-LENGTH
// NameComponent
//
// TrustModel := TRUST-MODEL-TYPE TLV-LENGTH
// nonNegativeInteger
//
// ChatroomPrefix := CHATROOM-PREFIX-TYPE TLV-LENGTH
// Name
//
// ManagerPrefix := MANAGER-PREFIX-TYPE TLV-LENGTH
// Name
//
// Participants := PARTICIPANTS-TYPE TLV-LENGTH
// Name+
// Participants
size_t participantsLength = 0;
for (std::list<Name>::const_reverse_iterator it = m_participants.rbegin();
it != m_participants.rend(); ++it) {
participantsLength += it->wireEncode(encoder);
}
participantsLength += encoder.prependVarNumber(participantsLength);
participantsLength += encoder.prependVarNumber(tlv::Participants);
totalLength += participantsLength;
// Manager Prefix
size_t managerLength = m_manager.wireEncode(encoder);
totalLength += managerLength;
totalLength += encoder.prependVarNumber(managerLength);
totalLength += encoder.prependVarNumber(tlv::ManagerPrefix);
// Chatroom Sync Prefix
size_t chatroomSyncPrefixLength = m_syncPrefix.wireEncode(encoder);
totalLength += chatroomSyncPrefixLength;
totalLength += encoder.prependVarNumber(chatroomSyncPrefixLength);
totalLength += encoder.prependVarNumber(tlv::ChatroomPrefix);
// Trust Model
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::TrustModel, m_trustModel);
// Chatroom Name
size_t chatroomNameLength = m_chatroomName.wireEncode(encoder);
totalLength += chatroomNameLength;
totalLength += encoder.prependVarNumber(chatroomNameLength);
totalLength += encoder.prependVarNumber(tlv::ChatroomName);
// Chatroom Info
totalLength += encoder.prependVarNumber(totalLength);
totalLength += encoder.prependVarNumber(tlv::ChatroomInfo);
return totalLength;
}
const Block&
ChatroomInfo::wireEncode() const
{
ndn::EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
ndn::EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
m_wire.parse();
return m_wire;
}
void
ChatroomInfo::wireDecode(const Block& chatroomWire)
{
m_wire = chatroomWire;
m_wire.parse();
m_participants.clear();
// ChatroomInfo := CHATROOM-INFO-TYPE TLV-LENGTH
// ChatroomName
// TrustModel
// ChatroomPrefix
// ManagerPrefix
// Participants
//
// ChatroomName := CHATROOM-NAME-TYPE TLV-LENGTH
// NameComponent
//
// TrustModel := TRUST-MODEL-TYPE TLV-LENGTH
// nonNegativeInteger
//
// ChatroomPrefix := CHATROOM-PREFIX-TYPE TLV-LENGTH
// Name
//
// ManagerPrefix := MANAGER-PREFIX-TYPE TLV-LENGTH
// Name
//
// Participants := PARTICIPANTS-TYPE TLV-LENGTH
// Name+
if (m_wire.type() != tlv::ChatroomInfo)
throw Error("Unexpected TLV number when decoding chatroom packet");
// Chatroom Info
Block::element_const_iterator i = m_wire.elements_begin();
if (i == m_wire.elements_end())
throw Error("Missing Chatroom Name");
if (i->type() != tlv::ChatroomName)
throw Error("Expect Chatroom Name but get TLV Type " + std::to_string(i->type()));
m_chatroomName.wireDecode(i->blockFromValue());
++i;
// Trust Model
if (i == m_wire.elements_end())
throw Error("Missing Trust Model");
if (i->type() != tlv::TrustModel)
throw Error("Expect Trust Model but get TLV Type " + std::to_string(i->type()));
m_trustModel =
static_cast<TrustModel>(readNonNegativeInteger(*i));
++i;
// Chatroom Sync Prefix
if (i == m_wire.elements_end())
throw Error("Missing Chatroom Prefix");
if (i->type() != tlv::ChatroomPrefix)
throw Error("Expect Chatroom Prefix but get TLV Type " + std::to_string(i->type()));
m_syncPrefix.wireDecode(i->blockFromValue());
++i;
// Manager Prefix
if (i == m_wire.elements_end())
throw Error("Missing Manager Prefix");
if (i->type() != tlv::ManagerPrefix)
throw Error("Expect Manager Prefix but get TLV Type " + std::to_string(i->type()));
m_manager.wireDecode(i->blockFromValue());
++i;
// Participants
if (i == m_wire.elements_end())
throw Error("Missing Participant");
if (i->type() != tlv::Participants)
throw Error("Expect Participant but get TLV Type " + std::to_string(i->type()));
Block temp = *i;
temp.parse();
Block::element_const_iterator j = temp.elements_begin();
while (j != temp.elements_end() && j->type() == tlv::Name) {
m_participants.push_back(Name(*j));
++j;
}
if (j != temp.elements_end())
throw Error("Unexpected element");
if (m_participants.empty())
throw Error("No participant in the chatroom");
++i;
if (i != m_wire.elements_end()) {
throw Error("Unexpected element");
}
}
void
ChatroomInfo::setName(const Name::Component& name)
{
m_wire.reset();
m_chatroomName = name;
}
void
ChatroomInfo::setTrustModel(const TrustModel trustModel)
{
m_wire.reset();
m_trustModel = trustModel;
}
void
ChatroomInfo::addParticipant(const Name& participant)
{
m_wire.reset();
if (find(m_participants.begin(), m_participants.end(), participant) ==
m_participants.end()) {
m_participants.push_back(participant);
}
}
void
ChatroomInfo::removeParticipant(const Name& participant)
{
m_wire.reset();
m_participants.remove(participant);
}
void
ChatroomInfo::setSyncPrefix(const Name& prefix)
{
m_wire.reset();
m_syncPrefix = prefix;
}
void
ChatroomInfo::setManager(const Name& manager)
{
m_wire.reset();
m_manager = manager;
}
} // namespace chronochat