version 0.3.31
[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         Poco::AutoPtr<Poco::XML::Element> root=doc->createElement("Message");\r
16 \r
17         doc->appendChild(root);\r
18 \r
19         root->appendChild(XMLCreateTextElement(doc,"Date",m_date));\r
20         root->appendChild(XMLCreateTextElement(doc,"Time",m_time));\r
21         root->appendChild(XMLCreateCDATAElement(doc,"Subject",m_subject));\r
22         root->appendChild(XMLCreateCDATAElement(doc,"MessageID",m_messageid));\r
23         root->appendChild(XMLCreateCDATAElement(doc,"ReplyBoard",m_replyboard));\r
24         \r
25         root->appendChild(XMLCreateCDATAElement(doc,"Body",m_body));\r
26 \r
27         Poco::AutoPtr<Poco::XML::Element> brds=doc->createElement("Boards");\r
28 \r
29         root->appendChild(brds);\r
30 \r
31         // attach boards\r
32         for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
33         {\r
34                 std::string boardname=(*i);\r
35                 StringFunctions::Convert(boardname,boardname);\r
36                 brds->appendChild(XMLCreateCDATAElement(doc,"Board",boardname));\r
37         }\r
38 \r
39         // attach inreplyto ids\r
40         if(m_inreplyto.size()>0)\r
41         {\r
42                 Poco::AutoPtr<Poco::XML::Element> rply=doc->createElement("InReplyTo");\r
43                 root->appendChild(rply);\r
44                 for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
45                 {\r
46                         Poco::AutoPtr<Poco::XML::Element> mess=doc->createElement("Message");\r
47                         rply->appendChild(mess);\r
48                         mess->appendChild(XMLCreateTextElement(doc,"Order",(*j).first));\r
49                         mess->appendChild(XMLCreateCDATAElement(doc,"MessageID",(*j).second));\r
50                 }\r
51         }\r
52 \r
53         // add attachemnt node if we have attachments\r
54         if(m_fileattachments.size()>0)\r
55         {\r
56                 Poco::AutoPtr<Poco::XML::Element> attachments=doc->createElement("Attachments");\r
57                 root->appendChild(attachments);\r
58                 for(std::vector<fileattachment>::iterator j=m_fileattachments.begin(); j!=m_fileattachments.end(); j++)\r
59                 {\r
60                         Poco::AutoPtr<Poco::XML::Element> f=doc->createElement("File");\r
61                         attachments->appendChild(f);\r
62                         f->appendChild(XMLCreateCDATAElement(doc,"Key",(*j).m_key));\r
63                         f->appendChild(XMLCreateTextElement(doc,"Size",(*j).m_size));\r
64                 }\r
65         }\r
66 \r
67         return GenerateXML(doc,false);\r
68 }\r
69 \r
70 void MessageXML::Initialize()\r
71 {\r
72         m_date="";\r
73         m_time="";\r
74         m_subject="";\r
75         m_boards.clear();\r
76         m_replyboard="";\r
77         m_inreplyto.clear();\r
78         m_body="";\r
79         m_fileattachments.clear();\r
80 }\r
81 \r
82 const bool MessageXML::ParseXML(const std::string &xml)\r
83 {\r
84         bool parsed=false;\r
85         Poco::XML::DOMParser dp;\r
86 \r
87         Initialize();\r
88 \r
89         try\r
90         {\r
91                 Poco::AutoPtr<Poco::XML::Document> doc=dp.parseString(FixCDATA(xml));\r
92                 Poco::XML::Element *root=XMLGetFirstChild(doc,"Message");\r
93                 Poco::XML::Element *txt=NULL;\r
94 \r
95                 txt=XMLGetFirstChild(root,"Date");\r
96                 if(txt)\r
97                 {\r
98                         if(txt->firstChild())\r
99                         {\r
100                                 m_date=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
101                         }\r
102                 }\r
103                 txt=XMLGetFirstChild(root,"Time");\r
104                 if(txt)\r
105                 {\r
106                         if(txt->firstChild())\r
107                         {\r
108                                 m_time=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
109                         }\r
110                 }\r
111                 txt=XMLGetFirstChild(root,"Subject");\r
112                 if(txt)\r
113                 {\r
114                         if(txt->firstChild())\r
115                         {\r
116                                 m_subject=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
117                         }\r
118                 }\r
119                 txt=XMLGetFirstChild(root,"MessageID");\r
120                 if(txt)\r
121                 {\r
122                         if(txt->firstChild())\r
123                         {\r
124                                 m_messageid=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
125                         }\r
126                 }\r
127                 txt=XMLGetFirstChild(root,"ReplyBoard");\r
128                 if(txt)\r
129                 {\r
130                         if(txt->firstChild())\r
131                         {\r
132                                 m_replyboard=SanitizeSingleString(txt->firstChild()->getNodeValue());\r
133                                 StringFunctions::LowerCase(m_replyboard,m_replyboard);\r
134                                 // strip off everything after , in board name\r
135                                 if(m_replyboard.find(",")!=std::string::npos)\r
136                                 {\r
137                                         m_replyboard.erase(m_replyboard.find(","));\r
138                                 }\r
139                                 if(m_replyboard.size()>40)\r
140                                 {\r
141                                         m_replyboard.erase(40);\r
142                                 }\r
143                         }\r
144                 }\r
145                 txt=XMLGetFirstChild(root,"Body");\r
146                 if(txt)\r
147                 {\r
148                         if(txt->firstChild())\r
149                         {\r
150                                 m_body=txt->firstChild()->getNodeValue();\r
151                         }\r
152                 }\r
153                 Poco::XML::Element *boards=XMLGetFirstChild(root,"Boards");\r
154                 if(boards)\r
155                 {\r
156                         Poco::XML::Element *board=XMLGetFirstChild(boards,"Board");\r
157                         while(board)\r
158                         {\r
159                                 if(board->firstChild())\r
160                                 {\r
161                                         std::string boardname=SanitizeSingleString(board->firstChild()->getNodeValue());\r
162                                         StringFunctions::LowerCase(boardname,boardname);\r
163                                         // strip off everything after , in board name\r
164                                         if(boardname.find(",")!=std::string::npos)\r
165                                         {\r
166                                                 boardname.erase(boardname.find(","));\r
167                                         }\r
168                                         if(boardname.size()>40)\r
169                                         {\r
170                                                 boardname.erase(40);\r
171                                         }\r
172                                         m_boards.push_back(boardname);\r
173                                 }\r
174                                 board=XMLGetNextSibling(board,"Board");\r
175                         }\r
176                 }\r
177                 Poco::XML::Element *inreplyto=XMLGetFirstChild(root,"InReplyTo");\r
178                 if(inreplyto)\r
179                 {\r
180                         Poco::XML::Element *message=XMLGetFirstChild(inreplyto,"Message");\r
181                         while(message)\r
182                         {\r
183                                 Poco::XML::Element *orderel=XMLGetFirstChild(message,"Order");\r
184                                 Poco::XML::Element *messageidel=XMLGetFirstChild(message,"MessageID");\r
185                                 if(orderel && orderel->firstChild() && messageidel && messageidel->firstChild())\r
186                                 {\r
187                                         int order=-1;\r
188                                         std::string messageid="";\r
189 \r
190                                         StringFunctions::Convert(orderel->firstChild()->getNodeValue(),order);\r
191                                         messageid=messageidel->firstChild()->getNodeValue();\r
192 \r
193                                         if(order!=-1 && messageid!="")\r
194                                         {\r
195                                                 m_inreplyto[order]=messageid;\r
196                                         }\r
197                                 }\r
198                                 message=XMLGetNextSibling(message,"Message");\r
199                         }\r
200                 }\r
201                 Poco::XML::Element *attachments=XMLGetFirstChild(root,"Attachments");\r
202                 if(attachments)\r
203                 {\r
204                         Poco::XML::Element *file=XMLGetFirstChild(attachments,"File");\r
205                         while(file)\r
206                         {\r
207                                 Poco::XML::Element *keyel=XMLGetFirstChild(file,"Key");\r
208                                 Poco::XML::Element *sizeel=XMLGetFirstChild(file,"Size");\r
209 \r
210                                 if(keyel && keyel->firstChild() && sizeel && sizeel->firstChild())\r
211                                 {\r
212                                         int size=-1;\r
213                                         std::string key="";\r
214                                         \r
215                                         StringFunctions::Convert(sizeel->firstChild()->getNodeValue(),size);\r
216                                         key=keyel->firstChild()->getNodeValue();\r
217 \r
218                                         if(size!=-1 && key!="")\r
219                                         {\r
220                                                 m_fileattachments.push_back(fileattachment(key,size));\r
221                                         }\r
222                                 }\r
223 \r
224                                 file=XMLGetNextSibling(file,"File");\r
225                         }\r
226                 }\r
227 \r
228                 parsed=true;\r
229 \r
230         }\r
231         catch(...)\r
232         {\r
233         }\r
234 \r
235         return parsed;\r
236 }\r