OSDN Git Service

Support password timeout.
[tombo/Tombo.git] / Src / URIScanner.cpp
1 #include <windows.h>\r
2 #include <tchar.h>\r
3 #include "Tombo.h"\r
4 #include "UniConv.h"\r
5 #include "TString.h"\r
6 #include "TomboURI.h"\r
7 #include "VarBuffer.h"\r
8 #include "URIScanner.h"\r
9 #include "Repository.h"\r
10 \r
11 #define URILIST_INITSIZE 20\r
12 #define URILIST_DELTASIZE 10\r
13 \r
14 /////////////////////////////////////////////////\r
15 //////////////////////////////////////////////////\r
16 // URIList implementation\r
17 //////////////////////////////////////////////////\r
18 //////////////////////////////////////////////////\r
19 \r
20 URIList::URIList()\r
21 {\r
22 }\r
23 \r
24 URIList::~URIList()\r
25 {\r
26         for (DWORD i = 0; i < liList.NumItems(); i++) {\r
27                 URIListItem *pItem = liList.GetUnit(i);\r
28                 delete pItem->pURI;\r
29                 delete [] pItem->pTitle;\r
30         }\r
31 }\r
32 \r
33 BOOL URIList::Init()\r
34 {\r
35         if (!liList.Init(URILIST_INITSIZE, URILIST_DELTASIZE)) return FALSE;\r
36         return TRUE;\r
37 }\r
38 \r
39 BOOL URIList::Add(const TomboURI *pURI, LPCTSTR pTitle)\r
40 {\r
41         URIListItem item;\r
42         if (pURI) {\r
43                 item.pURI = new TomboURI(*pURI);\r
44                 if (item.pURI == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }\r
45         }\r
46 \r
47         if (pTitle) {\r
48                 item.pTitle = StringDup(pTitle); \r
49                 if (item.pTitle == NULL) return FALSE;\r
50         }\r
51 \r
52         if (!liList.Add(&item)) return FALSE;\r
53 \r
54         return TRUE;\r
55 }\r
56 \r
57 /////////////////////////////////////////////////\r
58 //////////////////////////////////////////////////\r
59 // URIScanner implementation\r
60 //////////////////////////////////////////////////\r
61 //////////////////////////////////////////////////\r
62 \r
63 //////////////////////////////////////////////////\r
64 // ctor & Initialize\r
65 //////////////////////////////////////////////////\r
66 \r
67 URIScanner::URIScanner() : pBaseURI(NULL), pCurrentURI(NULL), pTop(NULL), pBaseTitle(NULL)\r
68 {\r
69 }\r
70 \r
71 BOOL URIScanner::Init(IEnumRepository *pRepo, const TomboURI *pURI, BOOL bSKE)\r
72 {\r
73         // initialize value\r
74         pRepository = pRepo;\r
75         bSkipEncrypt = bSKE;\r
76         iDirection = 1;\r
77 \r
78         // check URI\r
79         URIOption opt(NOTE_OPTIONMASK_VALID);\r
80         if (!pRepository->GetOption(pURI, &opt)) return FALSE;\r
81 \r
82         if (!opt.bFolder) {\r
83                 SetLastError(ERROR_INVALID_PARAMETER);\r
84                 return FALSE;\r
85         }\r
86 \r
87         // set URI\r
88         pBaseURI = new TomboURI(*pURI);\r
89 \r
90         return TRUE;\r
91 }\r
92 \r
93 //////////////////////////////////////////////////\r
94 // dtor\r
95 //////////////////////////////////////////////////\r
96 \r
97 URIScanner::~URIScanner()\r
98 {\r
99         ClearStack();\r
100         delete pBaseURI;\r
101         delete pBaseTitle;\r
102 }\r
103 \r
104 //////////////////////////////////////////////////\r
105 // treat stack frame\r
106 //////////////////////////////////////////////////\r
107 \r
108 void URIScanner::ClearStack()\r
109 {\r
110         while(pTop) {\r
111                 LeaveFrame();\r
112         }\r
113 }\r
114 \r
115 void URIScanner::LeaveFrame()\r
116 {\r
117         StackFrame *pSF = pTop;\r
118         pTop = pSF->pNext;\r
119 \r
120         delete pSF->pList;\r
121         delete pSF;\r
122 }\r
123 \r
124 BOOL URIScanner::PushFrame(const TomboURI *pURI)\r
125 {\r
126         StackFrame *pSF = new StackFrame();\r
127         if (pSF == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }\r
128 \r
129         BOOL bLoose;\r
130         pSF->pList = pRepository->GetChild(pCurrentURI, bSkipEncrypt, FALSE, &bLoose);\r
131         if (pSF->pList == NULL) {\r
132                 DWORD n = GetLastError();\r
133                 if (GetLastError() == ERROR_CANCELLED) {\r
134                         StopScan();\r
135                         delete pSF;\r
136                         return TRUE;\r
137                 }\r
138                 return FALSE;\r
139         }\r
140         if (iDirection == 1) {\r
141                 pSF->nPos = 0;\r
142         } else {\r
143                 pSF->nPos = pSF->pList->GetSize() - 1;\r
144         }\r
145 \r
146         pSF->pNext = pTop;\r
147         pTop = pSF;\r
148 \r
149         return TRUE;\r
150 }\r
151 \r
152 //////////////////////////////////////////////////\r
153 // cutomisable methods\r
154 //////////////////////////////////////////////////\r
155 \r
156 void URIScanner::InitialScan() {}\r
157 void URIScanner::AfterScan() {}\r
158 void URIScanner::PreFolder() {}\r
159 void URIScanner::PostFolder() {}\r
160 void URIScanner::Node() {}\r
161 \r
162 //////////////////////////////////////////////////\r
163 // Scan repository\r
164 //////////////////////////////////////////////////\r
165 \r
166 BOOL URIScanner::FullScan()\r
167 {\r
168         return Scan(NULL, FALSE);\r
169 }\r
170 \r
171 //////////////////////////////////////////////////\r
172 // Scan repository\r
173 //////////////////////////////////////////////////\r
174 \r
175 BOOL URIScanner::Scan(const TomboURI *pStartURI, BOOL bReverse)\r
176 {\r
177         // Initialize \r
178         if (bReverse) {\r
179                 iDirection = -1;\r
180         } else {\r
181                 iDirection = 1;\r
182         }\r
183         bStopScan = FALSE;\r
184         pBaseTitle = new TString();\r
185         if (!pRepository->GetHeadLine(pBaseURI, pBaseTitle)) return FALSE;\r
186 \r
187         // set marker and call initialize method\r
188         pCurrentURI = pBaseURI;\r
189         pTitle = pBaseTitle->Get();\r
190         InitialScan();\r
191 \r
192 \r
193         // create stack frame\r
194         if (pStartURI == NULL || _tcscmp(pStartURI->GetFullURI(), pBaseURI->GetFullURI()) == 0) {\r
195                 if (!PushFrame(pCurrentURI)) return FALSE;\r
196                 if (bStopScan) {\r
197                         AfterScan();\r
198                         return TRUE;\r
199                 }\r
200                 PreFolder();\r
201         } else {\r
202                 // if pStartURI is passed, traverse the tree to create stack frame.\r
203                 if (!MakeFrame(pStartURI)) {\r
204                         return FALSE;\r
205                 }\r
206         }\r
207 \r
208         while(pTop) {\r
209                 // enum current frame\r
210                 while (pTop->nPos >= 0 && pTop->nPos < pTop->pList->GetSize()) {\r
211 \r
212                         if (bStopScan) break;\r
213 \r
214                         // update marker\r
215                         pCurrentURI = pTop->pList->GetURI(pTop->nPos);\r
216                         pTitle = pTop->pList->GetTitle(pTop->nPos);\r
217 \r
218                         // check folder or not\r
219                         URIOption opt(NOTE_OPTIONMASK_VALID);\r
220                         if (!pRepository->GetOption(pCurrentURI, &opt)) return FALSE;\r
221 \r
222                         if (opt.bFolder) {\r
223                                 // create new frame\r
224                                 if (!PushFrame(pCurrentURI)) return FALSE;\r
225                                 if (bStopScan) break;\r
226                                 PreFolder();\r
227                                 continue;\r
228                         } else {\r
229                                 Node();\r
230                         }\r
231                         pTop->nPos += iDirection;\r
232                 }\r
233 \r
234                 // when enumeration finished, \r
235                 LeaveFrame();\r
236                 if (pTop) {\r
237                         pCurrentURI = pTop->pList->GetURI(pTop->nPos);\r
238                         pTitle = pTop->pList->GetTitle(pTop->nPos);\r
239                 } else {\r
240                         pCurrentURI = pBaseURI;\r
241                         pTitle = pBaseTitle->Get();\r
242                 }\r
243                 PostFolder();\r
244                 if (pTop) {\r
245                         pTop->nPos += iDirection;\r
246                 }\r
247         }\r
248 \r
249         // call finalize method\r
250         AfterScan();\r
251 \r
252         return TRUE;\r
253 }\r
254 \r
255 //////////////////////////////////////////////////\r
256 //\r
257 //////////////////////////////////////////////////\r
258 \r
259 BOOL URIScanner::MakeFrame(const TomboURI *pStartURI)\r
260 {\r
261         // check base uri and start uri\r
262         TString repB, repS;\r
263         if (!pBaseURI->GetRepositoryName(&repB) || !pStartURI->GetRepositoryName(&repS) ||\r
264                 _tcscmp(repB.Get(), repS.Get()) != 0) return FALSE;\r
265 \r
266         TomboURIItemIterator itrB(pBaseURI);\r
267         TomboURIItemIterator itrS(pStartURI);\r
268         if (!itrB.Init() || !itrS.Init()) return FALSE;\r
269         itrB.First(); itrS.First();\r
270         while(TRUE) {\r
271                 LPCTSTR pB = itrB.Current();\r
272                 LPCTSTR pS = itrS.Current();\r
273 \r
274                 if (pB == NULL || pS == NULL) {\r
275                         if (pS == NULL && pB != NULL) return FALSE;\r
276                         break;\r
277                 }\r
278 \r
279                 if (_tcscmp(pB, pS) != 0) return FALSE;\r
280 \r
281                 itrB.Next();\r
282                 itrS.Next();\r
283         }\r
284 \r
285         // OK, stack frames.\r
286 \r
287         const TomboURI *pURI = pCurrentURI;\r
288 \r
289         pTitle = pBaseTitle->Get();\r
290 \r
291         // stack first frame\r
292         if (!PushFrame(pURI)) return FALSE;\r
293         PreFolder();\r
294 \r
295         TString shl;\r
296 \r
297         LPCTSTR pElement = itrS.Current();\r
298         LPCTSTR pHeadLine;\r
299 \r
300         do {\r
301                 // get each element\r
302                 if (itrS.IsLeaf()) {\r
303                         if (!pRepository->GetHeadLine(pStartURI, &shl)) return FALSE;\r
304                         pHeadLine = shl.Get();\r
305 \r
306                 } else {\r
307                         pHeadLine = pElement;\r
308 \r
309                 }\r
310 \r
311                 while (pTop->nPos >= 0 && pTop->nPos < pTop->pList->GetSize()) {\r
312                         LPCTSTR pElem = pTop->pList->GetTitle(pTop->nPos);\r
313 \r
314                         if (_tcscmp(pHeadLine, pElem) == 0) {\r
315                                 // path is matched.\r
316 \r
317                                 pCurrentURI = pTop->pList->GetURI(pTop->nPos);\r
318                                 pTitle = pElem;\r
319 \r
320                                 URIOption opt(NOTE_OPTIONMASK_VALID);\r
321                                 if (!pRepository->GetOption(pCurrentURI, &opt)) return FALSE;\r
322                                 if (opt.bFolder) {\r
323                                         if (!PushFrame(pCurrentURI)) return FALSE;\r
324                                         if (bStopScan) break;\r
325                                         PreFolder();\r
326                                         break;\r
327                                 } else {\r
328                                         break;\r
329                                 }\r
330                         }\r
331 \r
332                         pTop->nPos += iDirection;\r
333                 }\r
334 \r
335                 itrS.Next();\r
336         } while((pElement = itrS.Current()) != NULL);\r
337 \r
338 \r
339         return TRUE;\r
340 }\r