version 0.3.0
[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         Poco::AutoPtr<Poco::XML::Document> doc=new Poco::XML::Document;\r
15         //TiXmlDocument td;\r
16         //TiXmlDeclaration *tdec=new TiXmlDeclaration("1.0","UTF-8","");\r
17         Poco::XML::Element *root=doc->createElement("Message");\r
18         //TiXmlElement *tid;\r
19         //TiXmlPrinter tp;\r
20 \r
21         doc->appendChild(root);\r
22         //td.LinkEndChild(tdec);\r
23         //tid=new TiXmlElement("Message");\r
24         //td.LinkEndChild(tid);\r
25 \r
26         root->appendChild(XMLCreateTextElement(doc,"Date",m_date));\r
27         root->appendChild(XMLCreateTextElement(doc,"Time",m_time));\r
28         root->appendChild(XMLCreateCDATAElement(doc,"Subject",m_subject));\r
29         root->appendChild(XMLCreateCDATAElement(doc,"MessageID",m_messageid));\r
30         root->appendChild(XMLCreateCDATAElement(doc,"ReplyBoard",m_replyboard));\r
31         /*\r
32         tid->LinkEndChild(XMLCreateTextElement("Date",m_date));\r
33         tid->LinkEndChild(XMLCreateTextElement("Time",m_time));\r
34         tid->LinkEndChild(XMLCreateCDATAElement("Subject",m_subject));\r
35         tid->LinkEndChild(XMLCreateCDATAElement("MessageID",m_messageid));\r
36         tid->LinkEndChild(XMLCreateCDATAElement("ReplyBoard",m_replyboard));\r
37         */\r
38         \r
39         root->appendChild(XMLCreateCDATAElement(doc,"Body",m_body));\r
40         // a little hack because TinyXML doesn't handle ]]> inside a CDATA section - manually separate into multiple CDATA sections\r
41         // TinyXML still won't be able to parse past the 1st CDATA section, but other implementations might\r
42         //tid->LinkEndChild(XMLCreateCDATAElement("Body",StringFunctions::Replace(m_body,"]]>","]]]]><![CDATA[>")));\r
43 \r
44         Poco::XML::Element *brds=doc->createElement("Boards");\r
45         //TiXmlElement *brds=new TiXmlElement("Boards");\r
46         root->appendChild(brds);\r
47         //tid->LinkEndChild(brds);\r
48         for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
49         {\r
50                 std::string boardname=(*i);\r
51                 StringFunctions::Convert(boardname,boardname);\r
52                 brds->appendChild(XMLCreateCDATAElement(doc,"Board",boardname));\r
53                 //brds->LinkEndChild(XMLCreateCDATAElement("Board",boardname));\r
54         }\r
55 \r
56         if(m_inreplyto.size()>0)\r
57         {\r
58                 Poco::XML::Element *rply=doc->createElement("InReplyTo");\r
59                 //TiXmlElement *rply=new TiXmlElement("InReplyTo");\r
60                 root->appendChild(rply);\r
61                 //tid->LinkEndChild(rply);\r
62                 for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
63                 {\r
64                         Poco::XML::Element *mess=doc->createElement("Message");\r
65                         //TiXmlElement *mess=new TiXmlElement("Message");\r
66                         rply->appendChild(mess);\r
67                         mess->appendChild(XMLCreateTextElement(doc,"Order",(*j).first));\r
68                         mess->appendChild(XMLCreateCDATAElement(doc,"MessageID",(*j).second));\r
69                         //mess->LinkEndChild(XMLCreateTextElement("Order",(*j).first));\r
70                         //mess->LinkEndChild(XMLCreateCDATAElement("MessageID",(*j).second));\r
71                 }\r
72         }\r
73 \r
74         // add attachemnt node if we have attachments\r
75         if(m_fileattachments.size()>0)\r
76         {\r
77                 Poco::XML::Element *attachments=doc->createElement("Attachments");\r
78                 //TiXmlElement *attachments=new TiXmlElement("Attachments");\r
79                 root->appendChild(attachments);\r
80                 //tid->LinkEndChild(attachments);\r
81                 for(std::vector<fileattachment>::iterator j=m_fileattachments.begin(); j!=m_fileattachments.end(); j++)\r
82                 {\r
83                         Poco::XML::Element *f=doc->createElement("File");\r
84                         //TiXmlElement *f=new TiXmlElement("File");\r
85                         attachments->appendChild(f);\r
86                         //attachments->LinkEndChild(f);\r
87                         f->appendChild(XMLCreateCDATAElement(doc,"Key",(*j).m_key));\r
88                         f->appendChild(XMLCreateTextElement(doc,"Size",(*j).m_size));\r
89                         //f->LinkEndChild(XMLCreateCDATAElement("Key",(*j).m_key));\r
90                         //f->LinkEndChild(XMLCreateTextElement("Size",(*j).m_size));\r
91                 }\r
92         }\r
93 \r
94         //td.Accept(&tp);\r
95         //return std::string(tp.CStr());\r
96         return GenerateXML(doc);\r
97 }\r
98 \r
99 void MessageXML::Initialize()\r
100 {\r
101         m_date="";\r
102         m_time="";\r
103         m_subject="";\r
104         m_boards.clear();\r
105         m_replyboard="";\r
106         m_inreplyto.clear();\r
107         m_body="";\r
108         m_fileattachments.clear();\r
109 }\r
110 \r
111 const bool MessageXML::ParseXML(const std::string &xml)\r
112 {\r
113         bool parsed=false;\r
114         Poco::XML::DOMParser dp;\r
115 \r
116         Initialize();\r
117 \r
118         try\r
119         {\r
120                 Poco::AutoPtr<Poco::XML::Document> doc=dp.parseString(FixCDATA(xml));\r
121                 Poco::XML::Element *root=XMLGetFirstChild(doc,"Message");\r
122                 Poco::XML::Element *txt=NULL;\r
123 \r
124                 txt=XMLGetFirstChild(root,"Date");\r
125                 if(txt)\r
126                 {\r
127                         if(txt->firstChild())\r
128                         {\r
129                                 m_date=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
130                         }\r
131                 }\r
132                 txt=XMLGetFirstChild(root,"Time");\r
133                 if(txt)\r
134                 {\r
135                         if(txt->firstChild())\r
136                         {\r
137                                 m_time=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
138                         }\r
139                 }\r
140                 txt=XMLGetFirstChild(root,"Subject");\r
141                 if(txt)\r
142                 {\r
143                         if(txt->firstChild())\r
144                         {\r
145                                 m_subject=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
146                         }\r
147                 }\r
148                 txt=XMLGetFirstChild(root,"MessageID");\r
149                 if(txt)\r
150                 {\r
151                         if(txt->firstChild())\r
152                         {\r
153                                 m_messageid=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
154                         }\r
155                 }\r
156                 txt=XMLGetFirstChild(root,"ReplyBoard");\r
157                 if(txt)\r
158                 {\r
159                         if(txt->firstChild())\r
160                         {\r
161                                 m_replyboard=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
162                                 StringFunctions::LowerCase(m_replyboard,m_replyboard);\r
163                                 if(m_replyboard.size()>40)\r
164                                 {\r
165                                         m_replyboard.erase(40);\r
166                                 }\r
167                         }\r
168                 }\r
169                 txt=XMLGetFirstChild(root,"Body");\r
170                 if(txt)\r
171                 {\r
172                         if(txt->firstChild())\r
173                         {\r
174                                 m_body=txt->firstChild()->getNodeValue();\r
175                         }\r
176                 }\r
177                 Poco::XML::Element *boards=XMLGetFirstChild(root,"Boards");\r
178                 if(boards)\r
179                 {\r
180                         Poco::XML::Element *board=XMLGetFirstChild(boards,"Board");\r
181                         while(board)\r
182                         {\r
183                                 if(board->firstChild())\r
184                                 {\r
185                                         std::string boardname=SanitizeSingleString(board->firstChild()->getNodeValue());\r
186                                         StringFunctions::LowerCase(boardname,boardname);\r
187                                         if(boardname.size()>40)\r
188                                         {\r
189                                                 boardname.erase(40);\r
190                                         }\r
191                                         m_boards.push_back(boardname);\r
192                                 }\r
193                                 board=XMLGetNextSibling(board,"Board");\r
194                         }\r
195                 }\r
196                 Poco::XML::Element *inreplyto=XMLGetFirstChild(root,"InReplyTo");\r
197                 if(inreplyto)\r
198                 {\r
199                         Poco::XML::Element *message=XMLGetFirstChild(inreplyto,"Message");\r
200                         while(message)\r
201                         {\r
202                                 Poco::XML::Element *orderel=XMLGetFirstChild(message,"Order");\r
203                                 Poco::XML::Element *messageidel=XMLGetFirstChild(message,"MessageID");\r
204                                 if(orderel && orderel->firstChild() && messageidel && messageidel->firstChild())\r
205                                 {\r
206                                         int order=-1;\r
207                                         std::string messageid="";\r
208 \r
209                                         StringFunctions::Convert(orderel->firstChild()->getNodeValue(),order);\r
210                                         messageid=messageidel->firstChild()->getNodeValue();\r
211 \r
212                                         if(order!=-1 && messageid!="")\r
213                                         {\r
214                                                 m_inreplyto[order]=messageid;\r
215                                         }\r
216                                 }\r
217                                 message=XMLGetNextSibling(message,"Message");\r
218                         }\r
219                 }\r
220                 Poco::XML::Element *attachments=XMLGetFirstChild(root,"Attachments");\r
221                 if(attachments)\r
222                 {\r
223                         Poco::XML::Element *file=XMLGetFirstChild(attachments,"File");\r
224                         while(file)\r
225                         {\r
226                                 Poco::XML::Element *keyel=XMLGetFirstChild(file,"Key");\r
227                                 Poco::XML::Element *sizeel=XMLGetFirstChild(file,"Size");\r
228 \r
229                                 if(keyel && keyel->firstChild() && sizeel && sizeel->firstChild())\r
230                                 {\r
231                                         int size=-1;\r
232                                         std::string key="";\r
233                                         \r
234                                         StringFunctions::Convert(sizeel->firstChild()->getNodeValue(),size);\r
235                                         key=keyel->firstChild()->getNodeValue();\r
236 \r
237                                         if(size!=-1 && key!="")\r
238                                         {\r
239                                                 m_fileattachments.push_back(fileattachment(key,size));\r
240                                         }\r
241                                 }\r
242 \r
243                                 file=XMLGetNextSibling(file,"File");\r
244                         }\r
245                 }\r
246 \r
247                 parsed=true;\r
248 \r
249         }\r
250         catch(...)\r
251         {\r
252         }\r
253 \r
254         return parsed;\r
255 \r
256 /*\r
257         TiXmlDocument td;\r
258         td.Parse(xml.c_str());\r
259 \r
260         if(!td.Error())\r
261         {\r
262                 TiXmlHandle hnd(&td);\r
263                 TiXmlNode *node2;\r
264                 TiXmlText *txt;\r
265 \r
266                 Initialize();\r
267 \r
268                 txt=hnd.FirstChild("Message").FirstChild("Date").FirstChild().ToText();\r
269                 if(txt)\r
270                 {\r
271                         m_date=SanitizeSingleString(txt->ValueStr());\r
272                 }\r
273                 txt=hnd.FirstChild("Message").FirstChild("Time").FirstChild().ToText();\r
274                 if(txt)\r
275                 {\r
276                         m_time=SanitizeSingleString(txt->ValueStr());\r
277                 }\r
278                 txt=hnd.FirstChild("Message").FirstChild("Subject").FirstChild().ToText();\r
279                 if(txt)\r
280                 {\r
281                         m_subject=SanitizeSingleString(txt->ValueStr());\r
282                 }\r
283                 txt=hnd.FirstChild("Message").FirstChild("MessageID").FirstChild().ToText();\r
284                 if(txt)\r
285                 {\r
286                         m_messageid=SanitizeSingleString(txt->ValueStr());\r
287                 }\r
288                 txt=hnd.FirstChild("Message").FirstChild("ReplyBoard").FirstChild().ToText();\r
289                 if(txt)\r
290                 {\r
291                         m_replyboard=SanitizeSingleString(txt->ValueStr());\r
292                         StringFunctions::LowerCase(m_replyboard,m_replyboard);\r
293                         if(m_replyboard.size()>40)\r
294                         {\r
295                                 m_replyboard.erase(40);\r
296                         }\r
297                 }\r
298                 txt=hnd.FirstChild("Message").FirstChild("Body").FirstChild().ToText();\r
299                 if(txt)\r
300                 {\r
301                         m_body=txt->ValueStr();\r
302                 }\r
303 \r
304                 node2=hnd.FirstChild("Message").FirstChild("Boards").FirstChild("Board").ToNode();\r
305                 while(node2)\r
306                 {\r
307                         if(node2->FirstChild())\r
308                         {\r
309                                 std::string boardname=SanitizeSingleString(node2->FirstChild()->ValueStr());\r
310                                 StringFunctions::LowerCase(boardname,boardname);\r
311                                 if(boardname.size()>40)\r
312                                 {\r
313                                         boardname.erase(40);\r
314                                 }\r
315                                 m_boards.push_back(boardname);\r
316                         }\r
317                         node2=node2->NextSibling("Board");\r
318                 }\r
319 \r
320                 node2=hnd.FirstChild("Message").FirstChild("InReplyTo").FirstChild("Message").ToNode();\r
321                 while(node2)\r
322                 {\r
323                         std::string orderstr;\r
324                         long order=-1;\r
325                         std::string messageid="";\r
326                         TiXmlHandle hnd2(node2);\r
327                         txt=hnd2.FirstChild("Order").FirstChild().ToText();\r
328                         if(txt)\r
329                         {\r
330                                 orderstr=SanitizeSingleString(txt->ValueStr());\r
331                                 StringFunctions::Convert(orderstr,order);\r
332                         }\r
333                         txt=hnd2.FirstChild("MessageID").FirstChild().ToText();\r
334                         if(txt)\r
335                         {\r
336                                 messageid=SanitizeSingleString(txt->ValueStr());\r
337                         }\r
338 \r
339                         if(order!=-1 && messageid!="")\r
340                         {\r
341                                 m_inreplyto[order]=messageid;\r
342                         }\r
343 \r
344                         node2=node2->NextSibling("Message");\r
345                 }\r
346 \r
347                 node2=hnd.FirstChild("Message").FirstChild("Attachments").FirstChild("File").ToNode();\r
348                 while(node2)\r
349                 {\r
350                         std::string key="";\r
351                         std::string sizestr="-1";\r
352                         int size=-1;\r
353 \r
354                         TiXmlHandle hnd2(node2);\r
355 \r
356                         txt=hnd2.FirstChild("Key").FirstChild().ToText();\r
357                         if(txt)\r
358                         {\r
359                                 key=SanitizeSingleString(txt->ValueStr());\r
360                         }\r
361 \r
362                         txt=hnd2.FirstChild("Size").FirstChild().ToText();\r
363                         if(txt)\r
364                         {\r
365                                 sizestr=SanitizeSingleString(txt->ValueStr());\r
366                                 StringFunctions::Convert(sizestr,size);\r
367                         }\r
368 \r
369                         if(key!="" && size>0)\r
370                         {\r
371                                 m_fileattachments.push_back(fileattachment(key,size));\r
372                         }\r
373 \r
374                         node2=node2->NextSibling("File");\r
375                 }\r
376 \r
377                 return true;\r
378         }\r
379         else\r
380         {\r
381                 return false;\r
382         }\r
383         */\r
384 }\r