"Fossies" - the Fresh Open Source Software Archive

Member "mapgenerator-1.1.2/src/htmlfile.cpp" (26 Oct 2003, 24947 Bytes) of package /linux/www/old/mapgenerator-1.1.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "htmlfile.cpp" see the Fossies "Dox" file reference documentation.

    1 //
    2 // File: htmlfile.h
    3 // Created by:  <>
    4 // Created on: Tue Aug 19 17:58:02 2003
    5 // under the terms of the GPL version 2.0 or higher
    6 
    7 #include "htmlfile.h"
    8 #include <iostream>
    9 #include <errno.h>
   10 using namespace std;
   11 
   12 #ifdef DEBUG
   13 #define LINE() cout << "line: " << __LINE__ << endl;
   14 #define exit(X) \
   15 {\
   16 cout << "Errorcode: " << #X << endl;\
   17 cout << "Line: " << __LINE__ << "\nFile: " << __FILE__ << endl;\
   18 exit(X);\
   19 }
   20 #else
   21 #define LINE()
   22 #define exit(X) exit((int)#X)
   23 #endif
   24 
   25 htmlfile::htmlfile()
   26 {
   27 #ifdef DEBUG
   28     cout << "htmlfile() line: " << __LINE__ << endl;
   29 #endif
   30     state=0;
   31     write=false;
   32 }
   33 
   34 
   35 htmlfile::~htmlfile(){
   36 #ifdef DEBUG
   37     cout << "~htmlfile() line: " << __LINE__ << endl;
   38 #endif
   39 }
   40 
   41 void htmlfile::edit_cb(Fl_Widget*,void* o){
   42 #ifdef DEBUG
   43     cout << "edit_cb() line: " << __LINE__ << endl;
   44 #endif
   45     ((htmlfile*)o)->edit_call();
   46 }
   47 
   48 void htmlfile::edit_call(){
   49 #ifdef DEBUG
   50     cout << "edit_call() line: " << __LINE__ << endl;
   51 #endif
   52     img_selected=Image_select->value();
   53     close_img_select=true;
   54 }
   55 
   56 bool htmlfile::equal_string(const std::string & str1,const std::string & str2){
   57     int len1=str1.length();
   58     int len2=str2.length();
   59     char buf1,buf2;
   60     if(len1!=len2) return false;
   61     for(int i=0;i<len1;i++){
   62         if(str1[i]>=65 && str1[i]<=90) buf1=str1[i]+32;
   63         else buf1=str1[i];
   64         if(str2[i]>=65 && str2[i]<=90) buf2=str2[i]+32;
   65         else buf2=str2[i];
   66         if(buf1!=buf2) return false;
   67     }
   68     return true;
   69 }
   70 
   71 int htmlfile::find_images(std::string & img_sel){
   72 #ifdef DEBUG
   73     cout << "find_images() line: " << __LINE__ << endl;
   74 #endif
   75   Fl_Window* w;
   76   { Fl_Window* o = new Fl_Window(380, 250);
   77     w = o;
   78     Edit = new Fl_Button(5, 220, 370, 25,
   79         "Select an image and klick on the Button");
   80     { Fl_Hold_Browser* o = Image_select = new Fl_Hold_Browser(5, 5, 370,
   81             210);
   82       o->labeltype(FL_NO_LABEL);
   83     }
   84     o->end();
   85   }
   86     Edit->callback(edit_cb,this);
   87     vector<string> names;
   88     int num=0;
   89     while(gotobeg("img")){
   90         string nam;
   91         if(getattribute(nam,"src")==false){
   92             dat.seekg(1,ios::cur); continue;
   93         }
   94         names.push_back(nam);
   95         Image_select->add(names[num].c_str());
   96         num++;
   97         dat.seekg(1,ios::cur);
   98     }
   99     w->resizable(w);
  100     w->set_modal();
  101     w->show();
  102     close_img_select=false;
  103     while((w->visible()||w->shown())&&close_img_select==false) Fl::wait();
  104     delete w;
  105     if(img_selected>0) img_sel=names[img_selected-1];
  106     else return 0;
  107     return img_selected;
  108 }
  109 
  110 void htmlfile::get_dir_name(std::string & nname, const std::string & name){
  111 #ifdef DEBUG
  112     cout << "get_dir_name() line: " << __LINE__ << endl;
  113 #endif
  114     int i;
  115     for(i=name.length()-1;i>=0;i--)
  116         if(name[i]=='/' && name[i-1]!='\\') break;
  117     nname.assign(name,0,i+1);
  118     return;
  119 }
  120 
  121 bool htmlfile::gotobeg(const std::string & name){
  122 #ifdef DEBUG
  123     cout << "gotobeg() line: " << __LINE__ << endl;
  124     cout << name << endl;
  125 #endif
  126     int len=name.length();
  127     char* readbuf=new char[len+1];
  128     char buf;
  129     while(true){
  130         buf=dat.get();
  131         if(dat.eof()) {delete readbuf; return false;}
  132         if(buf=='<'){
  133             dat.read(readbuf,len);
  134             if(dat.eof()) {delete readbuf; return false;}
  135             *(readbuf+len)=0;
  136             buf=dat.get();
  137             if(equal_string(readbuf,name) && (buf==' ' || buf=='>')) break;
  138             else dat.seekg(-(len),ios::cur);
  139         }
  140     }
  141     dat.seekg(-(len+2),ios::cur);
  142     if(write) dat.seekp(dat.tellg(),ios::beg);
  143     delete readbuf;
  144     return true;
  145 }
  146 
  147 void htmlfile::get_content(std::string & content,const std::string & tag){
  148     int beg, end;
  149     int pos=dat.tellg();
  150     string endtag="/";
  151     gotoend(tag);
  152     beg=dat.tellg();
  153     endtag+=tag;
  154     gotobeg(endtag);
  155     end=dat.tellg();
  156     dat.seekg(beg,ios::beg);
  157     char *readbuf=new char[end-beg+1];
  158     dat.read(readbuf,end-beg);
  159     *(readbuf+(end-beg))=0;
  160     content=readbuf;
  161     dat.seekg(pos,ios::beg);
  162 }
  163 
  164 bool htmlfile::getattribute(std::string & content,const std::string & name){
  165 #ifdef DEBUG
  166     cout << "getattribute() line: " << __LINE__ << endl;
  167     cout << name << endl;
  168 #endif
  169     string search=" ";
  170     search+=name;
  171     int pos=dat.tellg();
  172     int len=search.length();
  173     char* help=new char[len+1];
  174     char buf,buf2;
  175     bool quot=false;
  176     while(true){
  177         dat.read(help,len);
  178         help[len]=0;
  179         if(help[0]=='>') {dat.seekg(pos,ios::beg); content="";
  180             delete help; return false;}
  181         if(dat.eof()) {dat.seekg(pos,ios::beg); content="";
  182             delete help; return false;}
  183         buf=dat.get();
  184         if(equal_string(help,search)&& (buf==' ' || buf=='=' || buf=='>')) break;
  185         else dat.seekg(-(len),ios::cur);
  186     }
  187     dat.seekg(-1,ios::cur);
  188     delete help;
  189     while(true){
  190         buf=dat.get();
  191         if(buf=='>' || (buf!=' ' && buf!='=')) {dat.seekg(pos,ios::beg); content=""; return true;}
  192         if(dat.eof()) {dat.seekg(pos,ios::beg); content=""; return true;}
  193         if(buf=='=') break;
  194     }
  195     for(len=0;;len++){
  196         buf=dat.get();
  197         if(dat.eof()) {dat.seekg(pos,ios::beg); content=""; return true;}
  198         if(buf=='>') {dat.seekg(pos,ios::beg); content=""; return true;}
  199         if(buf!=' ') break;
  200     }
  201     dat.seekg(-1,ios::cur); 
  202     buf=dat.get();
  203     for(len=0;;len++){
  204         buf2=dat.get();
  205         if(len==0 && buf=='"') quot=true;
  206         if((buf==' ' && quot==false) || (buf=='>' && quot==false)
  207                 || dat.eof()){
  208             dat.seekg(-1,ios::cur);
  209             break;
  210         }
  211         if(quot && buf=='\"' && (buf2==' ' || buf2=='>')){
  212             len++;
  213             break;
  214         }
  215         buf=buf2;
  216     }
  217     dat.seekg(-(len+1),ios::cur);
  218     help=new char[len+1];
  219     dat.read(help,len);
  220     help[len]=0;
  221     char *nhelp=0;
  222     if(help[len-1]=='\"' && help[0]=='\"'){
  223         nhelp=help+1;
  224         help[len-1]=0;
  225     }
  226     else nhelp=help;
  227     dat.seekg(pos,ios::beg);
  228     content=nhelp;
  229     delete help;
  230     return true;
  231 }
  232 
  233 void htmlfile::str_search(int & beg,int & end,const std::string & str,const std::string & search){
  234     string s2=" ";
  235     s2+=search;
  236     int str_len=str.length();
  237     int search_len=s2.length();
  238     if(str_len==0 || search_len==0) {beg=-1;end=-1;return;}
  239     int times=str_len-search_len;
  240     bool in_quot=false;
  241     beg=-1;
  242     string tmp;
  243     int i;
  244     for(i=0;i<times;i++){
  245         tmp.assign(str,i,search_len);
  246         if(equal_string(tmp,s2)){
  247             if(i+search_len>=str_len){
  248                 i++;
  249                 beg=i;
  250                 break;
  251             }
  252             else if(str[i+search_len]==' ' || str[i+search_len]=='='){
  253                 i++;
  254                 beg=i;
  255                 break;
  256             }
  257         }
  258     }
  259     if(beg==-1){
  260         end=-1;
  261         return;
  262     }
  263     for(;i<str_len;i++){
  264         if(str[i]==' '){
  265             end=i-1;
  266             for(;i<str_len,str[i]==' ';i++);
  267             if(str[i]!='=') return;
  268             break;
  269         }
  270         if(str[i]=='=') break;
  271     }
  272     for(i++;i<str_len,str[i]==' ';i++);
  273     if(str[i]=='"') in_quot=true;
  274     for(;i<str_len;i++){
  275         if(str[i]==' ' && in_quot==false) break;
  276         if(str[i]==' ' && in_quot && str[i-1]=='"') break;
  277     }
  278     end=i-1;
  279 }
  280 
  281 void htmlfile::sort(int & b1, int & b2, int & b3, int & b4, int & e1, int & e2, int & e3, int & e4){
  282     int t;
  283     if(b1>b2){
  284         t=b1; b1=b2; b2=t;
  285         t=e1; e1=e2; e2=t;
  286     }
  287     if(b1>b3){
  288         t=b1; b1=b3; b3=t;
  289         t=e1; e1=e3; e3=t;
  290     }
  291     if(b1>b4){
  292         t=b1; b1=b4; b4=t;
  293         t=e1; e1=e4; e4=t;
  294     }
  295     
  296     if(b2>b3){
  297         t=b2; b2=b3; b3=t;
  298         t=e2; e2=e3; e3=t;
  299     }
  300     if(b2>b4){
  301         t=b2; b2=b4; b4=t;
  302         t=e2; e2=e4; e4=t;
  303     }
  304     
  305     if(b3>b4){
  306         t=b3; b3=b4; b4=t;
  307         t=e3; e3=e4; e4=t;
  308     }
  309 }
  310 
  311 void htmlfile::getothattr(std::string & str,const std::string & natr1,
  312         const std::string & natr2, const std::string & natr3, const std::string & natr4){
  313 #ifdef DEBUG
  314     cout << "getothattr(): line: " << __LINE__ << endl;
  315     cout << "natr1: " << natr1 << " natr2: " << natr2 << " natr3: " << natr3
  316          << " natr4: " << natr4 << endl;
  317 #endif
  318     char buf;
  319     int beg1,beg2,beg3,beg4,end1,end2,end3,end4;
  320     int end;
  321     int pos=dat.tellg();
  322     bool in_quot=false;
  323     bool first=true;
  324     char* all;
  325     string strall;
  326     string tmp;
  327     int i,pos1=0;
  328     for(i=0;;i++){
  329         buf=dat.get();
  330         if(buf==' ') first=false;
  331         if(first) pos1++;
  332         if(dat.eof()) {dat.seekg(pos,ios::beg); dat.clear(); str=""; return;}
  333         if(buf=='\"' && in_quot==false) in_quot=true;
  334         if(buf=='\"' && in_quot) in_quot=false;
  335         if(buf=='>' && in_quot==false) break;
  336     }
  337     all=new char[i-pos1+1];
  338     dat.seekg(pos+pos1,ios::beg);
  339     dat.read(all,i-pos1);
  340     all[i-pos1]=0;
  341     dat.seekg(pos,ios::beg);
  342     strall=all;
  343     delete all;
  344     str_search(beg1,end1,strall,natr1);
  345     str_search(beg2,end2,strall,natr2);
  346     str_search(beg3,end3,strall,natr3);
  347     str_search(beg4,end4,strall,natr4);
  348     str="";
  349     sort(beg1,beg2,beg3,beg4,end1,end2,end3,end4);
  350     end=0;
  351     int back=-1;
  352     if(beg1!=-1){
  353         if(beg1>1){
  354             tmp.assign(strall,1,beg1-1);
  355             str+=tmp;
  356         }
  357         end=end1;
  358     }
  359     if(beg2!=-1){
  360         if(beg2>1){
  361             tmp.assign(strall,end1+2,beg2-2-end1);
  362             str+=tmp;
  363         }
  364         end=end2;
  365     }
  366     if(beg3!=-1){
  367         if(beg3>1){
  368             tmp.assign(strall,end2+2,beg3-2-end2);
  369             str+=tmp;
  370         }
  371         end=end3;
  372     }
  373     if(beg4!=-1){
  374         if(beg4>1){
  375             tmp.assign(strall,end3+2,beg4-2-end3);
  376             str+=tmp;
  377         }
  378         end=end4;
  379     }
  380     tmp=strall.assign(strall,end+2,strall.length()-1-end);
  381     str+=tmp;
  382 }
  383 
  384 unsigned int htmlfile::count_tags(const std::string & search_name,
  385         const std::string & end_name){
  386 #ifdef DEBUG
  387     cout << "count_tags() line: " << __LINE__ << endl;
  388 #endif
  389     int found=0;
  390     int lens=search_name.length(), lene=end_name.length(), len=0;
  391     string search,end;
  392     int pos=dat.tellg();
  393     if(lens>lene) len=lens;
  394     else len=lene;
  395     char* readbuf=new char[len];
  396     char buf;
  397     int npos;
  398     while(true){
  399         buf=dat.get();
  400         if(dat.eof()){ delete readbuf; dat.seekg(pos); dat.clear(); return found;}
  401         if(buf=='<'){
  402             npos=dat.tellg();
  403             dat.read(readbuf,len);
  404             search.assign(readbuf,0,lens);
  405             end.assign(readbuf,0,lene);
  406             if(equal_string(end,end_name)){ delete readbuf; dat.seekg(pos); dat.clear(); return found;}
  407             if(lens>=lene) buf=dat.get();
  408             else buf=readbuf[lens];
  409             if(equal_string(search,search_name) && (buf==' ' || buf=='=' || buf=='>')) found++;
  410             dat.clear();
  411             dat.seekg(npos+1);
  412         }
  413     }
  414     dat.seekg(pos);
  415     delete readbuf;
  416     return found;
  417 }
  418 
  419 Frame_Buffer* htmlfile::read_image(const std::string & name){
  420 #ifdef DEBUG
  421     cout << "read_image() line: " << __LINE__ << endl;
  422 #endif
  423     Frame_Buffer* help;
  424     int len=name.length();
  425     int i;
  426     const char* cname=name.c_str();
  427     for(i=len-1;i>=0;i--){
  428         if(name[i]=='.') break;
  429     }
  430     const char* extension=&cname[i+1];
  431     if(equal_string(extension,"jpg") || equal_string(extension,"jpeg"))
  432         help=read_jpeg(cname);
  433     else{
  434     if(equal_string(extension,"png"))
  435         help=read_png(cname);
  436     else{
  437     if(equal_string(extension,"gif"))
  438         help=read_gif(cname);
  439     else{
  440         fl_alert("File format not supported!");
  441         return 0;
  442     }}}
  443     return help;
  444 }
  445 
  446 bool htmlfile::open(int & width,int & height){
  447 #ifdef DEBUG
  448     cout << "open() line: " << __LINE__ << endl;
  449 #endif
  450     string atr;
  451     int img;
  452     use_a=false;
  453     html_name=fl_file_chooser("Image:","*.htm*",0);
  454     if(html_name=="")return false;
  455     dat.open(html_name.c_str(),ios::in); dat.seekg(0,ios::beg); dat.clear();
  456     write=false;
  457     if((img=find_images(short_img_name))==0) {dat.close(); return false;}
  458     if(short_img_name=="") {dat.close(); return false;}
  459     get_dir_name(img_name,html_name);
  460     img_name+=short_img_name;
  461     fb=read_image(img_name);
  462     if(fb==0) {dat.close(); return false;}
  463     dat.clear();
  464     dat.seekg(0,ios::beg);
  465     for(int i=0;i<img;i++){
  466         if(gotobeg("img")==false) {dat.close(); return false;}
  467         dat.seekg(1,ios::cur);
  468     }
  469     dat.seekg(-1,ios::cur);
  470     if(getattribute(atr,"src")==false) {dat.close(); return false;}
  471     if(atr!=short_img_name) exit(1);
  472     if(getattribute(atr,"width")) width=atoi(atr.c_str());
  473     else width=-1;
  474     if(getattribute(atr,"height")) height=atoi(atr.c_str());
  475     else height=-1;
  476     getattribute(atr,"usemap");
  477     if(atr.length()<2) {map_name=""; dat.close(); return true;}
  478     map_name.assign(atr,1,std::string::npos);
  479     dat.seekg(1,ios::cur);
  480     dat.close();
  481     return true;
  482 }
  483 
  484 bool htmlfile::getmap(std::string & oth_attr){
  485 #ifdef DEBUG
  486     cout << "getmap() line: " << __LINE__ << endl;
  487 #endif
  488     if(state!=0) exit(5);
  489     if(html_name=="") exit(3);
  490     string atr;
  491     state=1;
  492     dat.open(html_name.c_str(),ios::in); dat.seekg(0,ios::beg); dat.clear();
  493     write=false;
  494     if(map_name=="") return false;
  495     while(true){
  496         if(gotobeg("map")==false) return false;
  497         if(getattribute(atr,"name")==false) continue;
  498         if(equal_string(atr,map_name)) break;
  499         dat.seekg(1,ios::cur);
  500     }
  501     getothattr(oth_attr,"name");
  502     return true;
  503 }
  504 
  505 bool htmlfile::getobj(int & object,std::string & url, std::string & alt_text,
  506         std::string & oth_attr){
  507 #ifdef DEBUG
  508     cout << "getobj() line: " << __LINE__ << endl;
  509     cout << "dat.tellg(): " << dat.tellg() << endl;
  510 #endif
  511     if(state<1 || state>3) exit(6);
  512     string obj;
  513     object=-1;
  514     int b=count_tags("area","/map");
  515     int a=count_tags("a","/map");
  516     if(a>b) use_a=true;
  517     else use_a=false;
  518     if(a<1 && b<1)return false;
  519     if(use_a) gotobeg("a");
  520     else gotobeg("area");
  521     getattribute(obj,"shape");
  522     if(equal_string("circle",obj)) object=objCircle;
  523     if(equal_string("rect",obj)) object=objSquare;
  524     if(equal_string("poly",obj)) object=objPolygon;
  525     getattribute(url,"href");
  526     if(use_a) get_content(alt_text,"a");
  527     else getattribute(alt_text,"alt");
  528     getothattr(oth_attr,"shape","href","alt","coords");
  529     state=2;
  530     return true;
  531 }
  532 
  533 bool htmlfile::get_coords(int &x,int &y){
  534 #ifdef DEBUG
  535     cout << "get_coords(int &x,int &y) line: " << __LINE__ << endl;
  536 #endif
  537     if(state<2 || state>3) exit(7);
  538     if(state!=3){
  539         string scoord,tmp;
  540         int index=0, index2;
  541         int number;
  542         coords.clear();
  543         coord=0;
  544         coord_max=0;
  545         getattribute(scoord,"coords");
  546         if(scoord=="") return false;
  547         int times=scoord.find_last_of(",");
  548         while(index<=times){
  549             index2=scoord.find(",",index);
  550             tmp.assign(scoord,index,index2-index);
  551             index=index2+1;
  552             number=atoi(tmp.c_str());
  553             coords.push_back(number);
  554             coord_max++;
  555         }
  556         tmp.assign(scoord,index,scoord.length()-index);
  557         number=atoi(tmp.c_str());
  558         coords.push_back(number);
  559         coord_max++;
  560     }
  561     state=3;
  562     if(coord>=coord_max) {
  563         if(use_a) gotoend("/a");
  564         else gotoend("area");
  565         return false;
  566     }
  567     x=coords[coord];
  568     coord++;
  569     y=coords[coord];
  570     coord++;
  571     if(coord==coord_max){
  572         if(use_a) gotoend("/a");
  573         else gotoend("area");
  574     }
  575     return true;
  576 }
  577 
  578 bool htmlfile::get_coords(int &r){
  579 #ifdef DEBUG
  580     cout << "get_coords(int &r) line: " << __LINE__ << endl;
  581 #endif
  582     if(state<2 || state>3) exit(7);
  583     if(state!=3){
  584         string scoord,tmp;
  585         int index=0, index2;
  586         int number;
  587         coords.clear();
  588         coord=0;
  589         coord_max=0;
  590         getattribute(scoord,"coords");
  591         if(scoord=="") return false;
  592         int times=scoord.find_last_of(",");
  593         while(index<=times){
  594             index2=scoord.find(",",index);
  595             tmp.assign(scoord,index,index2-index);
  596             index=index2+1;
  597             number=atoi(tmp.c_str());
  598             coords.push_back(number);
  599             coord_max++;
  600         }
  601         tmp.assign(scoord,index,scoord.length()-index);
  602         number=atoi(tmp.c_str());
  603         coords.push_back(number);
  604         coord_max++;
  605     }
  606     state=3;
  607     if(coord>=coord_max) {
  608         if(use_a) gotoend("/a");
  609         else gotoend("area");
  610         return false;
  611     }
  612     r=coords[coord];
  613     coord++;
  614     if(coord==coord_max){
  615         if(use_a) gotoend("/a");
  616         else gotoend("area");
  617     }
  618     return true;
  619 }
  620 
  621 void htmlfile::close_map(){
  622 #ifdef DEBUG
  623     cout << "close_map() line: " << __LINE__ << endl;
  624 #endif
  625     if(state<1 || state>3) exit(8);
  626     dat.close();
  627     state=0;
  628 }
  629 
  630 void htmlfile::save(const std::string & oth_attr, bool use_a){
  631 #ifdef DEBUG
  632     cout << "save() line: " << __LINE__ << endl;
  633 #endif
  634     if(state!=0) exit(9);
  635     state=10;
  636     if(use_a) this->use_a=true;
  637     else this->use_a=false;
  638     string name=html_name;
  639     name+=".bak";
  640     copy(name,html_name);
  641     remove_map();
  642     const char* help;
  643     if(map_name=="")
  644         help=fl_input("Insert MapName",short_img_name.c_str());
  645     else
  646         help=fl_input("Insert MapName",map_name.c_str());
  647     if(help==0 || strlen(help)==0){
  648         if(map_name!="")
  649             help=map_name.c_str();
  650         else
  651             help=short_img_name.c_str();
  652     }
  653     map_name=help;
  654     change_imagemap(help);
  655     move_lastpart();
  656     dat.open(html_name.c_str(),ios::app|ios::out); dat.seekp(0,ios::end);
  657     write=true;
  658     dat << "<map name=\"" << help << "\" " << oth_attr << ">\n";
  659 #ifdef DEBUG
  660     cout << "save(): done! line: " << __LINE__ << endl;
  661 #endif
  662 }
  663 
  664 void htmlfile::sav_circle(const std::string & url,int x,int y,int r,
  665         const std::string & alt_text, const std::string & oth_attr){
  666 #ifdef DEBUG
  667     cout << "sav_circle() line: " << __LINE__ << endl;
  668 #endif
  669     if(state!=10) exit(9);
  670     if(use_a)
  671         dat << " <a href=\"" << url
  672             << "\" shape=\"circle\" coords=\"" << x << "," << y << ","
  673             << r << "\" " << oth_attr << ">" << alt_text << "</a>\n";
  674     else
  675         dat << " <area href=\"" << url
  676             << "\" shape=\"circle\" coords=\"" << x << "," << y
  677             << "," << r << "\" alt=\"" << alt_text << "\" " << oth_attr
  678             << ">\n";
  679 }
  680 
  681 void htmlfile::sav_square(const std::string & url,int x1,int y1,int x2,int y2,
  682         const std::string & alt_text, const std::string & oth_attr){
  683 #ifdef DEBUG
  684     cout << "sav_square() line: " << __LINE__ << endl;
  685 #endif
  686     if(state!=10) exit(9);
  687     if(use_a)
  688         dat << " <a href=\"" << url << "\" shape=\"rect\" coords=\""
  689             << x1 << "," << y1 << "," << x2 << "," << y2 << "\" "
  690             << oth_attr << ">" << alt_text << "</a>\n";
  691     else
  692         dat << " <area href=\"" << url << "\" shape=\"rect\" coords=\""
  693             << x1 << "," << y1 << "," << x2 << "," << y2 << "\" alt=\""
  694             << alt_text << "\" " << oth_attr << ">\n";
  695 }
  696 
  697 void htmlfile::sav_polygon(const std::string & url,int x,int y){
  698 #ifdef DEBUG
  699     cout << "sav_polygon line: " << __LINE__ << endl;
  700 #endif
  701     if(state!=10) exit(9);
  702     state=11;
  703     if(use_a)
  704         dat << " <a href=\"" << url << "\" shape=\"poly\" coords=\""
  705             << x << "," << y;
  706     else
  707         dat << " <area href=\"" << url
  708             << "\" shape=\"poly\" coords=\"" << x << "," << y;
  709 }
  710 
  711 void htmlfile::sav_addpoly(int x,int y){
  712 #ifdef DEBUG
  713     cout << "sav_addpoly() line: " << __LINE__ << endl;
  714 #endif
  715     if(state!=11) exit(9);
  716     dat << "," << x << "," << y;
  717 }
  718 
  719 void htmlfile::close_polygon(const std::string & alt_text, const std::string & oth_attr){
  720 #ifdef DEBUG
  721     cout << "close_polygon() line: " << __LINE__ << endl;
  722 #endif
  723     if(state!=11) exit(9);
  724     state=10;
  725     if(use_a)
  726         dat << "\" " << oth_attr << ">" << alt_text << "</a>\n";
  727     else
  728         dat << "\" alt=\"" << alt_text << "\" " << oth_attr << ">\n";
  729 }
  730 
  731 void htmlfile::close_save(){
  732 #ifdef DEBUG
  733     cout << "close_save() line: " << __LINE__ << endl;
  734 #endif
  735     if(state!=10) exit(9);
  736     state=0;
  737     dat << "</map>\n";
  738     dat.close();
  739     write=false;
  740     add_lastpart();
  741     tmpfile="";
  742     fl_message("Changes saved!");
  743 }
  744 
  745 void htmlfile::remove_map(){
  746 #ifdef DEBUG
  747     cout << "remove_map() line: " << __LINE__ << endl;
  748 #endif
  749     dat.open(html_name.c_str(),ios::in); dat.seekg(0,ios::beg); dat.clear();
  750     write=false;
  751     char buf;
  752     string content;
  753     while(true){                                                 LINE();
  754         if(gotobeg("map")==false) {dat.close();return;}          LINE();
  755         getattribute(content,"name");
  756         if(content==map_name) break;
  757         dat.seekg(1,ios::cur);
  758     }
  759     int beg=dat.tellg();
  760     if(gotoend("/map")==false) {dat.close(); return;}           LINE();
  761     int end=dat.tellg();
  762     if(dat.get()=='\n') end++;
  763     char tmp[]=P_tmpdir"/MapGeneratorXXXXXX";
  764     mkstemp(tmp);
  765     dat.close();
  766     copy_part(tmp,html_name,0,beg);
  767     add_part(tmp,html_name,end,0);
  768     ::remove(html_name.c_str());
  769     move(html_name.c_str(),tmp);
  770 }
  771 
  772 bool htmlfile::gotoend(const std::string & name){
  773 #ifdef DEBUG
  774     cout << "gotoend() line: " << __LINE__ << endl;
  775 #endif
  776     gotobeg(name);
  777     char buf;
  778     while(true){
  779         buf=dat.get();
  780         if(buf=='>') break;
  781         if(buf=='\"'){
  782             while(true){
  783                 if(dat.get()=='\"') break;
  784                 if(dat.eof()) return false;
  785             }
  786         }
  787         if(dat.eof()) return false;
  788     }
  789     return true;
  790 }
  791 
  792 void htmlfile::copy(const std::string & newpath, const std::string & oldpath){
  793 #ifdef DEBUG
  794     cout << "copy() line: " << __LINE__ << endl;
  795 #endif
  796     copy_part(newpath,oldpath,0,0);
  797 }
  798 
  799 void htmlfile::move(const std::string & newpath, const std::string & oldpath){
  800 #ifdef DEBUG
  801     cout << "move() line: " << __LINE__ << endl;
  802 #endif
  803     copy_part(newpath,oldpath,0,0);
  804     ::remove(oldpath.c_str());
  805 }
  806 
  807 void htmlfile::copy_part(const std::string & newpath,const std::string & oldpath,
  808         int beg,int end){
  809 #ifdef DEBUG
  810     cout << "copy_part() line: " << __LINE__ << endl;
  811     cout << oldpath.c_str() << endl;
  812     cout << newpath.c_str() << endl;
  813 #endif
  814     ::remove(newpath.c_str());
  815     bool read=true;
  816     fstream oldp,newp;
  817     oldp.open(oldpath.c_str(),ios::in|ios::binary);
  818     newp.open(newpath.c_str(),ios::out|ios::binary);
  819     oldp.seekg(0,ios::end);
  820     int loop=((int)oldp.tellg()-beg)/1024;
  821     int last=((int)oldp.tellg()-beg)%1024;
  822     oldp.seekg(beg,ios::beg);
  823     oldp.clear();
  824     char text[1024];
  825     for(int i=0;i<loop;i++){
  826         oldp.read(text,1024);
  827         if(oldp.tellg()>=end && end!=0){
  828             last=(end-beg)%1024;
  829             if(last==0) {
  830                 oldp.read(text,1024);
  831                 newp.write(text,1024);
  832             }
  833             read=false;
  834             break;
  835         }
  836         newp.write(text,1024);
  837     }
  838     if(last!=0 && read) oldp.read(text,last);
  839     if(last!=0) newp.write(text,last);
  840     oldp.close();
  841     newp.close();
  842 }
  843 
  844 void htmlfile::add_part(const std::string & addpath,const std::string & oldpath,
  845         int beg,int end){
  846 #ifdef DEBUG
  847     cout << "add_part() line: " << __LINE__ << endl;
  848 #endif
  849     fstream oldp,newp;
  850     bool read=true;
  851     oldp.open(oldpath.c_str(),ios::in|ios::binary);
  852     newp.open(addpath.c_str(),ios::app|ios::out|ios::binary);
  853     oldp.seekg(0,ios::end);
  854     int loop=((int)oldp.tellg()-beg)/1024;
  855     int last=((int)oldp.tellg()-beg)%1024;
  856     oldp.seekg(beg,ios::beg);
  857     oldp.clear();
  858     char text[1024];
  859     for(int i=0;i<loop;i++){
  860         oldp.read(text,1024);
  861         if(oldp.tellg()>=end && end!=0){
  862             last=(end-beg)%1024;
  863             if(last==0){
  864                 oldp.read(text,1024);
  865                 newp.write(text,1024);
  866             }
  867             read=false;
  868             break;
  869         }
  870         newp.write(text,1024);
  871     }
  872 #ifdef DEBUG
  873     cout << "add_part(): len: " << last << " oldp.tellg: "
  874         << oldp.tellg() << " line: " << __LINE__ << endl;
  875 #endif
  876     if(last!=0 && read) oldp.read(text,last);
  877     if(last!=0) newp.write(text,last);
  878     oldp.close();
  879     newp.close();
  880 }
  881 
  882 void htmlfile::change_imagemap(const std::string & name){
  883 #ifdef DEBUG
  884     cout << "change_imagemap() line: " << __LINE__ << endl;
  885     cout << dat.is_open()<<endl;
  886 #endif
  887     bool rem=false;
  888     int beg;
  889     bool quote=false;
  890     dat.open(html_name.c_str(),ios::in); dat.seekg(0,ios::beg); dat.clear();
  891     dat.seekg(0,ios::beg); dat.clear();
  892     write=false;
  893     while(true){
  894         string name;
  895         if(gotobeg("img")==false) {dat.close(); return;}
  896         getattribute(name,"src");
  897         if(name==short_img_name) break;
  898         dat.seekg(1,ios::cur);
  899     }
  900     char readbuf[7];
  901     readbuf[6]=0;
  902     while(true){
  903         dat.read(readbuf,6);
  904         if(dat.eof()) {dat.close(); return;}
  905         if(readbuf[5]=='>') { dat.seekg(-1,ios::cur); break;}
  906         if(equal_string(readbuf,"usemap")){ rem=true; break;}
  907         dat.seekg(-5,ios::cur);
  908     }
  909     if(rem){
  910         char buf;
  911         char buf2;
  912         dat.seekg(-7,ios::cur);
  913         beg=dat.tellg();
  914         buf=dat.get();
  915         if(buf!=' ') beg++;
  916         int i=0;
  917         while(true){
  918             buf=dat.get();
  919             if(dat.eof()) {dat.close(); return;}
  920             if(buf=='>') {dat.close();return;}
  921             if(buf=='=') break;
  922         }
  923         while(true){
  924             buf=dat.get();
  925             if(dat.eof()) {dat.close();return;}
  926             if(buf=='>') {dat.close();return;}
  927             if(buf=='"') {quote=true; break;}
  928             if(buf!=' ') break;
  929         }
  930         buf2=dat.get();
  931         while(true){
  932             buf=buf2;
  933             if(dat.eof()) {dat.close(); return;}
  934             if((buf==' ' || buf=='>') && quote==false) break;
  935             buf2=dat.get();
  936             if(buf=='"' && (buf2==' ' || buf2=='>') && quote) break;
  937         }
  938         int end=(int)dat.tellg()-1;
  939         dat.close();
  940         char tmp[]=P_tmpdir"/MapGeneratorXXXXXX";
  941         mkstemp(tmp);
  942         copy_part(tmp,html_name,0,beg);
  943         add_part(tmp,html_name,end,0);
  944         ::remove(html_name.c_str());
  945         move(html_name.c_str(),tmp);
  946     }
  947     else{
  948         beg=dat.tellg();
  949         dat.close();
  950     }
  951     char tmpbeg[]=P_tmpdir"/MapGeneratorXXXXXX";
  952     mkstemp(tmpbeg);
  953     char tmpend[]=P_tmpdir"/MapGeneratorXXXXXX";
  954     mkstemp(tmpend);
  955     copy_part(tmpbeg,html_name.c_str(),0,beg);
  956     copy_part(tmpend,html_name.c_str(),beg,0);
  957     ::remove(html_name.c_str());
  958     move(html_name.c_str(),tmpbeg);
  959     dat.open(html_name.c_str(),ios::app|ios::out); dat.seekp(0,ios::end);
  960     write=true;
  961     dat << " usemap=\"#" << name << "\"";
  962     dat.close();
  963     write=false;
  964     add_part(html_name.c_str(),tmpend,0,0);
  965     ::remove(tmpbeg);
  966     ::remove(tmpend);
  967 }
  968 
  969 void htmlfile::move_lastpart(){
  970 #ifdef DEBUG
  971     cout << "move_lastpart() line: " << __LINE__ << endl;
  972 #endif
  973     dat.open(html_name.c_str(),ios::in); dat.seekg(0,ios::beg); dat.clear();
  974 #ifdef DEBUG
  975     cout << "dat open? " << dat.is_open() << endl;
  976     cout << "dat.tellg() " << dat.tellg() << endl;
  977     cout << "dat.eof() " << dat.eof() << endl;
  978 #endif
  979     write=false;
  980     string content;
  981     while(true){
  982         if(gotobeg("img")==false) {dat.close(); return;}
  983         getattribute(content,"src");
  984         if(content==short_img_name) break;
  985         dat.seekg(1,ios::cur);
  986     }      LINE();
  987     int beg=dat.tellg();
  988     char tmpbeg[]=P_tmpdir"/MapGeneratorXXXXXX";
  989     mkstemp(tmpbeg);
  990     char tmpend[]=P_tmpdir"/MapGeneratorXXXXXX";
  991     mkstemp(tmpend);
  992     dat.close();
  993     copy_part(tmpbeg,html_name,0,beg);
  994     copy_part(tmpend,html_name,beg,0);  
  995     ::remove(html_name.c_str());
  996     move(html_name.c_str(),tmpbeg);
  997     tmpfile=tmpend;
  998 #ifdef DEBUG
  999     cout << "Tmpend: " << tmpend << " Tmpfile: " << tmpfile << endl;
 1000 #endif
 1001 }
 1002 
 1003 void htmlfile::add_lastpart(){
 1004 #ifdef DEBUG
 1005     cout << "add_lastpart() line: " << __LINE__ << endl;
 1006     cout << "tmpfile: " << tmpfile << endl;
 1007 #endif
 1008     fstream tmpdat;
 1009     dat.open(html_name.c_str(),ios::app|ios::binary|ios::out); dat.seekp(0,ios::end);
 1010     write=true;
 1011     tmpdat.open(tmpfile.c_str(),ios::in|ios::binary);
 1012     tmpdat.seekg(0,ios::end);
 1013     int loop=tmpdat.tellg()/1024;
 1014     int last=tmpdat.tellg()%1024;
 1015     tmpdat.seekg(0,ios::beg);
 1016     char text[1024];
 1017     for(int i=0;i<loop;i++){
 1018         tmpdat.read(text,1024); 
 1019         dat.write(text,1024);
 1020     }
 1021     tmpdat.read(text,last);
 1022     dat.write(text,last);
 1023     dat.close();
 1024     write=false;
 1025     tmpdat.close();
 1026     ::remove(tmpfile.c_str());
 1027 }