version 0.2.11
[fms.git] / src / freenet / messagexml.cpp
1 #include "../../include/freenet/messagexml.h"\r
2 \r
3 #ifdef XMEM\r
4         #include <xmem.h>\r
5 #endif\r
6 \r
7 MessageXML::MessageXML()\r
8 {\r
9         Initialize();\r
10 }\r
11 \r
12 std::string MessageXML::GetXML()\r
13 {\r
14         TiXmlDocument td;\r
15         TiXmlDeclaration *tdec=new TiXmlDeclaration("1.0","UTF-8","");\r
16         TiXmlElement *tid;\r
17         TiXmlPrinter tp;\r
18 \r
19         td.LinkEndChild(tdec);\r
20         tid=new TiXmlElement("Message");\r
21         td.LinkEndChild(tid);\r
22 \r
23         tid->LinkEndChild(XMLCreateTextElement("Date",m_date));\r
24         tid->LinkEndChild(XMLCreateTextElement("Time",m_time));\r
25         tid->LinkEndChild(XMLCreateCDATAElement("Subject",m_subject));\r
26         tid->LinkEndChild(XMLCreateCDATAElement("MessageID",m_messageid));\r
27         tid->LinkEndChild(XMLCreateCDATAElement("ReplyBoard",m_replyboard));\r
28         // a little hack because TinyXML doesn't handle ]]> inside a CDATA section - manually separate into multiple CDATA sections\r
29         // TinyXML still won't be able to parse past the 1st CDATA section, but other implementations might\r
30         tid->LinkEndChild(XMLCreateCDATAElement("Body",StringFunctions::Replace(m_body,"]]>","]]]]><![CDATA[>")));\r
31 \r
32         TiXmlElement *brds=new TiXmlElement("Boards");\r
33         tid->LinkEndChild(brds);\r
34         for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
35         {\r
36                 std::string boardname=(*i);\r
37                 StringFunctions::Convert(boardname,boardname);\r
38                 brds->LinkEndChild(XMLCreateCDATAElement("Board",boardname));\r
39         }\r
40 \r
41         if(m_inreplyto.size()>0)\r
42         {\r
43                 TiXmlElement *rply=new TiXmlElement("InReplyTo");\r
44                 tid->LinkEndChild(rply);\r
45                 for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
46                 {\r
47                         TiXmlElement *mess=new TiXmlElement("Message");\r
48                         rply->LinkEndChild(mess);\r
49                         mess->LinkEndChild(XMLCreateTextElement("Order",(*j).first));\r
50                         mess->LinkEndChild(XMLCreateCDATAElement("MessageID",(*j).second));\r
51                 }\r
52         }\r
53 \r
54         // add attachemnt node if we have attachments\r
55         if(m_fileattachments.size()>0)\r
56         {\r
57                 TiXmlElement *attachments=new TiXmlElement("Attachments");\r
58                 tid->LinkEndChild(attachments);\r
59                 for(std::vector<fileattachment>::iterator j=m_fileattachments.begin(); j!=m_fileattachments.end(); j++)\r
60                 {\r
61                         TiXmlElement *f=new TiXmlElement("File");\r
62                         attachments->LinkEndChild(f);\r
63                         f->LinkEndChild(XMLCreateCDATAElement("Key",(*j).m_key));\r
64                         f->LinkEndChild(XMLCreateTextElement("Size",(*j).m_size));\r
65                 }\r
66         }\r
67 \r
68         td.Accept(&tp);\r
69         return std::string(tp.CStr());\r
70 }\r
71 \r
72 void MessageXML::Initialize()\r
73 {\r
74         m_date="";\r
75         m_time="";\r
76         m_subject="";\r
77         m_boards.clear();\r
78         m_replyboard="";\r
79         m_inreplyto.clear();\r
80         m_body="";\r
81         m_fileattachments.clear();\r
82 }\r
83 \r
84 const bool MessageXML::ParseXML(const std::string &xml)\r
85 {\r
86         TiXmlDocument td;\r
87         td.Parse(xml.c_str());\r
88 \r
89         if(!td.Error())\r
90         {\r
91                 TiXmlHandle hnd(&td);\r
92                 TiXmlNode *node2;\r
93                 TiXmlText *txt;\r
94 \r
95                 Initialize();\r
96 \r
97                 txt=hnd.FirstChild("Message").FirstChild("Date").FirstChild().ToText();\r
98                 if(txt)\r
99                 {\r
100                         m_date=txt->ValueStr();\r
101                 }\r
102                 txt=hnd.FirstChild("Message").FirstChild("Time").FirstChild().ToText();\r
103                 if(txt)\r
104                 {\r
105                         m_time=txt->ValueStr();\r
106                 }\r
107                 txt=hnd.FirstChild("Message").FirstChild("Subject").FirstChild().ToText();\r
108                 if(txt)\r
109                 {\r
110                         m_subject=txt->ValueStr();\r
111                 }\r
112                 txt=hnd.FirstChild("Message").FirstChild("MessageID").FirstChild().ToText();\r
113                 if(txt)\r
114                 {\r
115                         m_messageid=txt->ValueStr();\r
116                 }\r
117                 txt=hnd.FirstChild("Message").FirstChild("ReplyBoard").FirstChild().ToText();\r
118                 if(txt)\r
119                 {\r
120                         m_replyboard=txt->ValueStr();\r
121                         StringFunctions::LowerCase(m_replyboard,m_replyboard);\r
122                         if(m_replyboard.size()>40)\r
123                         {\r
124                                 m_replyboard.erase(40);\r
125                         }\r
126                 }\r
127                 txt=hnd.FirstChild("Message").FirstChild("Body").FirstChild().ToText();\r
128                 if(txt)\r
129                 {\r
130                         m_body=txt->ValueStr();\r
131                 }\r
132 \r
133                 node2=hnd.FirstChild("Message").FirstChild("Boards").FirstChild("Board").ToNode();\r
134                 while(node2)\r
135                 {\r
136                         if(node2->FirstChild())\r
137                         {\r
138                                 std::string boardname=node2->FirstChild()->ValueStr();\r
139                                 StringFunctions::LowerCase(boardname,boardname);\r
140                                 if(boardname.size()>40)\r
141                                 {\r
142                                         boardname.erase(40);\r
143                                 }\r
144                                 m_boards.push_back(boardname);\r
145                         }\r
146                         node2=node2->NextSibling("Board");\r
147                 }\r
148 \r
149                 node2=hnd.FirstChild("Message").FirstChild("InReplyTo").FirstChild("Message").ToNode();\r
150                 while(node2)\r
151                 {\r
152                         std::string orderstr;\r
153                         long order=-1;\r
154                         std::string messageid="";\r
155                         TiXmlHandle hnd2(node2);\r
156                         txt=hnd2.FirstChild("Order").FirstChild().ToText();\r
157                         if(txt)\r
158                         {\r
159                                 orderstr=txt->ValueStr();\r
160                                 StringFunctions::Convert(orderstr,order);\r
161                         }\r
162                         txt=hnd2.FirstChild("MessageID").FirstChild().ToText();\r
163                         if(txt)\r
164                         {\r
165                                 messageid=txt->ValueStr();\r
166                         }\r
167 \r
168                         if(order!=-1 && messageid!="")\r
169                         {\r
170                                 m_inreplyto[order]=messageid;\r
171                         }\r
172 \r
173                         node2=node2->NextSibling("Message");\r
174                 }\r
175 \r
176                 node2=hnd.FirstChild("Message").FirstChild("Attachments").FirstChild("File").ToNode();\r
177                 while(node2)\r
178                 {\r
179                         std::string key="";\r
180                         std::string sizestr="-1";\r
181                         int size=-1;\r
182 \r
183                         TiXmlHandle hnd2(node2);\r
184 \r
185                         txt=hnd2.FirstChild("Key").FirstChild().ToText();\r
186                         if(txt)\r
187                         {\r
188                                 key=txt->ValueStr();\r
189                         }\r
190 \r
191                         txt=hnd2.FirstChild("Size").FirstChild().ToText();\r
192                         if(txt)\r
193                         {\r
194                                 sizestr=txt->ValueStr();\r
195                                 StringFunctions::Convert(sizestr,size);\r
196                         }\r
197 \r
198                         if(key!="" && size>0)\r
199                         {\r
200                                 m_fileattachments.push_back(fileattachment(key,size));\r
201                         }\r
202 \r
203                         node2=node2->NextSibling("File");\r
204                 }\r
205 \r
206                 return true;\r
207         }\r
208         else\r
209         {\r
210                 return false;\r
211         }\r
212 }\r