kviewshell
DjVmDir.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063
00064 #include "DjVmDir.h"
00065 #include "BSByteStream.h"
00066 #include "GURL.h"
00067 #include "debug.h"
00068
00069 #include <ctype.h>
00070
00071
00072 #ifdef HAVE_NAMESPACES
00073 namespace DJVU {
00074 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00075 }
00076 #endif
00077 #endif
00078
00079
00080 GP<DjVmDir::File>
00081 DjVmDir::File::create(const GUTF8String &load_name,
00082 const GUTF8String &save_name, const GUTF8String &title,
00083 const FILE_TYPE file_type)
00084 {
00085 File *file_ptr=new File();
00086 GP<File> file=file_ptr;
00087 file_ptr->set_load_name(load_name);
00088 file_ptr->set_save_name(save_name);
00089 file_ptr->set_title(title);
00090 file_ptr->flags=(file_type & TYPE_MASK);
00091 return file;
00092 }
00093
00094 const GUTF8String &
00095 DjVmDir::File::check_save_name(const bool xis_bundled)
00096 {
00097 if(!xis_bundled && !valid_name)
00098 {
00099 GUTF8String retval=name.length()?name:id;
00100 if(GUTF8String(GNativeString(retval)) != retval)
00101 {
00102 const_cast<bool &>(valid_name)=true;
00103 char *buf;
00104 GPBuffer<char> gbuf(buf,2*retval.length()+1);
00105 char *s=buf;
00106 int i=0;
00107 for(char c=retval[i++];c;)
00108 {
00109 static const char hex[]="0123456789ABCDEF";
00110 int len=retval.nextChar(i)-i;
00111 if(len>1 || ((len == 1)&&(c&0x80)))
00112 {
00113 do
00114 {
00115 s++[0]=hex[(c>>4)&0xf];
00116 s++[0]=hex[(c&0xf)];
00117 c=retval[i++];
00118 } while(c && ((--len) > 0));
00119 }else
00120 {
00121 s++[0]=c;
00122 c=retval[i++];
00123 }
00124 }
00125 s++[0]=0;
00126 oldname=retval;
00127 name=buf;
00128 }
00129 const_cast<bool &>(valid_name)=true;
00130 }
00131 return *(name.length()?&name:&id);
00132 }
00133
00134 const GUTF8String &
00135 DjVmDir::File::get_save_name(void) const
00136 {
00137 return *(name.length()?&name:&id);
00138 }
00139
00140 void
00141 DjVmDir::File::set_load_name(const GUTF8String &xid)
00142 {
00143 GURL url=GURL::UTF8(xid);
00144 if(!url.is_valid())
00145 {
00146 url=GURL::Filename::UTF8(xid);
00147 }
00148 id=url.fname();
00149 }
00150
00151 void
00152 DjVmDir::File::set_save_name(const GUTF8String &xname)
00153 {
00154 GURL url;
00155 valid_name=false;
00156 if(!xname.length())
00157 {
00158 GURL url=GURL::UTF8(id);
00159 if(!url.is_valid())
00160 {
00161 name=id;
00162 }else
00163 {
00164 name=url.fname();
00165 }
00166 }else
00167 {
00168 GURL url=GURL::UTF8(xname);
00169 if(!url.is_valid())
00170 {
00171 url=GURL::Filename::UTF8(xname);
00172 }
00173 name=url.fname();
00174 }
00175 oldname="";
00176 }
00177
00178
00179
00180 DjVmDir::File::File(void) : offset(0), size(0), valid_name(false),
00181 flags(0), page_num(-1) { }
00182
00183 GUTF8String
00184 DjVmDir::File::get_str_type(void) const
00185 {
00186 GUTF8String type;
00187 switch(flags & TYPE_MASK)
00188 {
00189 case INCLUDE:
00190 type="INCLUDE";
00191 break;
00192 case PAGE:
00193 type="PAGE";
00194 break;
00195 case THUMBNAILS:
00196 type="THUMBNAILS";
00197 break;
00198 case SHARED_ANNO:
00199 type="SHARED_ANNO";
00200 break;
00201 default:
00202
00203
00204 G_THROW( ERR_MSG("DjVmDir.get_str_type") );
00205 }
00206 return type;
00207 }
00208
00209
00210 const int DjVmDir::version=1;
00211
00212 void
00213 DjVmDir::decode(const GP<ByteStream> &gstr)
00214 {
00215 ByteStream &str=*gstr;
00216 DEBUG_MSG("DjVmDir::decode(): decoding contents of 'DIRM' chunk...\n");
00217 DEBUG_MAKE_INDENT(3);
00218
00219 GCriticalSectionLock lock(&class_lock);
00220
00221 GPosition pos;
00222
00223 files_list.empty();
00224 page2file.resize(-1);
00225 name2file.empty();
00226 id2file.empty();
00227 title2file.empty();
00228
00229 int ver=str.read8();
00230 bool bundled=(ver & 0x80)!=0;
00231 ver&=0x7f;
00232
00233 DEBUG_MSG("DIRM version=" << ver << ", our version=" << version << "\n");
00234 if (ver>version)
00235 G_THROW( ERR_MSG("DjVmDir.version_error") "\t"
00236 + GUTF8String(version) + "\t" + GUTF8String(ver));
00237
00238
00239 DEBUG_MSG("bundled directory=" << bundled << "\n");
00240 DEBUG_MSG("reading the directory records...\n");
00241 int files=str.read16();
00242 DEBUG_MSG("number of files=" << files << "\n");
00243
00244 if (files)
00245 {
00246 DEBUG_MSG("reading offsets (and sizes for ver==0)\n");
00247 for(int nfile=0;nfile<files;nfile++)
00248 {
00249 GP<File> file=new File();
00250 files_list.append(file);
00251 if (bundled)
00252 {
00253 file->offset=str.read32();
00254 if (ver==0)
00255 file->size=str.read24();
00256 if (file->offset==0)
00257 G_THROW( ERR_MSG("DjVmDir.no_indirect") );
00258 } else
00259 {
00260 file->offset=file->size=0;
00261 }
00262 }
00263
00264 GP<ByteStream> gbs_str=BSByteStream::create(gstr);
00265 ByteStream &bs_str=*gbs_str;
00266 if (ver>0)
00267 {
00268 DEBUG_MSG("reading and decompressing sizes...\n");
00269 for(GPosition pos=files_list;pos;++pos)
00270 files_list[pos]->size=bs_str.read24();
00271 }
00272
00273 DEBUG_MSG("reading and decompressing flags...\n");
00274 for(pos=files_list;pos;++pos)
00275 files_list[pos]->flags=bs_str.read8();
00276
00277 if (!ver)
00278 {
00279 DEBUG_MSG("converting flags from version 0...\n");
00280 for(pos=files_list;pos;++pos)
00281 {
00282 unsigned char flags_0=files_list[pos]->flags;
00283 unsigned char flags_1;
00284 flags_1=(flags_0 & File::IS_PAGE_0)?(File::PAGE):(File::INCLUDE);
00285 if (flags_0 & File::HAS_NAME_0)
00286 flags_1|=File::HAS_NAME;
00287 if (flags_0 & File::HAS_TITLE_0)
00288 flags_1|=File::HAS_TITLE;
00289 files_list[pos]->flags=flags_1;
00290 }
00291 }
00292
00293 DEBUG_MSG("reading and decompressing names...\n");
00294 GTArray<char> strings;
00295 char buffer[1024];
00296 int length;
00297 while((length=bs_str.read(buffer, 1024)))
00298 {
00299 int strings_size=strings.size();
00300 strings.resize(strings_size+length-1);
00301 memcpy((char*) strings+strings_size, buffer, length);
00302 }
00303 DEBUG_MSG("size of decompressed names block=" << strings.size() << "\n");
00304
00305
00306 const char * ptr=strings;
00307 for(pos=files_list;pos;++pos)
00308 {
00309 GP<File> file=files_list[pos];
00310
00311 file->id=ptr;
00312 ptr+=file->id.length()+1;
00313 if (file->flags & File::HAS_NAME)
00314 {
00315 file->name=ptr;
00316 ptr+=file->name.length()+1;
00317 } else
00318 {
00319 file->name=file->id;
00320 }
00321 if (file->flags & File::HAS_TITLE)
00322 {
00323 file->title=ptr;
00324 ptr+=file->title.length()+1;
00325 } else
00326 file->title=file->id;
00327
00328
00329
00330
00331 }
00332
00333
00334 int shared_anno_cnt=0;
00335 for(pos=files_list;pos;++pos)
00336 {
00337 if (files_list[pos]->is_shared_anno())
00338 {
00339 shared_anno_cnt++;
00340 }
00341 }
00342 if (shared_anno_cnt>1)
00343 G_THROW( ERR_MSG("DjVmDir.corrupt") );
00344
00345
00346 int pages=0;
00347 for(pos=files_list;pos;++pos)
00348 pages+=files_list[pos]->is_page() ? 1 : 0;
00349 DEBUG_MSG("got " << pages << " pages\n");
00350 page2file.resize(pages-1);
00351 int page_num=0;
00352 for(pos=files_list;pos;++pos)
00353 {
00354 GP<File> file=files_list[pos];
00355 if (file->is_page())
00356 {
00357 page2file[page_num]=file;
00358 file->page_num=page_num++;
00359 }
00360 }
00361
00362
00363 for(pos=files_list;pos;++pos)
00364 {
00365 GP<File> file=files_list[pos];
00366 if (name2file.contains(file->name))
00367 G_THROW( ERR_MSG("DjVmDir.dupl_name") "\t" + file->name );
00368 name2file[file->name]=file;
00369 }
00370
00371
00372 for(pos=files_list;pos;++pos)
00373 {
00374 GP<File> file=files_list[pos];
00375 if (id2file.contains(file->id))
00376 G_THROW( ERR_MSG("DjVmDir.dupl_id") "\t" + file->id);
00377 id2file[file->id]=file;
00378 }
00379
00380
00381 for(pos=files_list;pos;++pos)
00382 {
00383 GP<File> file=files_list[pos];
00384 if (file->title.length())
00385 {
00386 if (title2file.contains(file->title))
00387 G_THROW( ERR_MSG("DjVmDir.dupl_title") "\t" + file->title);
00388 title2file[file->title]=file;
00389 }
00390 }
00391 }
00392 }
00393
00394
00395 void
00396 DjVmDir::encode(const GP<ByteStream> &gstr, const bool do_rename) const
00397 {
00398 bool bundled = true;
00399 GPosition pos = files_list;
00400 if (files_list.size() && !files_list[pos]->offset)
00401 bundled = false;
00402 for (pos=files_list; pos; ++pos)
00403 if ( !bundled != !files_list[pos]->offset)
00404
00405 G_THROW( ERR_MSG("DjVmDir.bad_dir") );
00406
00407 encode(gstr, bundled, do_rename);
00408 }
00409
00410 void
00411 DjVmDir::encode(const GP<ByteStream> &gstr, const bool bundled, const bool do_rename) const
00412 {
00413 ByteStream &str=*gstr;
00414 DEBUG_MSG("DjVmDir::encode(): encoding contents of the 'DIRM' chunk do_rename=" << do_rename << "\n");
00415 DEBUG_MAKE_INDENT(3);
00416
00417 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00418 GPosition pos;
00419
00420 DEBUG_MSG("encoding version number=" << version << ", bundled=" << bundled << "\n");
00421 str.write8(version | ((int) bundled<< 7));
00422
00423 DEBUG_MSG("storing the number of records=" << files_list.size() << "\n");
00424 str.write16(files_list.size());
00425
00426 if (files_list.size())
00427 {
00428
00429 int shared_anno_cnt=0;
00430 for (pos=files_list; pos; ++pos)
00431 if (files_list[pos]->is_shared_anno())
00432 shared_anno_cnt++;
00433 if (shared_anno_cnt>1)
00434 G_THROW( ERR_MSG("DjVmDir.multi_save") );
00435
00436 if (bundled)
00437 {
00438
00439
00440
00441
00442 DEBUG_MSG("storing offsets for every record\n");
00443 for (pos=files_list; pos; ++pos)
00444 {
00445 GP<File> file=files_list[pos];
00446 if (!file->offset)
00447
00448 G_THROW( ERR_MSG("DjVmDir.bad_dir") );
00449 str.write32(file->offset);
00450 }
00451 }
00452
00453 GP<ByteStream> gbs_str=BSByteStream::create(gstr, 50);
00454 ByteStream &bs_str=*gbs_str;
00455 DEBUG_MSG("storing and compressing sizes for every record\n");
00456 for (pos=files_list; pos; ++pos)
00457 {
00458 const GP<File> file(files_list[pos]);
00459 bs_str.write24(file->size);
00460 }
00461 DEBUG_MSG("storing and compressing flags for every record\n");
00462 const bool xdo_rename=(do_rename||!bundled);
00463 for(pos=files_list;pos;++pos)
00464 {
00465 const GP<File> file(files_list[pos]);
00466 if(xdo_rename)
00467 {
00468 const GUTF8String new_id = file->name;
00469 if (! new_id)
00470 if(!file->oldname.length() || file->oldname == new_id)
00471 file->flags &= ~File::HAS_NAME;
00472 else
00473 file->flags |= File::HAS_NAME;
00474 }
00475 else
00476 {
00477 if (!file->name.length() || file->name == file->id)
00478 file->flags &= ~File::HAS_NAME;
00479 else
00480 file->flags |= File::HAS_NAME;
00481 }
00482 if (file->title.length() && (file->title!=file->id))
00483 file->flags |= File::HAS_TITLE;
00484 else
00485 file->flags &= ~File::HAS_TITLE;
00486
00487 bs_str.write8(file->flags);
00488 }
00489
00490 DEBUG_MSG("storing and compressing names...\n");
00491 for(pos=files_list;pos;++pos)
00492 {
00493 GP<File> file=files_list[pos];
00494 GUTF8String id;
00495 GUTF8String name;
00496 GUTF8String title;
00497 if (xdo_rename)
00498 {
00499 id = file->name;
00500 if (! id)
00501 id = file->id;
00502 if ((file->flags) & File::HAS_NAME)
00503 name = file->oldname;
00504 }
00505 else
00506 {
00507 id=file->id;
00508 if ((file->flags) & File::HAS_NAME)
00509 name = file->name;
00510 }
00511 if ((file->flags) & File::HAS_TITLE)
00512 title = file->title;
00513 DEBUG_MSG("rename=" <<xdo_rename<<" id='" << id << "' name='" << name << "' title='" << title << "'\n");
00514 bs_str.writestring(id);
00515 bs_str.write8(0);
00516 if (name.length())
00517 {
00518 bs_str.writestring(name);
00519 bs_str.write8(0);
00520 }
00521 if (title.length())
00522 {
00523 bs_str.writestring(title);
00524 bs_str.write8(0);
00525 }
00526 }
00527 }
00528 DEBUG_MSG("done\n");
00529 }
00530
00531 GP<DjVmDir::File>
00532 DjVmDir::page_to_file(int page_num) const
00533 {
00534 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00535
00536 return (page_num<page2file.size())?page2file[page_num]:(GP<DjVmDir::File>(0));
00537 }
00538
00539 GP<DjVmDir::File>
00540 DjVmDir::name_to_file(const GUTF8String & name) const
00541 {
00542 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00543
00544 GPosition pos;
00545 return (name2file.contains(name, pos))?name2file[pos]:(GP<DjVmDir::File>(0));
00546 }
00547
00548 GP<DjVmDir::File>
00549 DjVmDir::id_to_file(const GUTF8String &id) const
00550 {
00551 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00552
00553 GPosition pos;
00554 return (id2file.contains(id, pos))?id2file[pos]:(GP<DjVmDir::File>(0));
00555 }
00556
00557 GP<DjVmDir::File>
00558 DjVmDir::title_to_file(const GUTF8String &title) const
00559 {
00560 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00561
00562 GPosition pos;
00563 return (title2file.contains(title, pos))?title2file[pos]:(GP<DjVmDir::File>(0));
00564 }
00565
00566 GPList<DjVmDir::File>
00567 DjVmDir::get_files_list(void) const
00568 {
00569 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00570 return files_list;
00571 }
00572
00573 int
00574 DjVmDir::get_files_num(void) const
00575 {
00576 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00577 return files_list.size();
00578 }
00579
00580 int
00581 DjVmDir::get_pages_num(void) const
00582 {
00583 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00584 return page2file.size();
00585 }
00586
00587 int
00588 DjVmDir::get_file_pos(const File * f) const
00589 {
00590 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00591 int cnt;
00592 GPosition pos;
00593 for(pos=files_list, cnt=0;pos&&(files_list[pos]!=f);++pos, cnt++)
00594 continue;
00595 return (pos)?cnt:(-1);
00596 }
00597
00598 int
00599 DjVmDir::get_page_pos(int page_num) const
00600 {
00601 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00602
00603 GP<File> file=page_to_file(page_num);
00604 return (file)?get_file_pos(file):(-1);
00605 }
00606
00607 GP<DjVmDir::File>
00608 DjVmDir::get_shared_anno_file(void) const
00609 {
00610 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00611
00612 GP<File> file;
00613 for(GPosition pos=files_list;pos;++pos)
00614 {
00615 GP<File> frec=files_list[pos];
00616 if (frec->is_shared_anno())
00617 {
00618 file=frec;
00619 break;
00620 }
00621 }
00622 return file;
00623 }
00624
00625 int
00626 DjVmDir::insert_file(const GP<File> & file, int pos_num)
00627 {
00628 DEBUG_MSG("DjVmDir::insert_file(): name='" << file->name << "', pos=" << pos_num << "\n");
00629 DEBUG_MAKE_INDENT(3);
00630
00631 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00632
00633 if (pos_num<0)
00634 pos_num=files_list.size();
00635
00636
00637
00638
00639 if (id2file.contains(file->id))
00640 G_THROW( ERR_MSG("DjVmDir.dupl_id2") "\t" + file->id);
00641 if (name2file.contains(file->name))
00642 G_THROW( ERR_MSG("DjVmDir.dupl_name2") "\t" + file->name);
00643 name2file[file->name]=file;
00644 id2file[file->id]=file;
00645 if (file->title.length())
00646 {
00647 if (title2file.contains(file->title))
00648 G_THROW( ERR_MSG("DjVmDir.dupl_title2") "\t" + file->title);
00649 title2file[file->title]=file;
00650 }
00651
00652
00653 if (file->is_shared_anno())
00654 {
00655 for(GPosition pos=files_list;pos;++pos)
00656 if (files_list[pos]->is_shared_anno())
00657 G_THROW( ERR_MSG("DjVmDir.multi_save2") );
00658 }
00659
00660
00661 int cnt;
00662 GPosition pos;
00663 for(pos=files_list, cnt=0;pos&&(cnt!=pos_num);++pos, cnt++)
00664 continue;
00665 if (pos)
00666 files_list.insert_before(pos, file);
00667 else
00668 files_list.append(file);
00669
00670 if (file->is_page())
00671 {
00672
00673
00674 int page_num=0;
00675 for(pos=files_list;pos;++pos)
00676 {
00677 GP<File> &f=files_list[pos];
00678 if (f==file)
00679 break;
00680 if (f->is_page())
00681 page_num++;
00682 }
00683
00684 int i;
00685 page2file.resize(page2file.size());
00686 for(i=page2file.size()-1;i>page_num;i--)
00687 page2file[i]=page2file[i-1];
00688 page2file[page_num]=file;
00689 for(i=page_num;i<page2file.size();i++)
00690 page2file[i]->page_num=i;
00691 }
00692 return pos_num;
00693 }
00694
00695 void
00696 DjVmDir::delete_file(const GUTF8String &id)
00697 {
00698 DEBUG_MSG("Deleting file with id='" << (const char *)id << "'\n");
00699 DEBUG_MAKE_INDENT(3);
00700
00701 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00702
00703 for(GPosition pos=files_list;pos;++pos)
00704 {
00705 GP<File> & f=files_list[pos];
00706 if (id == f->id)
00707 {
00708 name2file.del(f->name);
00709 id2file.del(f->id);
00710 title2file.del(f->title);
00711 if (f->is_page())
00712 {
00713 for(int page=0;page<page2file.size();page++)
00714 {
00715 if (page2file[page]==f)
00716 {
00717 int i;
00718 for(i=page;i<page2file.size()-1;i++)
00719 page2file[i]=page2file[i+1];
00720 page2file.resize(page2file.size()-2);
00721 for(i=page;i<page2file.size();i++)
00722 page2file[i]->page_num=i;
00723 break;
00724 }
00725 }
00726 }
00727 files_list.del(pos);
00728 break;
00729 }
00730 }
00731 }
00732
00733 void
00734 DjVmDir::set_file_name(const GUTF8String &id, const GUTF8String &name)
00735 {
00736 DEBUG_MSG("DjVmDir::set_file_name(): id='" << id << "', name='" << name << "'\n");
00737 DEBUG_MAKE_INDENT(3);
00738
00739 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00740
00741 GPosition pos;
00742
00743
00744 for(pos=files_list;pos;++pos)
00745 {
00746 GP<File> file=files_list[pos];
00747 if (file->id!=id && file->name==name)
00748 G_THROW( ERR_MSG("DjVmDir.name_in_use") "\t" + GUTF8String(name));
00749 }
00750
00751
00752 if (!id2file.contains(id, pos))
00753 G_THROW( ERR_MSG("DjVmDir.no_info") "\t" + GUTF8String(id));
00754 GP<File> file=id2file[pos];
00755 name2file.del(file->name);
00756 file->name=name;
00757 name2file[name]=file;
00758 }
00759
00760 void
00761 DjVmDir::set_file_title(const GUTF8String &id, const GUTF8String &title)
00762 {
00763 DEBUG_MSG("DjVmDir::set_file_title(): id='" << id << "', title='" << title << "'\n");
00764 DEBUG_MAKE_INDENT(3);
00765
00766 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00767
00768 GPosition pos;
00769
00770
00771 for(pos=files_list;pos;++pos)
00772 {
00773 GP<File> file=files_list[pos];
00774 if (file->id!=id && file->title==title)
00775 G_THROW( ERR_MSG("DjVmDir.title_in_use") "\t" + GUTF8String(title));
00776 }
00777
00778
00779 if (!id2file.contains(id, pos))
00780 G_THROW( ERR_MSG("DjVmDir.no_info") "\t" + GUTF8String(id));
00781 GP<File> file=id2file[pos];
00782 title2file.del(file->title);
00783 file->title=title;
00784 title2file[title]=file;
00785 }
00786
00787 GPList<DjVmDir::File>
00788 DjVmDir::resolve_duplicates(const bool save_as_bundled)
00789 {
00790 GCriticalSectionLock lock((GCriticalSection *) &class_lock);
00791
00792 GPosition pos;
00793 GMap<GUTF8String,void *> save_map;
00794 GMap<GUTF8String,GPList<DjVmDir::File> > conflicts;
00795 for(pos=files_list;pos;++pos)
00796 {
00797 const GUTF8String save_name=files_list[pos]->check_save_name(save_as_bundled).downcase();
00798 if(save_map.contains(save_name))
00799 {
00800 conflicts[save_name].append(files_list[pos]);
00801 }else
00802 {
00803 save_map[save_name]=0;
00804 }
00805 }
00806 for(pos=conflicts;pos;++pos)
00807 {
00808 const GUTF8String &save_name=conflicts.key(pos);
00809 const int dot=save_name.rsearch('.',0);
00810 GPList<DjVmDir::File> &cfiles=conflicts[pos];
00811 int count=1;
00812 for(GPosition qpos=cfiles;qpos;++qpos)
00813 {
00814 GUTF8String new_name=cfiles[qpos]->get_load_name();
00815 if((new_name != GUTF8String(GNativeString(new_name)))
00816 ||conflicts.contains(new_name))
00817 {
00818 do
00819 {
00820 new_name=(dot<0)
00821 ?(save_name+"-"+GUTF8String(count++))
00822 :(save_name.substr(0,dot)+"-"+GUTF8String(count++)+
00823 save_name.substr(dot,(unsigned int)(-1)));
00824 } while(save_map.contains(new_name.downcase()));
00825 }
00826 cfiles[qpos]->set_save_name(new_name);
00827 save_map[new_name]=0;
00828 }
00829 }
00830 return files_list;
00831 }
00832
00833
00834 #ifdef HAVE_NAMESPACES
00835 }
00836 # ifndef NOT_USING_DJVU_NAMESPACE
00837 using namespace DJVU;
00838 # endif
00839 #endif