blob: c021d0e14792bee3794b2c317fd0a0c5119c915c [file] [log] [blame]
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * 卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
20 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
21 */
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080022
23#include "sync-state.h"
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080024#include "sync-diff-leaf.h"
25#include "sync-std-name-info.h"
26
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080027#include <boost/assert.hpp>
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080028#include <boost/foreach.hpp>
29#include <boost/shared_ptr.hpp>
30#include <boost/throw_exception.hpp>
31#include <boost/lexical_cast.hpp>
32
33#define TIXML_USE_STL
34#include <tinyxml.h>
35
36using namespace std;
37using namespace boost;
38
39typedef error_info<struct tag_errmsg, string> info_str;
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080040
Alexander Afanasyevc1030192012-03-08 22:21:28 -080041using namespace Sync::Error;
42
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080043namespace Sync {
44
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080045#ifdef _DEBUG
46#define DEBUG_ENDL os << "\n";
47#else
48#define DEBUG_ENDL
49#endif
50
51std::ostream &
52operator << (std::ostream &os, const State &state)
53{
54 os << "<state>"; DEBUG_ENDL;
55
56 BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
57 {
58 shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
59 if (diffLeaf != 0)
60 {
61 os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
62 }
63 else
64 {
65 os << "<item>"; DEBUG_ENDL;
66 }
Alexander Afanasyeve4e2bf72012-03-12 12:44:54 -070067 os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -080068 if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
69 {
70 os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
71 }
72 os << "</item>"; DEBUG_ENDL;
73 }
74 os << "</state>";
75}
76
77std::istream &
78operator >> (std::istream &in, State &state)
79{
80 TiXmlDocument doc;
81 in >> doc;
82
83 if (doc.RootElement() == 0)
84 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
85
86 for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
87 iterator != 0;
88 iterator = iterator->NextSiblingElement("item"))
89 {
90 TiXmlElement *name = iterator->FirstChildElement ("name");
91 if (name == 0 || name->GetText() == 0)
92 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
93
94 NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
95
96 if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
97 {
98 TiXmlElement *seq = iterator->FirstChildElement ("seq");
99 if (seq == 0)
100 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
101
102 TiXmlElement *session = seq->FirstChildElement ("session");
103 TiXmlElement *seqno = seq->FirstChildElement ("seqno");
104
105 if (session == 0 || session->GetText() == 0)
106 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
107 if (seqno == 0 || seqno->GetText() == 0)
108 BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
109
110 state.update (info, SeqNo (
111 lexical_cast<uint32_t> (session->GetText()),
112 lexical_cast<uint32_t> (seqno->GetText())
113 ));
114 }
115 else
116 {
117 state.remove (info);
118 }
119 }
120
121 return in;
122}
123
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -0800124}