• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kviewshell

XMLTags.cpp

Go to the documentation of this file.
00001 //C-  -*- C++ -*-
00002 //C- -------------------------------------------------------------------
00003 //C- DjVuLibre-3.5
00004 //C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
00005 //C- Copyright (c) 2001  AT&T
00006 //C-
00007 //C- This software is subject to, and may be distributed under, the
00008 //C- GNU General Public License, Version 2. The license should have
00009 //C- accompanied the software or you may obtain a copy of the license
00010 //C- from the Free Software Foundation at http://www.fsf.org .
00011 //C-
00012 //C- This program is distributed in the hope that it will be useful,
00013 //C- but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //C- GNU General Public License for more details.
00016 //C- 
00017 //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
00018 //C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech 
00019 //C- Software authorized us to replace the original DjVu(r) Reference 
00020 //C- Library notice by the following text (see doc/lizard2002.djvu):
00021 //C-
00022 //C-  ------------------------------------------------------------------
00023 //C- | DjVu (r) Reference Library (v. 3.5)
00024 //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
00025 //C- | The DjVu Reference Library is protected by U.S. Pat. No.
00026 //C- | 6,058,214 and patents pending.
00027 //C- |
00028 //C- | This software is subject to, and may be distributed under, the
00029 //C- | GNU General Public License, Version 2. The license should have
00030 //C- | accompanied the software or you may obtain a copy of the license
00031 //C- | from the Free Software Foundation at http://www.fsf.org .
00032 //C- |
00033 //C- | The computer code originally released by LizardTech under this
00034 //C- | license and unmodified by other parties is deemed "the LIZARDTECH
00035 //C- | ORIGINAL CODE."  Subject to any third party intellectual property
00036 //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
00037 //C- | non-exclusive license to make, use, sell, or otherwise dispose of 
00038 //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
00039 //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
00040 //C- | General Public License.   This grant only confers the right to 
00041 //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
00042 //C- | the extent such infringement is reasonably necessary to enable 
00043 //C- | recipient to make, have made, practice, sell, or otherwise dispose 
00044 //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
00045 //C- | any greater extent that may be necessary to utilize further 
00046 //C- | modifications or combinations.
00047 //C- |
00048 //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
00049 //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
00050 //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
00051 //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00052 //C- +------------------------------------------------------------------
00053 // 
00054 // $Id: XMLTags.cpp,v 1.12 2003/11/07 22:08:22 leonb Exp $
00055 // $Name: release_3_5_15 $
00056 
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063 
00064 // From: Leon Bottou, 1/31/2002
00065 // This is purely Lizardtech stuff.
00066 
00067 #include "XMLTags.h"
00068 #include "UnicodeByteStream.h"
00069 #include <ctype.h>
00070 #if HAS_WCTYPE
00071 #include <wctype.h>
00072 #endif
00073 
00074 
00075 #ifdef HAVE_NAMESPACES
00076 namespace DJVU {
00077 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00078 }
00079 #endif
00080 #endif
00081 
00082 lt_XMLContents::lt_XMLContents(void) {}
00083 
00084 lt_XMLContents::lt_XMLContents(GP<lt_XMLTags> t)
00085 {
00086   tag=t;
00087 }
00088 
00089 static GUTF8String
00090 getargn(char const tag[], char const *&t)
00091 {
00092   char const *s;
00093   for(s=tag;isspace(*s);s++);
00094   for(t=s;(*t)&&((*t)!='/')&&((*t)!='>')&&((*t)!='=')&&!isspace(*t);++t);
00095   return GUTF8String(s,t-s);
00096 }
00097 
00098 static GUTF8String
00099 getargv(char const tag[], char const *&t)
00100 {
00101   GUTF8String retval;
00102   if(tag && tag[0] == '=')
00103   {
00104     char const *s=t=tag+1;
00105     if((*t == '"')||(*t == '\47'))
00106     {
00107       char const q=*(t++);
00108       for(s++;(*t)&&((*t)!=q)&&((*t)!='>');++t);
00109       retval=GUTF8String(s,t-s);
00110       if (t[0] == q)
00111       {
00112         ++t;
00113       }
00114     }else
00115     {
00116       for(t=s;(*t)&&((*t)!='/')&&((*t)!='>')&&!isspace(*t);++t);
00117       retval=GUTF8String(s,t-s);
00118     }
00119   }else
00120   {
00121     t=tag;
00122   }
00123   return retval;
00124 }
00125 
00126 static GUTF8String
00127 tagtoname(char const tag[],char const *&t)
00128 {
00129   char const *s;
00130   for(s=tag;isspace(*s);s++);
00131   for(t=s;(*t)&&((*t)!='>')&&((*t)!='/')&&!isspace(*t);++t);
00132   return GUTF8String(s,t-s);
00133 }
00134 
00135 static inline GUTF8String
00136 tagtoname(char const tag[])
00137 {
00138   char const *t;
00139   return tagtoname(tag,t);
00140 }
00141 
00142 static inline bool
00143 isspaces(const GUTF8String &raw)
00144 {
00145   return (raw.nextNonSpace() == (int)raw.length());
00146 }
00147 
00148 void
00149 lt_XMLTags::ParseValues(char const *t, GMap<GUTF8String,GUTF8String> &args,bool downcase)
00150 {
00151   GUTF8String argn;
00152   char const *tt;
00153   while((argn=getargn(t,tt)).length())
00154   {
00155     if(downcase)
00156       argn=argn.downcase();
00157     args[argn]=getargv(tt,t).fromEscaped();
00158   }
00159 }
00160 
00161 lt_XMLTags::~lt_XMLTags() {}
00162 
00163 lt_XMLTags::lt_XMLTags(void) : startline(0) {}
00164 
00165 lt_XMLTags::lt_XMLTags(const char n[]) : startline(0)
00166 {
00167   char const *t;
00168   name=tagtoname(n,t);
00169   ParseValues(t,args);
00170 }
00171 
00172 void
00173 lt_XMLTags::init(const GP<ByteStream> &bs)
00174 {
00175   GP<XMLByteStream> gxmlbs=XMLByteStream::create(bs);
00176   init(*gxmlbs);
00177 }
00178 
00179 void
00180 lt_XMLTags::init(const GURL &url)
00181 {
00182   const GP<ByteStream> bs=ByteStream::create(url,"rb");
00183   init(bs);
00184 }
00185 
00186 void
00187 lt_XMLTags::init(XMLByteStream &xmlbs)
00188 {
00189   if(!get_count())
00190   {
00191     G_THROW( ERR_MSG("XMLTags.no_GP") );
00192   }
00193   GPList<lt_XMLTags> level;
00194   GUTF8String tag,raw(xmlbs.gets(0,'<',false));
00195   int linesread=xmlbs.get_lines_read();
00196   if(!isspaces(raw))
00197   {
00198     G_THROW( (ERR_MSG("XMLTags.raw_string") "\t")+raw);
00199   }
00200   GUTF8String encoding;
00201   for(int len;(len=(tag=xmlbs.gets(0,'>',true)).length());)
00202   {
00203     if(tag[len-1] != '>')
00204     {
00205       G_THROW((ERR_MSG("XMLTags.bad_tag") "\t")+tag);
00206     }
00207     switch(tag[1])
00208     {
00209       case '?':
00210       {
00211         while(len < 4 || tag.substr(len-2,len) != "?>")
00212         {
00213           GUTF8String cont(xmlbs.gets(0,'>',true));
00214           if(!cont.length())
00215           { 
00216             G_THROW( (ERR_MSG("XMLTags.bad_PI") "\t")+tag);
00217           }
00218           len=((tag+=cont).length());
00219         }
00220         char const *n;
00221         GUTF8String xtag = tag.substr(2,-1);
00222         GUTF8String xname = tagtoname(xtag,n);
00223         if(xname.downcase() == "xml")
00224         {
00225           ParseValues(n,args);
00226           for(GPosition pos=args;pos;++pos)
00227           {
00228             if(args.key(pos) == "encoding")
00229             {
00230               const GUTF8String e=args[pos].upcase();
00231               if(e != encoding)
00232               {
00233                 xmlbs.set_encoding((encoding=e));
00234               }
00235             }
00236           }
00237         }
00238         break;
00239       }
00240       case '!':
00241       {
00242         if(tag[2] == '-' && tag[3] == '-')
00243         {
00244           while((len < 7) ||
00245             (tag.substr(len-3,-1) != "-->"))
00246           {
00247             GUTF8String cont(xmlbs.gets(0,'>',true));
00248             if(!cont.length())
00249             { 
00250               GUTF8String mesg;
00251               mesg.format( ERR_MSG("XMLTags.bad_comment") "\t%s",(const char *)tag);
00252               G_THROW(mesg);
00253             }
00254             len=((tag+=cont).length());
00255           }
00256         }
00257         break;
00258       }
00259       case '/':
00260       {
00261         GUTF8String xname=tagtoname(tag.substr(2,-1));
00262         GPosition last=level.lastpos();
00263         if(last)
00264         {
00265           if(level[last]->name != xname)
00266           {
00267             G_THROW( (ERR_MSG("XMLTags.unmatched_end") "\t")
00268               +level[last]->name+("\t"+GUTF8String(level[last]->get_Line()))
00269               +("\t"+xname)+("\t"+GUTF8String(linesread+1)));
00270           }
00271           level.del(last);
00272         }else
00273         {
00274           G_THROW( ERR_MSG("XMLTags.bad_form") );
00275         }
00276         break;
00277       }
00278       default:
00279       {
00280         GPosition last=level.lastpos();
00281         GP<lt_XMLTags> t;
00282         if(last)
00283         {
00284           t=new lt_XMLTags(tag.substr(1,len-1));
00285           level[last]->addtag(t);
00286           if(tag[len-2] != '/')
00287           {
00288             level.append(t);
00289           }
00290         }else if(tag[len-2] != '/')
00291         {
00292           char const *n;
00293           GUTF8String xtag = tag.substr(1,-1); 
00294           name=tagtoname(xtag, n);
00295           ParseValues(n,args);
00296           t=this;
00297           level.append(t);
00298         }else
00299         {
00300           G_THROW( ERR_MSG("XMLTags.no_body") );
00301         }
00302         t->set_Line(linesread+1);
00303         break;
00304       }
00305     }
00306     if((raw=xmlbs.gets(0,'<',false))[0])
00307     { 
00308       linesread=xmlbs.get_lines_read();
00309       GPosition last=level.lastpos();
00310       if(last)
00311       {
00312         level[last]->addraw(raw);
00313       }else if(!isspaces(raw))
00314       {
00315         G_THROW(( ERR_MSG("XMLTags.raw_string") "\t")+raw);
00316       }
00317     }
00318   }
00319 }
00320 
00321 GPList<lt_XMLTags>
00322 lt_XMLTags::get_Tags(char const tagname[]) const
00323 {
00324   GPosition pos=allTags.contains(tagname);
00325   GPList<lt_XMLTags> retval;
00326   return (pos?allTags[pos]:retval);
00327 }
00328 
00329 void
00330 lt_XMLTags::get_Maps(char const tagname[],
00331                      char const argn[],
00332                      GPList<lt_XMLTags> list,
00333                      GMap<GUTF8String, GP<lt_XMLTags> > &map)
00334 {
00335   for(GPosition pos=list;pos;++pos)
00336   {
00337     GP<lt_XMLTags> &tag=list[pos];
00338     if(tag)
00339     {
00340       GPosition loc;
00341       if((loc=tag->contains(tagname)))
00342       {
00343         GPList<lt_XMLTags> maps=(GPList<lt_XMLTags> &)((*tag)[loc]);
00344         for(GPosition mloc=maps;mloc;++mloc)
00345         {
00346           GP<lt_XMLTags> gtag=maps[mloc];
00347           if(gtag)
00348           {
00349             GMap<GUTF8String,GUTF8String> &args=gtag->args;
00350             GPosition gpos;
00351             if((gpos=args.contains(argn)))
00352             {
00353               map[args[gpos]]=gtag;
00354             }
00355           }
00356         }
00357       }
00358     }
00359   }
00360 }
00361 
00362 void
00363 lt_XMLTags::write(ByteStream &bs,bool const top) const
00364 {
00365   if(name.length())
00366   {
00367     GUTF8String tag="<"+name;
00368     for(GPosition pos=args;pos;++pos)
00369     {
00370       tag+=GUTF8String(' ')+args.key(pos)+GUTF8String("=\42")+args[pos].toEscaped()+GUTF8String("\42");
00371     }
00372     GPosition tags=content;
00373     if(tags||raw.length()) 
00374     {
00375       tag+=">";
00376       bs.writall((const char *)tag,tag.length());
00377       tag="</"+name+">";
00378       if(raw.length())
00379       {
00380         bs.writestring(raw);
00381       }
00382       for(;tags;++tags)
00383       {
00384         content[tags].write(bs);
00385       }
00386     }else if(!raw.length())
00387     {
00388       tag+="/>";
00389     }
00390     bs.writall((const char *)tag,tag.length());
00391   }
00392   if(top)
00393   {
00394      bs.writall("\n",1);
00395   }
00396 }
00397 
00398 void
00399 lt_XMLContents::write(ByteStream &bs) const
00400 {
00401   if(tag)
00402   {
00403     tag->write(bs,false);
00404   }
00405   if(raw.length())
00406   {
00407     bs.writestring(raw);
00408   } 
00409 }
00410 
00411 
00412 #ifdef HAVE_NAMESPACES
00413 }
00414 # ifndef NOT_USING_DJVU_NAMESPACE
00415 using namespace DJVU;
00416 # endif
00417 #endif

kviewshell

Skip menu "kviewshell"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • kviewshell
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal