Imported Upstream version 0.8~alpha1
[platform/upstream/syncevolution.git] / src / client-api / src / c++ / common / spds / FileData.cpp
1 /*
2  * Funambol is a mobile platform developed by Funambol, Inc. 
3  * Copyright (C) 2003 - 2007 Funambol, Inc.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Affero General Public License version 3 as published by
7  * the Free Software Foundation with the addition of the following permission 
8  * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
9  * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
10  * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
11  * 
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  * 
17  * You should have received a copy of the GNU Affero General Public License 
18  * along with this program; if not, see http://www.gnu.org/licenses or write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20  * MA 02110-1301 USA.
21  * 
22  * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
23  * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
24  * 
25  * The interactive user interfaces in modified source and object code versions
26  * of this program must display Appropriate Legal Notices, as required under
27  * Section 5 of the GNU Affero General Public License version 3.
28  * 
29  * In accordance with Section 7(b) of the GNU Affero General Public License
30  * version 3, these Appropriate Legal Notices must retain the display of the
31  * "Powered by Funambol" logo. If the display of the logo is not reasonably 
32  * feasible for technical reasons, the Appropriate Legal Notices must display
33  * the words "Powered by Funambol".
34  */
35
36 #include "base/fscapi.h"
37 #include "base/Log.h"
38 #include "base/util/XMLProcessor.h"
39 #include "syncml/formatter/Formatter.h"
40 #include "spds/FileData.h"
41 #include "base/quoted-printable.h"
42 #include "base/globalsdef.h"
43
44 USE_NAMESPACE
45
46
47 #define FILE_ITEM       TEXT("File")
48 #define FILE_HIDDEN     "h"
49 #define FILE_SYSTEM     "s"
50 #define FILE_ARCHIVED   "a"
51 #define FILE_DELETE     "d"
52 #define FILE_WRITABLE   "w"
53 #define FILE_READABLE   "r"
54 #define FILE_EXECUTABLE "e"
55 #define FILE_ACCESSED   "accessed"
56 #define FILE_ATTRIBUTES "attributes"
57 #define FILE_BODY       "body"
58 #define FILE_CTTYTPE    "cttype"
59 #define FILE_ENC        "enc"
60 #define FILE_MODIFIED   "modified"
61 #define FILE_NAME       "name"
62 #define FILE_SIZE       "size"
63 #define FILE_CREATED    "created"
64
65
66 FileData::FileData()
67 {
68     size = 0;
69     hidden = false;
70     system = false;
71     archived = false;
72     deleted = false;
73     writable = false;
74     readable = false;
75     executable = false;
76     isHiddenPresent = false;
77     isSystemPresent = false;
78     isArchivedPresent = false;
79     isDeletedPresent = false;
80     isWritablePresent = false;
81     isReadablePresent = false;
82     isExecutablePresent = false;
83 }
84
85 FileData::~FileData()
86 {
87 }
88
89 int FileData::parse(const void *syncmlData, size_t len) {
90     StringBuffer s((const char*)syncmlData, len);
91     return parse(&s);
92 }
93
94 int FileData::parse(const char *syncmlData, size_t len) {
95     StringBuffer s(syncmlData, len);
96     return parse(&s);
97 }
98
99 int FileData::parse(StringBuffer* s)
100 {
101     int ret = 0;
102     unsigned int start, end;
103     //StringBuffer* s = new StringBuffer(syncmlData, len);
104     StringBuffer bodyattr;
105
106     // FIXME: remove these replace once the server has fixed the message.
107     s->replaceAll("&lt;", "<");
108     s->replaceAll("&gt;", ">");
109     s->replaceAll("&amp;", "&");
110
111         /*
112     // Get the CDATA content
113     if(XMLProcessor::getElementContent(s->c_str(), "CDATA", NULL, &start, &end) == 0) {
114         LOG.error("FileData: can't find outer CDATA section.");
115         return -1;
116     }
117     StringBuffer msg = s->substr(start, end-start);
118
119     delete s;
120         */
121
122         if(XMLProcessor::getElementContent(s->c_str(), "File", NULL, &start, &end) == 0) {
123                 LOG.error("FileData: can't find outer FILE section.");
124                 return -1;
125         }
126         StringBuffer msg = s->substr(start, end-start);
127
128     // Get attributes
129     if( XMLProcessor::getElementContent (msg, FILE_HIDDEN, NULL, &start, &end) ) {
130         hidden = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
131         isHiddenPresent = true;
132     }
133     else hidden = false;
134
135     if( XMLProcessor::getElementContent (msg, FILE_SYSTEM, NULL, &start, &end) ) {
136         system = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
137         isSystemPresent = true;
138     }
139     else system = false;
140
141     if( XMLProcessor::getElementContent (msg, FILE_ARCHIVED, NULL, &start, &end) ) {
142         archived = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
143         isArchivedPresent = true;
144     }
145     else archived = false;
146
147     if( XMLProcessor::getElementContent (msg, FILE_DELETE, NULL, &start, &end) ) {
148         deleted = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
149         isDeletedPresent = true;
150     }
151     else deleted = false;
152
153     if( XMLProcessor::getElementContent (msg, FILE_WRITABLE, NULL, &start, &end) ) {
154         writable = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
155         isWritablePresent = true;
156     }
157     else writable = false;
158
159     if( XMLProcessor::getElementContent (msg, FILE_READABLE, NULL, &start, &end) ) {
160         readable = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
161         isReadablePresent = true;
162     }
163     else readable = false;
164
165     if( XMLProcessor::getElementContent (msg, FILE_EXECUTABLE, NULL, &start, &end) ) {
166         executable = ( strncmp(msg.c_str()+start, "true", end-start) == 0 ) ;
167         isExecutablePresent = true;
168     }
169     else executable = false;
170
171     if( XMLProcessor::getElementContent (msg, FILE_ACCESSED, NULL, &start, &end) ) {
172         accessed = msg.substr(start, end-start);
173     }
174     else accessed = TEXT("");
175
176     if( XMLProcessor::getElementContent (msg, FILE_MODIFIED, NULL, &start, &end) ) {
177         modified = msg.substr(start, end-start);
178     }
179     else modified = TEXT("");
180
181     if( XMLProcessor::getElementContent (msg, FILE_CREATED, NULL, &start, &end) ) {
182         created = msg.substr(start, end-start);
183     }
184     else created = TEXT("");
185
186     if ( XMLProcessor::getElementContent (msg, FILE_SIZE, NULL, &start, &end) ) {
187         size = atoi(msg.substr(start, end-start));
188     }
189
190     if( XMLProcessor::getElementContent (msg, FILE_BODY, NULL, &start, &end) ) {
191         body = msg.substr(start, end-start);
192     }
193     else body = "";
194     if ( XMLProcessor::getElementAttributes (msg, FILE_BODY, &start, &end) ) {
195         bodyattr = msg.substr(start, end-start);
196         size_t attrstart = bodyattr.ifind("enc");
197         if (attrstart!= StringBuffer::npos) {
198             enc = bodyattr.substr(attrstart + 4);
199             if (!enc.empty() && (enc != TEXT("\"base64\"")) &&
200                 (enc != TEXT("\"quoted-printable\"")))
201             {
202                 enc = TEXT("");
203             }
204             else
205             {
206                 int repNo = enc.replaceAll(TEXT("\""),TEXT(""));
207             }
208         }
209         else
210             enc = TEXT("");
211     }
212     else
213         enc = TEXT("");
214
215     if (!enc.empty() && (enc == TEXT("base64")))
216     {
217         int len = b64_decode((void *)body.c_str(), body.c_str());
218     }
219
220     if (!enc.empty() && (enc == TEXT("quoted-printable")))
221     {
222         body = qp_decode(body.c_str());
223     }
224
225
226     if( XMLProcessor::getElementContent (msg, FILE_NAME, NULL, &start, &end) ) {
227         name = msg.substr(start, end-start);
228     }
229     else name = TEXT("");
230
231         delete s;
232
233     return ret;
234 }
235
236 void FileData::setBody(const char* v, int len)
237 {
238     if (size == 0)
239     {
240         body = v;
241     }
242     else
243     {
244         char*   base64    = NULL;
245         int     encodeLen = lengthForB64(len);
246         base64 = new char[encodeLen + 1];
247         memset(base64, 0, encodeLen + 1);
248         b64_encode(base64, (char*)v, len);
249         body = base64;
250         delete [] base64;
251     }
252 }
253
254
255 char* FileData::format() {
256
257     StringBuffer out;
258
259     out.reserve(150);
260
261     out = "<File>\n";
262     if (name.length() > 0)
263         out += XMLProcessor::makeElement(FILE_NAME, _wcc(name));
264     if (created.length() > 0)
265         out += XMLProcessor::makeElement(FILE_CREATED, _wcc(created));
266     if (modified.length() > 0)
267         out += XMLProcessor::makeElement(FILE_MODIFIED, _wcc(modified));
268     if (accessed.length() > 0)
269         out += XMLProcessor::makeElement(FILE_ACCESSED, _wcc(accessed));
270
271     StringBuffer attributes;
272
273     if (isHiddenPresent)
274         attributes += XMLProcessor::makeElement(FILE_HIDDEN, hidden);
275     if (isSystemPresent)
276         attributes += XMLProcessor::makeElement(FILE_SYSTEM, system);
277     if (isArchivedPresent)
278         attributes += XMLProcessor::makeElement(FILE_ARCHIVED, archived);
279     if (isDeletedPresent)
280         attributes += XMLProcessor::makeElement(FILE_DELETE, deleted);
281     if (isWritablePresent)
282         attributes += XMLProcessor::makeElement(FILE_WRITABLE, writable);
283     if (isReadablePresent)
284         attributes += XMLProcessor::makeElement(FILE_READABLE, readable);
285     if (isExecutablePresent)
286         attributes += XMLProcessor::makeElement(FILE_EXECUTABLE, executable);
287     if (!attributes.empty())
288         out += XMLProcessor::makeElement(FILE_ATTRIBUTES, attributes);
289
290     if (enc.empty()){
291         int len = b64_decode((void*)body.c_str(), body.c_str());
292         out += XMLProcessor::makeElement(FILE_BODY, body);
293     }
294     else
295     {
296         ArrayList attrList;
297         KeyValuePair attr("enc", _wcc(enc.c_str()));
298         attrList.add(attr);
299         out += XMLProcessor::makeElement(FILE_BODY, body.c_str(), attrList);
300     }
301     if (size > 0)
302         out += XMLProcessor::makeElement(FILE_SIZE, size);
303     out += "</File>\n";
304     return stringdup(out.c_str());
305 }
306
307 int FileData::lengthForB64(int len) {
308
309     int modules = 0;
310     int ret     = 0;
311
312     modules = len % 3;
313     if (modules == 0) {
314         ret = 4 * (len / 3);
315
316     } else {
317         ret = 4 * ((len/3) + 1);
318
319     }
320     return ret;
321
322
323 }