blob: efb53c77e7b49aff1622eb544038972ca06e4da0 [file] [log] [blame]
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Alexander Afanasyev8722d872014-07-02 13:00:29 -07003 * Copyright (c) 2012-2014 University of California, Los Angeles
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -08004 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07005 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -08007 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07008 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080011 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070012 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080015 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070016 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
20 * @author Chaoyi Bian <bcy@pku.edu.cn>
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080022 */
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080023
24#include "sync-state.h"
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080025#include "sync-diff-leaf.h"
26#include "sync-std-name-info.h"
27
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080028#include <boost/assert.hpp>
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080029#include <boost/foreach.hpp>
30#include <boost/shared_ptr.hpp>
31#include <boost/throw_exception.hpp>
32#include <boost/lexical_cast.hpp>
33
Alexander Afanasyevd95c2312013-11-07 13:45:34 -080034// using namespace std;
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080035using namespace boost;
36
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070037typedef error_info<struct tag_errmsg, std::string> info_str;
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080038
Alexander Afanasyevc1030192012-03-08 22:21:28 -080039using namespace Sync::Error;
40
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080041namespace Sync {
42
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070043/*
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080044std::ostream &
45operator << (std::ostream &os, const State &state)
46{
47 os << "<state>"; DEBUG_ENDL;
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070048
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080049 BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
50 {
51 shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
52 if (diffLeaf != 0)
53 {
54 os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
55 }
56 else
57 {
58 os << "<item>"; DEBUG_ENDL;
59 }
Alexander Afanasyeve4e2bf72012-03-12 12:44:54 -070060 os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080061 if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
62 {
63 os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
64 }
65 os << "</item>"; DEBUG_ENDL;
66 }
67 os << "</state>";
68}
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070069*/
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080070
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070071SyncStateMsg &
72operator << (SyncStateMsg &ossm, const State &state)
73{
74 BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
75 {
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -070076 SyncState *oss = ossm.add_ss();
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070077 shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -070078 if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070079 {
80 oss->set_type(SyncState::DELETE);
81 }
82 else
83 {
84 oss->set_type(SyncState::UPDATE);
85 }
86
87 std::ostringstream os;
88 os << *leaf->getInfo();
89 oss->set_name(os.str());
90
91 if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
92 {
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -070093 SyncState::SeqNo *seqNo = oss->mutable_seqno();
94 seqNo->set_session(leaf->getSeq().getSession());
95 seqNo->set_seq(leaf->getSeq().getSeq());
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -070096 }
97 }
98 return ossm;
99}
100
101/*
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800102std::istream &
103operator >> (std::istream &in, State &state)
104{
105 TiXmlDocument doc;
106 in >> doc;
107
108 if (doc.RootElement() == 0)
109 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700110
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800111 for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
112 iterator != 0;
113 iterator = iterator->NextSiblingElement("item"))
114 {
115 TiXmlElement *name = iterator->FirstChildElement ("name");
116 if (name == 0 || name->GetText() == 0)
117 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700118
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800119 NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700120
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800121 if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
122 {
123 TiXmlElement *seq = iterator->FirstChildElement ("seq");
124 if (seq == 0)
125 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700126
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800127 TiXmlElement *session = seq->FirstChildElement ("session");
128 TiXmlElement *seqno = seq->FirstChildElement ("seqno");
129
130 if (session == 0 || session->GetText() == 0)
131 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
132 if (seqno == 0 || seqno->GetText() == 0)
133 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
134
135 state.update (info, SeqNo (
136 lexical_cast<uint32_t> (session->GetText()),
137 lexical_cast<uint32_t> (seqno->GetText())
138 ));
139 }
140 else
141 {
142 state.remove (info);
143 }
144 }
145
146 return in;
147}
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700148*/
149
150SyncStateMsg &
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -0700151operator >> (SyncStateMsg &issm, State &state)
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700152{
153 int n = issm.ss_size();
154 for (int i = 0; i < n; i++)
155 {
156 const SyncState &ss = issm.ss(i);
157 NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
158 if (ss.type() == SyncState::UPDATE)
159 {
Yingdi Yu280bb962014-01-30 09:52:43 -0800160 uint64_t session = lexical_cast<uint64_t>(ss.seqno().session());
161 uint64_t seq = lexical_cast<uint64_t>(ss.seqno().seq());
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -0700162 SeqNo seqNo(session, seq);
163 state.update(info, seqNo);
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700164 }
165 else
166 {
167 state.remove(info);
168 }
169 }
170 return issm;
171}
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800172
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -0800173}