Develop and Download Open Source Software

Browse CVS Repository

Contents of /malonnote/mnModel.cpp

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


Revision 1.23 - (show annotations) (download) (as text)
Thu Sep 15 09:20:48 2005 UTC (18 years, 6 months ago) by maloninc
Branch: MAIN
CVS Tags: dev_1_3-0005
Changes since 1.22: +121 -47 lines
File MIME type: text/x-c++src
implement effective update, but it's incomplete. (9/15)

1 #include "mnDef.h"
2 #include "mnModel.h"
3 #include <wx/dir.h>
4 #include <wx/regex.h>
5 #include <iconv.h>
6
7 static void toLower(char* string);
8 static char* decode(const char* string);
9 static char* encode(const char* string);
10 static int compWikiData(const void* wiki1, const void* wiki2);
11
12
13 /******* WikiList ************************/
14 #include <wx/listimpl.cpp>
15 WX_DEFINE_LIST(WikiList);
16
17
18 /******* mnModel ************************/
19
20 mnModel::mnModel(const char* dataDir)
21 {
22 wxCSConv conv(wxT(CODE_SET_SYSTEM));
23
24 wikiDataDir = new wxString(dataDir, conv);
25 searchStrList = new wxArrayString();
26 }
27
28 mnModel::~mnModel()
29 {
30 delete wikiDataDir;
31 }
32
33 /*
34 * iconv encode and create token list,
35 * so you must free tokenLis after you used
36 *
37 * if failed to make token list, return FALSE.
38 */
39 bool mnModel::makeSearchToken(const char* searchStr, char* tokenList[])
40 {
41 iconv_t codeSet;
42 char outbuf[MAX_BUF_SIZE];
43 const char* inbufPtr = searchStr;
44 char* outbufPtr = outbuf;
45 int inbufSize = strlen(searchStr);
46 int outbufSize = sizeof(outbuf);
47 char* token;
48 int i;
49
50 memset(outbuf, 0, outbufSize);
51 codeSet = iconv_open(CODE_SET_EUC_JP, CODE_SET_SYSTEM);
52 if(codeSet == (iconv_t)-1) {
53 MN_FATAL_ERROR(wxT("failed iconv_open"));
54 }
55 iconv(codeSet, (ICONV_CONST char**)&inbufPtr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
56 iconv_close(codeSet);
57
58 /* searchStr to Tokens */
59 token = strtok(outbuf, " ");
60 if(token == NULL) return false;
61 tokenList[0] = (char*)malloc(strlen(token)+1);
62 snprintf(tokenList[0], strlen(token)+1, "%s", token);
63 i = 1;
64 while((token = strtok(NULL, " ")) != NULL) {
65 tokenList[i] = (char*)malloc(strlen(token)+1);
66 snprintf(tokenList[i], strlen(token)+1, "%s", token);
67 i++;
68 }
69 return true;
70 }
71
72 bool mnModel::matchWithToken(wxString* fileName, char* tokenList[])
73 {
74 const char* decodeFileName;
75 char decodeFileNameBuf[MAX_BUF_SIZE];
76 wxString fullPathName;
77 FILE* fp;
78 bool ans = false;
79 bool found;
80
81 fullPathName = *wikiDataDir + wxT("/") + *fileName;
82 fp = fopen((const char*)fullPathName.mb_str(), "r");
83 if(fp == NULL) {
84 MN_FATAL_ERROR(wxT("fopen faild"));
85 }
86
87 /* TYPE search */
88 if(strstr(tokenList[0], TYPESEARCH_TAG) == tokenList[0])
89 {
90 found = typeSearch(tokenList[0], fp);
91 if(found){
92 ans = true;
93 }
94 }
95 /* Normal search */
96 else{
97 decodeFileName = decode(fileName->mb_str());
98 snprintf(decodeFileNameBuf, MAX_BUF_SIZE, "%s", decodeFileName);
99 toLower(decodeFileNameBuf);
100 found = normalSearch(tokenList, fp, decodeFileNameBuf);
101 if(found){
102 ans = true;
103 }
104 }
105 fclose(fp);
106
107 return ans;
108 }
109
110 WikiList* mnModel::search(const char* searchStr)
111 {
112 int i;
113 wxDir* dir;
114 WikiData* wikiData;
115 WikiList* list = new WikiList();
116 wxString* fileName = new wxString();
117 char* tokenList[32];
118
119 memset(tokenList, 0, sizeof(char*)*32);
120 if( makeSearchToken(searchStr, tokenList) == false) return list;
121
122 dir = new wxDir(*wikiDataDir);
123 if ( !dir->IsOpened() )
124 {
125 MN_FATAL_ERROR(wxT("wxDir has faild\n"));
126 return NULL;
127 }
128
129 bool cont = dir->GetFirst(fileName, wxT("*.txt"), wxDIR_FILES);
130 while(cont){
131
132 if( matchWithToken(fileName, tokenList) ) { /* match with token list */
133 wikiData = new WikiData(wikiDataDir, fileName);
134 list->Append(wikiData);
135 }
136
137 cont = dir->GetNext(fileName);
138 }
139
140 delete dir;
141 delete fileName;
142 for(i = 0; tokenList[i] != NULL; i++) free(tokenList[i]);
143
144 list->Sort(compWikiData);
145 return list;
146 }
147
148 void mnModel::group()
149 {
150 wxCSConv conv(wxT(CODE_SET_SYSTEM));
151 char buf[MAX_BUF_SIZE];
152 wxDir* dir;
153 FILE* fp;
154 wxString* fileName = new wxString();
155 wxString fullPathName;
156 int typeTagLen = strlen(TYPE_TAG);
157 char* token;
158 char* inbufPtr;
159 int inbufSize;
160 char outbuf[MAX_BUF_SIZE];
161 char* outbufPtr = outbuf;
162 int outbufSize;
163 wxString* typeToken;
164 char* ptr;
165 int i;
166
167 iconv_t codeSet = iconv_open(CODE_SET_SYSTEM, CODE_SET_EUC_JP);
168 if(codeSet == (iconv_t)-1) {
169 MN_FATAL_ERROR(wxT("failed iconv_open"));
170 }
171
172 dir = new wxDir(*wikiDataDir);
173 if ( !dir->IsOpened() )
174 {
175 MN_FATAL_ERROR(wxT("wxDir has faild\n"));
176 return ;
177 }
178 bool cont = dir->GetFirst(fileName, wxT("*.txt"), wxDIR_FILES);
179 while(cont){
180 fullPathName = *wikiDataDir + wxT("/") + *fileName;
181 fp = fopen((const char*)fullPathName.mb_str(), "r");
182 if(fp == NULL) {
183 MN_FATAL_ERROR(wxT("fopen faild"));
184 }
185 while(1) {
186 memset(buf, 0, MAX_BUF_SIZE);
187 fgets(buf, MAX_BUF_SIZE, fp);
188 if(buf[0] == 0) break;
189 if(strstr(buf, TYPE_TAG)){
190 ptr = &buf[typeTagLen];
191 while((token = strtok(ptr, " /\r\n:"))!= NULL) {
192 memset(outbuf, 0, MAX_BUF_SIZE);
193 snprintf(outbuf, MAX_BUF_SIZE, "%s", TYPESEARCH_TAG);
194 inbufPtr = token;
195 inbufSize = strlen(token);
196 outbufPtr = &outbuf[strlen(TYPESEARCH_TAG)];
197 outbufSize = sizeof(outbuf) - strlen(TYPESEARCH_TAG);
198 iconv(codeSet, (ICONV_CONST char**)&inbufPtr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
199
200 typeToken = new wxString(outbuf, conv);
201 addSearchStr(typeToken);
202 delete typeToken;
203 ptr = NULL;
204 }
205 }
206 }
207 fclose(fp);
208 cont = dir->GetNext(fileName);
209 }
210 delete dir;
211 delete fileName;
212 iconv_close(codeSet);
213 }
214
215 bool mnModel::normalSearch(char* tokenList[], FILE*fp, char* decodeFileNameBuf)
216 {
217 char buf[MAX_BUF_SIZE];
218 bool found;
219 int i;
220 while(1){
221 memset(buf, 0, MAX_BUF_SIZE);
222 fread(buf, MAX_BUF_SIZE-1, 1, fp);
223 if(buf[0] == 0) break;
224 toLower(buf);
225 found = TRUE;
226 for(i = 0; tokenList[i] != NULL; i++){
227 toLower(tokenList[i]);
228 if(strstr((const char*)buf, (const char*)tokenList[i]) || /* search in file context */
229 strstr((const char*)decodeFileNameBuf, (const char*)tokenList[i]) || /* search in file name */
230 strcmp((const char*)tokenList[i], (const char*)ALLMEMO_TAG) == 0) { /* SHOW ALL MEMO */
231 found = TRUE;
232 }
233 else {
234 found = FALSE;
235 break;
236 }
237 }
238
239 if(found){ /* all tokens found */
240 break;
241 }
242 buf[0] = 0;
243 }
244
245 return found;
246 }
247
248 bool mnModel::typeSearch(char* typeStr, FILE*fp)
249 {
250 char buf[MAX_BUF_SIZE];
251 bool found;
252 int i;
253 char* typeToken;
254 char typeStrCopy[MAX_BUF_SIZE];
255
256 snprintf(typeStrCopy, MAX_BUF_SIZE, "%s", typeStr);
257 while(1){
258 memset(buf, 0, MAX_BUF_SIZE);
259 fgets(buf, MAX_BUF_SIZE, fp);
260 if(buf[0] == 0) break;
261 if(strstr((const char*)buf, TYPE_TAG)){ /* search TYPE line */
262 typeToken = strtok(typeStrCopy, ":");
263 typeToken = strtok(NULL, ":"); /* second field separated by colon(:) */
264 if(typeToken == NULL) return false;
265 toLower(typeToken);
266 toLower(buf);
267 if(strstr(buf, typeToken)) return true;
268 }
269 }
270 return false;
271 }
272
273 void mnModel::addSearchStr(wxString* searchStr)
274 {
275 wxString *string;
276
277 if(searchStrList->Index(searchStr->c_str()) == wxNOT_FOUND){
278 string = new wxString(searchStr->c_str());
279 searchStrList->Add(*string, 1);
280 //searchStrList->Insert(*string, 0);
281 }
282 }
283
284 void mnModel::addSearchList(wxString* searchStr, WikiList* list)
285 {
286 wikiHash[*searchStr] = list;
287 }
288
289 void mnModel::removeSearchStr(wxString searchStr)
290 {
291 if(searchStrList->Index(searchStr.c_str()) != wxNOT_FOUND) {
292 searchStrList->Remove(searchStr.c_str());
293 }
294 }
295
296 void mnModel::modSearchStr(wxString* oldStr, wxString* newStr)
297 {
298 int index;
299
300 if((index = searchStrList->Index(oldStr->c_str())) != wxNOT_FOUND){
301 wxString& itemStr = searchStrList->Item(index);
302 itemStr.sprintf(wxT("%s"), newStr->c_str());
303 }
304 }
305 const wxString* mnModel::getWikiDataDir()
306 {
307 return wikiDataDir;
308 }
309
310 const wxArrayString* mnModel::getSearchStrList()
311 {
312 return searchStrList;
313 }
314
315 WikiData* mnModel::newWikiData()
316 {
317 WikiData* data = new WikiData(wikiDataDir);
318
319 return data;
320 }
321 const WikiList* mnModel::getSearchResultList(wxString* searchStr)
322 {
323 return wikiHash[*searchStr];
324 }
325
326 /* add "addData's" clone. if already exist same data, overwrite it*/
327 void mnModel::addSearchResultList(wxString* searchStr, WikiData* addData)
328 {
329 WikiList* wikiList = wikiHash[*searchStr];
330 WikiList::Node* node;
331 WikiData* data;
332
333 node = wikiList->GetFirst();
334 if(!node) {
335 MN_FATAL_ERROR(wxT("Search Result List is empty"));
336 }
337
338 while(node) {
339 data = node->GetData();
340 if(data == addData) return;
341 if( *(data->getSubject()) == *(addData->getSubject()) ) {
342 if(wikiList->DeleteObject(data)) {
343 delete data;
344 break;
345 }
346 else {
347 MN_FATAL_ERROR(wxT("Can't find delete data"));
348 }
349 }
350 node = node->GetNext();
351 }
352 WikiData* copy = new WikiData((wxString*)wikiDataDir, (wxString*)addData->getFileName());
353 wikiList->Append(copy);
354 wikiList->Sort(compWikiData);
355 }
356
357 /******* WikiData ************************/
358 WikiData::WikiData(wxString* dataDir, wxString* inFileName)
359 {
360 FILE* fp;
361 wxString fullPathName;
362 char* decodeStr;
363 char buf[MAX_BUF_SIZE];
364 char* inbuf;
365 int inbufSize;
366 char outbuf[MAX_BUF_SIZE];
367 char* outbufPtr = outbuf;
368 int outbufSize;
369 wxCSConv conv(wxT(CODE_SET_SYSTEM));
370
371 iconv_t codeSet = iconv_open(CODE_SET_SYSTEM, CODE_SET_EUC_JP);
372 if(codeSet == (iconv_t)-1) {
373 MN_FATAL_ERROR(wxT("failed iconv_open"));
374 }
375
376 text = NULL;
377 memset(outbuf, 0, MAX_BUF_SIZE);
378 fileName = new wxString(*inFileName);
379 dataDirName = dataDir;
380 decodeStr = decode(fileName->mb_str());
381 inbufSize = strlen(decodeStr);
382 outbufSize = sizeof(outbuf);
383 iconv(codeSet, (ICONV_CONST char**)&decodeStr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
384 subject = new wxString((const char*)outbuf, conv);
385 iconv_close(codeSet);
386
387 date = NULL;
388
389 fullPathName = *dataDir + wxT("/") + *fileName;
390 fp = fopen((const char*)fullPathName.mb_str(), "r");
391 if(fp == NULL) {
392 MN_FATAL_ERROR(wxT("fopen faild"));
393 }
394 while(fgets(buf, MAX_BUF_SIZE, fp)) {
395 if(strstr( (const char*)buf, (const char*)DATE_TAG)) {
396 strtok(buf, "\n");
397 strtok(buf, "\r");
398 date = new wxString((const char*)buf, conv);
399 break;
400 }
401 }
402 fclose(fp);
403 }
404
405 WikiData::WikiData(wxString* dataDir) {
406 time_t now;
407 char buf[MAX_BUF_SIZE];
408 wxCSConv conv(wxT(CODE_SET_SYSTEM));
409
410 dataDirName = dataDir;
411
412 time(&now);
413 memset(buf, 0, sizeof(buf));
414 strftime(buf, sizeof(buf), "%Y/%m/%d-%H%M%S",localtime(&now));
415 subject = new wxString(buf, conv);
416
417 fileName = new wxString(encode(buf), conv);
418 fileName->Append(wxT(EXT_TAG));
419
420 memset(buf, 0, sizeof(buf));
421 strftime(buf, sizeof(buf), DATE_TAG "%Y/%m/%d %H:%M:%S",localtime(&now));
422 date = new wxString(buf, conv);
423
424 memset(buf, 0, sizeof(buf));
425 strftime(buf, sizeof(buf), NEW_DATA,localtime(&now));
426 text = new wxString(buf, conv);
427
428 }
429
430 WikiData::~WikiData()
431 {
432 delete subject;
433 delete fileName;
434 delete date;
435 delete text;
436 }
437
438 const wxString* WikiData::getFileName()
439 {
440 return fileName;
441 }
442
443 const wxString* WikiData::getSubject()
444 {
445 return subject;
446 }
447
448 void WikiData::modSubject(wxString* newSubject)
449 {
450 wxCSConv conv(wxT(CODE_SET_SYSTEM));
451 wxString* oldFileName = fileName;
452 wxString* oldSubject = subject;
453 char oldFullPath[MAX_BUF_SIZE];
454 char newFullPath[MAX_BUF_SIZE];
455 iconv_t codeSet;
456 char outbuf[MAX_BUF_SIZE];
457 char inbuf[MAX_BUF_SIZE];
458 const char* inbufPtr = inbuf;
459 char* outbufPtr = outbuf;
460 int inbufSize;
461 int outbufSize = sizeof(outbuf);
462 FILE* fp;
463
464 memset(outbuf, 0, outbufSize);
465 memset(inbuf, 0, sizeof(inbuf));
466 strcpy(inbuf, (const char*)newSubject->mb_str());
467 inbufSize = strlen(inbuf);
468 codeSet = iconv_open(CODE_SET_EUC_JP, CODE_SET_SYSTEM);
469 if(codeSet == (iconv_t)-1) {
470 MN_FATAL_ERROR(wxT("failed iconv_open"));
471 }
472 iconv(codeSet, (ICONV_CONST char**)&inbufPtr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
473 iconv_close(codeSet);
474 subject = new wxString(newSubject->c_str());
475 fileName = new wxString(encode(outbuf), conv);
476 fileName->Append(wxT(EXT_TAG));
477
478 sprintf(oldFullPath, "%s/%s", (const char*)dataDirName->mb_str(), (const char*)oldFileName->mb_str());
479 sprintf(newFullPath, "%s/%s", (const char*)dataDirName->mb_str(), (const char*)fileName->mb_str());
480
481 if((fp = fopen(newFullPath, "r")) == NULL) {
482 if(rename(oldFullPath, newFullPath) < 0) wxLogMessage(wxT("rename error: errno=[%d]"), errno);
483 }
484 else if(strcmp(oldFullPath, newFullPath)){
485 wxLogMessage(wxT("File has already exist. [%s]"), fileName->c_str());
486 fclose(fp);
487 }
488 else {
489 fclose(fp);
490 }
491
492 delete oldSubject;
493 delete oldFileName;
494 }
495
496 const wxString* WikiData::getDate()
497 {
498 return date;
499 }
500
501
502 const wxString* WikiData::getText()
503 {
504 FILE* fp;
505 char buf[MAX_BUF_SIZE];
506 char fullPath[MAX_BUF_SIZE];
507 iconv_t codeSet;
508 char outbuf[MAX_BUF_SIZE];
509 char* inbufPtr;
510 char* outbufPtr;
511 int inbufSize;
512 int outbufSize;
513 wxCSConv conv(wxT(CODE_SET_SYSTEM));
514 wxString* tmpStr;
515
516 codeSet = iconv_open(CODE_SET_SYSTEM, CODE_SET_EUC_JP);
517 if(codeSet == (iconv_t)-1) {
518 MN_FATAL_ERROR(wxT("failed iconv_open"));
519 }
520
521 if(text) {
522 iconv_close(codeSet);
523 return text;
524 }
525
526 text = new wxString();
527 sprintf(fullPath, "%s/%s", (const char*)dataDirName->mb_str(), (const char*)fileName->mb_str());
528 fp = fopen(fullPath, "r");
529 if(fp == NULL) {
530 MN_FATAL_ERROR(wxT("File open error."));
531 }
532
533 while(fgets(buf, MAX_BUF_SIZE, fp)) {
534 #ifdef __WXMAC__
535 for(int i = 0; buf[i] != 0; i++) if(buf[i] == (char)MAC_BACKSLASH) buf[i] = '\\';
536 #endif
537 inbufPtr = buf;
538 inbufSize = sizeof(buf);
539 outbufPtr = outbuf;
540 outbufSize = sizeof(outbuf);
541 memset(outbuf, 0, outbufSize);
542 iconv(codeSet, (ICONV_CONST char**)&inbufPtr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
543 tmpStr = new wxString((char*)outbuf, conv);
544 *text += *tmpStr;
545 delete tmpStr;
546 }
547 iconv_close(codeSet);
548 fclose(fp);
549
550 return text;
551 }
552
553 void WikiData::modText(wxString* intext)
554 {
555 wxCSConv conv(wxT(CODE_SET_SYSTEM));
556 delete text;
557 //text = new wxString(intext->c_str());
558 text = new wxString(*intext);
559 //text = new wxString(intext->mb_str(), conv);
560 }
561
562 void WikiData::removeDataFile()
563 {
564 char fullPath[MAX_BUF_SIZE];
565
566 sprintf(fullPath, "%s/%s", (const char*)dataDirName->mb_str(), (const char*)fileName->mb_str());
567 if(remove(fullPath)) {
568 MN_FATAL_ERROR(wxT("remove file error"));
569 }
570 }
571
572 void WikiData::save()
573 {
574 char fullPath[MAX_BUF_SIZE];
575 FILE* fp;
576 iconv_t codeSet;
577 char inbuf[MAX_WIKI_TEXT_SIZE];
578 char outbuf[MAX_WIKI_TEXT_SIZE];
579 const char* inbufPtr;
580 char* outbufPtr;
581 int inbufSize;
582 int outbufSize;
583
584 codeSet = iconv_open(CODE_SET_EUC_JP, CODE_SET_SYSTEM);
585 if(codeSet == (iconv_t)-1) {
586 MN_FATAL_ERROR(wxT("failed iconv_open"));
587 }
588
589 sprintf(fullPath, "%s/%s", (const char*)dataDirName->mb_str(), (const char*)fileName->mb_str());
590 fp = fopen(fullPath, "wb");
591 if(fp == NULL) {
592 MN_FATAL_ERROR(wxT("File open error."));
593 }
594
595 memset(inbuf, 0, sizeof(inbuf));
596 strcpy(inbuf,(const char*)text->mb_str());
597
598 #ifdef __WXMAC__
599 for(int i = 0; inbuf[i] != 0; i++) if(inbuf[i] == (char)MAC_BACKSLASH) inbuf[i] = '\\';
600 #endif
601
602 inbufPtr = inbuf;
603 inbufSize = strlen(inbufPtr);
604 outbufPtr = outbuf;
605 outbufSize = sizeof(outbuf);
606 memset(outbuf, 0, outbufSize);
607 iconv(codeSet, (ICONV_CONST char**)&inbufPtr, (size_t*)&inbufSize, &outbufPtr, (size_t*)&outbufSize);
608 fwrite(outbuf, sizeof(outbuf)-outbufSize, 1, fp);
609 fclose(fp);
610 iconv_close(codeSet);
611 }
612
613 /******* Tools ************************/
614
615 static void toLower(char* string)
616 {
617 int i;
618
619 for(i = 0; string[i] != 0; i++) {
620 string[i] = tolower(string[i]);
621 }
622 }
623
624
625 static char* decode(const char* string)
626 {
627 static char buf[MAX_BUF_SIZE];
628 char c[5];
629 int i,j;
630 char* endPtr = NULL;
631
632 j = 0;
633 memset(buf, 0, MAX_BUF_SIZE);
634 for(i = 0; string[i] != 0; i+=2) {
635 c[0] = '0'; c[1] = 'x';
636 c[2] = string[i]; c[3] = string[i+1]; c[4] = 0;
637 buf[j] = strtol(c, &endPtr, 0);
638 j++;
639 if(j >= MAX_BUF_SIZE) {
640 buf[MAX_BUF_SIZE] = 0;
641 break;
642 }
643 }
644
645 return buf;
646 }
647
648 static char* encode(const char* string)
649 {
650 static char buf[MAX_BUF_SIZE];
651 int i,j;
652
653 j = 0;
654 memset(buf, 0, MAX_BUF_SIZE);
655 for(i = 0; string[i] != 0; i++) {
656 snprintf(&buf[j], 3, "%02X", (unsigned char)(string[i]));
657 j+=2;
658 if(j >= MAX_BUF_SIZE) {
659 buf[MAX_BUF_SIZE] = 0;
660 break;
661 }
662 }
663 return buf;
664 }
665
666 /*
667 * wiki1 > wiki2 -> return < 0
668 * wiki1 = wiki2 -> return = 0
669 * wiki1 < wiki2 -> return > 0
670 */
671 static int compWikiData(const void* wiki1, const void* wiki2)
672 {
673 WikiData* data1 = *(WikiData**)wiki1;
674 WikiData* data2 = *(WikiData**)wiki2;
675 const wxString* str1 = NULL;
676 const wxString* str2 = NULL;
677
678 str1 = data1->getDate();
679 str2 = data2->getDate();
680
681 if(str1 != NULL && str2 != NULL) {
682 return (strcmp(str2->mb_str(), str1->mb_str()));
683 }
684 else{
685 return 0;
686 }
687 }
688

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