Develop and Download Open Source Software

Browse CVS Repository

Contents of /tombo/Tombo/Src/TSParser.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Wed Feb 8 09:38:11 2006 UTC (18 years, 2 months ago) by hirami
Branch: MAIN
CVS Tags: Tombo_2_0a3, Tombo_1_17_1, B200, B201, B202, B203, B205, B206, B207, B208, B213, B212, B211, B217, B216, B215, B214, B219, B218, Tombo_2_0b2, Tombo_2_0b3, Tombo_2_0b1, Tombo_2_0b4, B228, B229, B226, B227, B224, B225, B222, B223, B220, B221, B231, B230, Tombo_1_17, Tombo_1_16, HEAD
Branch point for: Tombo_1_17_1_branch
Changes since 1.13: +27 -21 lines
File MIME type: text/x-c++src
* Remember last tree item (#6057)
- support uri attribute of src tag in vfolder.xml.

1 #include <windows.h>
2 #include <commctrl.h>
3 #include <tchar.h>
4 #define XMLPARSEAPI(type) type __cdecl // for expat
5 #define XML_UNICODE_WCHAR_T
6 #include <expat.h>
7 #include "Tombo.h"
8 #include "UniConv.h"
9 #include "TSParser.h"
10 #include "VFStream.h"
11 #include "VFManager.h"
12 #include "AutoPtr.h"
13 #include "TString.h"
14 #include "TomboURI.h"
15
16 ///////////////////////////////////////
17 // UCS2 -> MBCS conversion libs.
18 ///////////////////////////////////////
19
20 class ConvertWideToMultiByte {
21 char *p;
22 public:
23 ConvertWideToMultiByte() : p(NULL) {}
24 ~ConvertWideToMultiByte() { delete []p; }
25
26 char *Convert(WCHAR *p);
27 char *Get() { return p; }
28 };
29
30 char *ConvertWideToMultiByte::Convert(WCHAR *pSrc)
31 {
32 if (pSrc == NULL) return NULL;
33
34 DWORD n = (wcslen(pSrc) + 1) * 2;
35 p = new char[n];
36 if (p == NULL) return NULL;
37 WideCharToMultiByte(CP_ACP, 0, pSrc, -1, p, n, NULL, NULL);
38 return p;
39 }
40
41 ///////////////////////////////////////
42 // TSParser ctor&dtor
43 ///////////////////////////////////////
44
45 TSParser::TSParser()
46 {
47 }
48
49 TSParser::~TSParser()
50 {
51 }
52
53 ///////////////////////////////////////
54 // XML tag info
55 ///////////////////////////////////////
56
57 #define TAGID_UNKNOWN 0
58 #define TAGID_INITIAL 1
59 #define TAGID_FOLDERS 2
60 #define TAGID_VFOLDER 3
61 #define TAGID_GREP 4
62 #define TAGID_SRC 5
63 #define TAGID_TIMESTAMP 6
64 #define TAGID_LIMIT 7
65 #define TAGID_ORDER 8
66
67 static DWORD nAllowParent[] = {
68 0, // TAGID_UNKONWN
69 0, // TAGID_INITIAL
70 (1 << TAGID_INITIAL), // TAGID_FOLDERS
71 (1 << TAGID_FOLDERS), // TAGID_VFOLDER
72 (1 << TAGID_VFOLDER) | (1 << TAGID_GREP) | (1 << TAGID_TIMESTAMP) | (1 << TAGID_LIMIT) | (1 << TAGID_ORDER),
73 // TAGID_GREP
74 (1 << TAGID_VFOLDER) | (1 << TAGID_GREP) | (1 << TAGID_TIMESTAMP) | (1 << TAGID_LIMIT) | (1 << TAGID_ORDER),
75 // TAGID_SRC
76 (1 << TAGID_VFOLDER) | (1 << TAGID_GREP) | (1 << TAGID_TIMESTAMP) | (1 << TAGID_LIMIT) | (1 << TAGID_ORDER),
77 // TAGID_TIMESTAMP
78 (1 << TAGID_VFOLDER) | (1 << TAGID_GREP) | (1 << TAGID_TIMESTAMP) | (1 << TAGID_LIMIT) | (1 << TAGID_ORDER),
79 // TAGID_LIMIT
80 (1 << TAGID_VFOLDER) | (1 << TAGID_GREP) | (1 << TAGID_TIMESTAMP) | (1 << TAGID_LIMIT) | (1 << TAGID_ORDER),
81 // TAGID_ORDER
82 };
83
84 ///////////////////////////////////////
85 // TAG data
86 ///////////////////////////////////////
87
88 TSParseTagItem::~TSParseTagItem()
89 {
90 }
91
92 BOOL TSParseTagItem::StartElement(ParseInfo *p, const XML_Char **atts)
93 {
94 return TRUE;
95 }
96
97 BOOL TSParseTagItem::EndElement(ParseInfo *p)
98 {
99 return TRUE;
100 }
101
102 ///////////////////////////////////////
103 // "src" tag implimentation
104 ///////////////////////////////////////
105
106 class TSSrcTag : public TSParseTagItem {
107 WCHAR *pSrc;
108 WCHAR *pURI;
109 BOOL bCheckEncrypt;
110 public:
111 TSSrcTag() : TSParseTagItem(TAGID_SRC), pSrc(NULL), bCheckEncrypt(FALSE), pURI(NULL) {}
112 ~TSSrcTag();
113
114 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
115 BOOL EndElement(ParseInfo *p);
116 };
117
118 TSSrcTag::~TSSrcTag()
119 {
120 delete [] pSrc;
121 delete [] pURI;
122 }
123
124 BOOL TSSrcTag::StartElement(ParseInfo *p, const XML_Char **atts)
125 {
126 bCheckEncrypt = FALSE;
127
128 DWORD i = 0;
129 while(atts[i] != NULL) {
130 if (wcsicmp(atts[i], L"folder") == 0) {
131 delete[] pSrc;
132 pSrc = StringDupW(atts[i + 1]);
133 if (pSrc == NULL) return FALSE;
134 } else if (wcsicmp(atts[i], L"uri") == 0) {
135 delete[] pURI;
136 pURI = StringDupW(atts[i + 1]);
137 if (pURI == NULL) return FALSE;
138 } else if (wcsicmp(atts[i], L"checkencrypt") == 0) {
139 bCheckEncrypt = TRUE;
140 }
141
142 i += 2;
143 }
144
145 if (!pSrc && !pURI) {
146 // necessary attribute is not found.
147 return FALSE;
148 }
149 return TRUE;
150 }
151
152 BOOL TSSrcTag::EndElement(ParseInfo *p)
153 {
154 if (pHead != NULL) {
155 // "src" tag can't have sub items.
156 return FALSE;
157 }
158
159 VFDirectoryGenerator *pGen = new VFDirectoryGenerator();
160 if (pGen == NULL) return FALSE;
161
162 LPTSTR pSrcPath = ConvWCharToTChar(pSrc);
163 ArrayAutoPointer<TCHAR> ap1(pSrcPath);
164
165 LPTSTR pSrcURI = ConvWCharToTChar(pURI);
166 ArrayAutoPointer<TCHAR> ap2(pSrcURI);
167
168 if (pSrcPath && !pGen->Init(pSrcPath, bCheckEncrypt)) return FALSE;
169 else if (pSrcURI) {
170 TomboURI uri;
171 if (!uri.Init(pSrcURI)) return FALSE;
172 if (!pGen->Init(&uri, bCheckEncrypt)) return FALSE;
173 }
174 // Pass create object to parent item
175 TSParseTagItem *pParent = pNext;
176 pParent->pHead = pParent->pTail = pGen;
177 return TRUE;
178 }
179
180 ///////////////////////////////////////
181 // "grep" tag implimentation
182 ///////////////////////////////////////
183
184 class TSGrepTag : public TSParseTagItem {
185 WCHAR *pPattern;
186 BOOL bCaseSensitive;
187 BOOL bFileNameOnly;
188 BOOL bNegate;
189 BOOL bCheckEncrypt;
190 public:
191 TSGrepTag() : TSParseTagItem(TAGID_GREP), pPattern(NULL) {}
192 ~TSGrepTag();
193
194 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
195 BOOL EndElement(ParseInfo *p);
196 };
197
198 TSGrepTag::~TSGrepTag()
199 {
200 if (pPattern) delete [] pPattern;
201 }
202
203 BOOL TSGrepTag::StartElement(ParseInfo *p, const XML_Char **atts)
204 {
205 bCaseSensitive = bFileNameOnly = bNegate = bCheckEncrypt = FALSE;
206 DWORD i = 0;
207 while(atts[i] != NULL) {
208 if (wcsicmp(atts[i], L"pattern") == 0) {
209 pPattern = new WCHAR[wcslen(atts[i + 1]) + 1];
210 if (pPattern == NULL) return FALSE;
211 wcscpy(pPattern, atts[i + 1]);
212 } else if (wcsicmp(atts[i], L"casesensitive") == 0) {
213 bCaseSensitive = TRUE;
214 } else if (wcsicmp(atts[i], L"filenameonly") == 0) {
215 bFileNameOnly = TRUE;
216 } else if (wcsicmp(atts[i], L"not") == 0) {
217 bNegate = TRUE;
218 } else if (wcsicmp(atts[i], L"checkencrypt") == 0) {
219 bCheckEncrypt = TRUE;
220 }
221 i += 2;
222 }
223 if (!pPattern) {
224 return FALSE;
225 }
226 return TRUE;
227 }
228
229 BOOL TSGrepTag::EndElement(ParseInfo *p)
230 {
231 if (pHead == NULL) {
232 // Grep tag should have child tag.
233 return FALSE;
234 }
235 VFRegexFilter *pFilter = new VFRegexFilter();
236
237 #ifdef _WIN32_WCE
238 LPTSTR pConved = pPattern;
239 #else
240 ConvertWideToMultiByte conv;
241 if (!conv.Convert(pPattern)) return FALSE;
242 LPTSTR pConved = conv.Get();
243 #endif
244 if (!pFilter || !pFilter->Init(pConved, bCaseSensitive, bCheckEncrypt, bFileNameOnly, bNegate, g_pPasswordManager)) return FALSE;
245
246 // Pass create object to parent item
247 TSParseTagItem *pParent = pNext;
248 pTail->SetNext(pFilter);
249 pParent->pHead = pHead;
250 pParent->pTail = pFilter;
251 return TRUE;
252 }
253
254 ///////////////////////////////////////
255 // "vfolder" tag implimentation
256 ///////////////////////////////////////
257
258 class TSVFolderTag : public TSParseTagItem {
259 WCHAR *pName;
260 public:
261 TSVFolderTag() : TSParseTagItem(TAGID_VFOLDER), pName(NULL){}
262 ~TSVFolderTag();
263
264 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
265 BOOL EndElement(ParseInfo *p);
266 };
267
268 TSVFolderTag::~TSVFolderTag()
269 {
270 if (pName) delete[] pName;
271 }
272
273 BOOL TSVFolderTag::StartElement(ParseInfo *p, const XML_Char **atts)
274 {
275 DWORD i = 0;
276 while(atts[i] != NULL) {
277 if (wcsicmp(atts[i], L"name") == 0) {
278 pName = new WCHAR[wcslen(atts[i + 1]) + 1];
279 if (pName == NULL) return FALSE;
280 wcscpy(pName, atts[i + 1]);
281 }
282 i += 2;
283 }
284 if (!pName) {
285 return FALSE;
286 }
287 return TRUE;
288 }
289
290 BOOL TSVFolderTag::EndElement(ParseInfo *p)
291 {
292 if (pHead == NULL || pTail == NULL) return FALSE;
293
294 // add VFStore
295 VFStore *pStore = new VFStore();
296 if (!pStore || !pStore->Init()) {
297 delete pStore;
298 return FALSE;
299 }
300 pTail->SetNext(pStore);
301
302 // convert Node name
303 // TOMBO uses expat UNICODE version, so convert MBCS if platform is win32.
304
305 #ifdef _WIN32_WCE
306 LPTSTR pConved = pName;
307 #else
308 ConvertWideToMultiByte conv;
309 if (!conv.Convert(pName)) return FALSE;
310 LPTSTR pConved = conv.Get();
311 #endif
312
313 p->pListener->ProcessStream(pConved, TRUE, (VFDirectoryGenerator*)pHead, pStore);
314
315 return TRUE;
316 }
317
318 ///////////////////////////////////////
319 // "timestamp" tag implimentation
320 ///////////////////////////////////////
321
322 class TSTimestampTag : public TSParseTagItem {
323 DWORD nDelta;
324 DWORD nRecent;
325 public:
326 TSTimestampTag() : TSParseTagItem(TAGID_TIMESTAMP) {}
327 ~TSTimestampTag() {}
328
329 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
330 BOOL EndElement(ParseInfo *p);
331
332 };
333
334 BOOL TSTimestampTag::StartElement(ParseInfo *p, const XML_Char **atts)
335 {
336 DWORD i = 0;
337 nRecent = TRUE;
338 nDelta = 0xFFFFFFFF;
339 while(atts[i] != NULL) {
340 if (wcsicmp(atts[i], L"days") == 0) {
341 // atts[i + 1];
342 nDelta = _wtol(atts[i + 1]);
343 }
344 if (wcsicmp(atts[i], L"older") == 0) {
345 nRecent = FALSE;
346 }
347 if (wcsicmp(atts[i], L"newer") == 0) {
348 nRecent = TRUE;
349 }
350 i += 2;
351 }
352 if (nDelta == 0xFFFFFFFF) return FALSE;
353 return TRUE;
354 }
355
356 BOOL TSTimestampTag::EndElement(ParseInfo *p)
357 {
358 if (pHead == NULL) return FALSE;
359
360 VFTimestampFilter *pFilter = new VFTimestampFilter();
361 if (pFilter == NULL || !pFilter->Init(nDelta, nRecent)) return FALSE;
362 TSParseTagItem *pParent = pNext;
363 pTail->SetNext(pFilter);
364 pParent->pHead = pHead;
365 pParent->pTail = pFilter;
366 return TRUE;
367 }
368
369 ///////////////////////////////////////
370 // "limit" tag implimentation
371 ///////////////////////////////////////
372
373 class TSLimitTag : public TSParseTagItem {
374 DWORD nLimit;
375 public:
376 TSLimitTag() : TSParseTagItem(TAGID_LIMIT) {}
377 ~TSLimitTag() {}
378
379 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
380 BOOL EndElement(ParseInfo *p);
381
382 DWORD GetLimit() { return nLimit; }
383 };
384
385 BOOL TSLimitTag::StartElement(ParseInfo *p, const XML_Char **atts)
386 {
387 nLimit = 0xFFFFFFFF;
388 DWORD i = 0;
389 while(atts[i] != NULL) {
390 if (wcsicmp(atts[i], L"number") == 0) {
391 // atts[i + 1];
392 nLimit = _wtol(atts[i + 1]);
393 }
394 i += 2;
395 }
396 if (nLimit == 0xFFFFFFFF) return FALSE;
397 return TRUE;
398 }
399
400 BOOL TSLimitTag::EndElement(ParseInfo *p)
401 {
402 if (pHead == NULL) return FALSE;
403
404 VFLimitFilter *pFilter = new VFLimitFilter();
405 if (pFilter == NULL || !pFilter->Init(nLimit)) return FALSE;
406 TSParseTagItem *pParent = pNext;
407 pTail->SetNext(pFilter);
408 pParent->pHead = pHead;
409 pParent->pTail = pFilter;
410 return TRUE;
411 }
412
413 ///////////////////////////////////////
414 // "order" tag implimentation
415 ///////////////////////////////////////
416
417 class TSOrderTag : public TSParseTagItem {
418 VFSortFilter::SortFuncType sfType;
419 public:
420 TSOrderTag() : TSParseTagItem(TAGID_ORDER){}
421 ~TSOrderTag() {}
422
423 BOOL StartElement(ParseInfo *p, const XML_Char **atts);
424 BOOL EndElement(ParseInfo *p);
425 };
426
427 BOOL TSOrderTag::StartElement(ParseInfo *p, const XML_Char **atts)
428 {
429 DWORD i = 0;
430 while(atts[i] != NULL) {
431 if (wcsicmp(atts[i], L"func") == 0) {
432 if (wcsicmp(atts[i + 1], L"filename_asc") == 0) {
433 sfType = VFSortFilter::SortFunc_FileNameAsc;
434 } else if (wcsicmp(atts[i + 1], L"filename_dsc") == 0) {
435 sfType = VFSortFilter::SortFunc_FileNameDsc;
436 } else if (wcsicmp(atts[i + 1], L"lastupdate_asc") == 0) {
437 sfType = VFSortFilter::SortFunc_LastUpdateAsc;
438 } else if (wcsicmp(atts[i + 1], L"lastupdate_dsc") == 0) {
439 sfType = VFSortFilter::SortFunc_LastUpdateDsc;
440 } else if (wcsicmp(atts[i + 1], L"createdate_asc") == 0) {
441 sfType = VFSortFilter::SortFunc_CreateDateAsc;
442 } else if (wcsicmp(atts[i + 1], L"createdate_dsc") == 0) {
443 sfType = VFSortFilter::SortFunc_CreateDateDsc;
444 } else if (wcsicmp(atts[i + 1], L"filesize_asc") == 0) {
445 sfType = VFSortFilter::SortFunc_FileSizeAsc;
446 } else if (wcsicmp(atts[i + 1], L"filesize_dsc") == 0) {
447 sfType = VFSortFilter::SortFunc_FileSizeDsc;
448 } else {
449 return FALSE;
450 }
451 }
452 i += 2;
453 }
454 return TRUE;
455 }
456
457 BOOL TSOrderTag::EndElement(ParseInfo *p)
458 {
459 if (pHead == NULL) return FALSE;
460
461 VFSortFilter *pFilter = new VFSortFilter();
462 if (pFilter == NULL || !pFilter->Init(sfType)) return FALSE;
463 TSParseTagItem *pParent = pNext;
464 pTail->SetNext(pFilter);
465 pParent->pHead = pHead;
466 pParent->pTail = pFilter;
467 return TRUE;
468 }
469
470 ///////////////////////////////////////
471 // ParseInfo implimentation
472 ///////////////////////////////////////
473
474 ParseInfo::~ParseInfo()
475 {
476 TSParseTagItem *p = pTop;
477 TSParseTagItem *q;
478 while(p) {
479 q = p;
480 p = p->GetNext();
481 delete q;
482 }
483 }
484
485 BOOL ParseInfo::Init(VirtualFolderEnumListener *pLsnr)
486 {
487 pListener = pLsnr;
488
489 TSParseTagItem *pTag = new TSParseTagItem(TAGID_INITIAL);
490 if (pTag == NULL) return FALSE;
491 Push(pTag);
492 return TRUE;
493 }
494
495 DWORD ParseInfo::GetTagID(const WCHAR *pTagName)
496 {
497 if (wcsicmp(pTagName, L"folders") == 0) {
498 return TAGID_FOLDERS;
499 } else if (wcsicmp(pTagName, L"vfolder") == 0) {
500 return TAGID_VFOLDER;
501 } else if (wcsicmp(pTagName, L"grep") == 0) {
502 return TAGID_GREP;
503 } else if (wcsicmp(pTagName, L"src") == 0) {
504 return TAGID_SRC;
505 } else if (wcsicmp(pTagName, L"timestamp") == 0) {
506 return TAGID_TIMESTAMP;
507 } else if (wcsicmp(pTagName, L"limit") == 0) {
508 return TAGID_LIMIT;
509 } else if (wcsicmp(pTagName, L"sort") == 0) {
510 return TAGID_ORDER;
511 } else {
512 return TAGID_UNKNOWN;
513 }
514 }
515
516 TSParseTagItem *ParseInfo::GetTagObjectFactory(DWORD nTagID)
517 {
518 switch (nTagID) {
519 case TAGID_FOLDERS:
520 return new TSParseTagItem(TAGID_FOLDERS);
521 case TAGID_VFOLDER:
522 return new TSVFolderTag();
523 case TAGID_GREP:
524 return new TSGrepTag();
525 case TAGID_SRC:
526 return new TSSrcTag();
527 case TAGID_TIMESTAMP:
528 return new TSTimestampTag();
529 case TAGID_LIMIT:
530 return new TSLimitTag();
531 case TAGID_ORDER:
532 return new TSOrderTag();
533 default:
534 return NULL;
535 }
536 }
537
538 void ParseInfo::Push(TSParseTagItem *p)
539 {
540 p->SetNext(pTop);
541 pTop = p;
542 }
543
544 void ParseInfo::Pop()
545 {
546 TSParseTagItem *p = pTop;
547 pTop = p->GetNext();
548 delete p;
549 }
550
551 BOOL ParseInfo::IsValidParent(DWORD nTag)
552 {
553 return ((nAllowParent[nTag] & (1 << pTop->GetTagID())) != 0);
554 }
555
556 ///////////////////////////////////////
557 // expat callback funcs.
558 ///////////////////////////////////////
559
560 static void StartElement(void *userData, const XML_Char *name, const XML_Char **atts)
561 {
562 ParseInfo *pInfo = (ParseInfo*)userData;
563 if (pInfo->IsError()) return;
564
565 // Check tag
566 DWORD nCurTag = pInfo->GetTagID(name);
567 if (nCurTag == TAGID_UNKNOWN) {
568 pInfo->SetError();
569 return;
570 }
571 if (!pInfo->IsValidParent(nCurTag)) {
572 pInfo->SetError();
573 return;
574 }
575 TSParseTagItem *pTag = pInfo->GetTagObjectFactory(nCurTag);
576 pInfo->Push(pTag);
577 if (!pTag->StartElement(pInfo, atts)) {
578 pInfo->SetError();
579 }
580 }
581
582 static void EndElement(void *userData, const XML_Char *name)
583 {
584 ParseInfo *pInfo = (ParseInfo*)userData;
585 if (pInfo->IsError()) {
586 pInfo->Pop();
587 return;
588 }
589 pInfo->Top()->EndElement(pInfo);
590 pInfo->Pop();
591 }
592
593 ///////////////////////////////////////
594 // parser main
595 ///////////////////////////////////////
596
597 BOOL TSParser::Parse(LPCTSTR pFileName, VirtualFolderEnumListener *pLsnr)
598 {
599 XML_Parser pParser;
600 ParseInfo info;
601
602 if (!info.Init(pLsnr)) return FALSE;
603
604 HANDLE hFile = CreateFile(pFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
605 if (hFile == INVALID_HANDLE_VALUE) return FALSE;
606
607 DWORD nFileSize = GetFileSize(hFile, NULL);
608
609 pParser = XML_ParserCreate(NULL);
610 if (pParser == NULL) {
611 CloseHandle(hFile);
612 return FALSE;
613 }
614
615 XML_SetElementHandler(pParser, StartElement, EndElement);
616 XML_SetUserData(pParser, &info);
617
618 void *pBuf = XML_GetBuffer(pParser, nFileSize);
619 if (pBuf == NULL) {
620 CloseHandle(hFile);
621 return FALSE;
622 }
623 DWORD nRead;
624 if (!ReadFile(hFile, pBuf, nFileSize, &nRead, NULL)) {
625 CloseHandle(hFile);
626 return FALSE;
627 }
628
629 CloseHandle(hFile);
630
631 if (!XML_ParseBuffer(pParser, nFileSize, TRUE)) {
632 const WCHAR *p = XML_ErrorString(XML_GetErrorCode(pParser));
633 int ln = XML_GetCurrentLineNumber(pParser);
634 int col = XML_GetCurrentColumnNumber(pParser);
635 return FALSE;
636 }
637 XML_ParserFree(pParser);
638 return TRUE;
639 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26