00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef XMLOUTPUT_HPP
00017 #define XMLOUTPUT_HPP
00018 
00019 #include "Output.hpp"
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 #define XMLOUTPUT_INIT           0
00030 #define XMLOUTPUT_OPENLABEL      1
00031 #define XMLOUTPUT_OPENATTRIB     2
00032 #define XMLOUTPUT_AFTERDATA      3
00033 #define XMLOUTPUT_AFTERENDLABEL  4
00034 
00035 #define XMLINTENT_NONE        0
00036 #define XMLINTENT_WRAP        1
00037 #define XMLINTENT_SPACES      3
00038 #define XMLINTENT_TABS        4
00039 
00040 class XMLOutput : public Output
00041 {
00042    OUTPUT_STATIC int curcol,coldelta;
00043 
00044    OUTPUT_STATIC struct ABC {
00045    unsigned char  status:3;
00046    unsigned char  content:2;
00047    unsigned char  isinattrib:1;
00048    unsigned char  intentation:5;
00049    unsigned char  valuespacing:1;
00050    unsigned char  attribwhitespace:1;
00051    } x;
00052 
00053    OUTPUT_STATIC void GotoNextLine(char moveright)
00054    {
00055       switch(x.intentation)
00056       {
00057       case XMLINTENT_SPACES:
00058       case XMLINTENT_TABS:
00059       {
00060          StoreNewline();
00061 
00062          if(moveright==0)
00063             curcol-=coldelta;
00064 
00065          if(x.intentation==XMLINTENT_SPACES)
00066             mymemset(GetDataPtr(curcol),' ',curcol);
00067          else
00068             mymemset(GetDataPtr(curcol),'\t',curcol);
00069 
00070          if(moveright)
00071             curcol+=coldelta;
00072          break;
00073       }
00074 
00075 
00076 
00077 
00078 
00079       }
00080    }
00081 
00082 public:
00083 
00084    void OUTPUT_STATIC Init(unsigned char myintentation,unsigned char myvaluespacing=0,unsigned char mycoldelta=1)
00085    {
00086       curcol=0;
00087       coldelta=mycoldelta;
00088       x.intentation=myintentation;
00089 
00090       x.status=XMLOUTPUT_INIT;
00091       x.isinattrib=0;
00092 
00093       x.valuespacing=myvaluespacing;
00094    }
00095 
00096    XMLOutput()
00097    {
00098       Init(XMLINTENT_NONE);
00099    }
00100 
00101 
00102 
00103 #ifndef XDEMILL_NOOUTPUT
00104 
00105    void OUTPUT_STATIC startElement(char *str,int len)
00106    {
00107       switch(x.status)
00108       {
00109       case XMLOUTPUT_OPENLABEL:
00110          StoreChar('>');
00111          GotoNextLine(1);
00112          break;
00113 
00114       case XMLOUTPUT_OPENATTRIB:
00115          Error("Cannot start element within attribute!");
00116          Exit();
00117 
00118       case XMLOUTPUT_AFTERENDLABEL:
00119       case XMLOUTPUT_AFTERDATA:
00120          GotoNextLine(1);
00121          break;
00122 
00123       case XMLOUTPUT_INIT:
00124          curcol+=coldelta;
00125          break;
00126       }
00127       StoreChar('<');
00128 
00129       x.status=XMLOUTPUT_OPENLABEL;
00130       StoreData(str,len);
00131 
00132       x.attribwhitespace=0;
00133    }
00134 
00135    void OUTPUT_STATIC endElement(char *str,int len)
00136    {
00137       char *ptr;
00138       switch(x.status)
00139       {
00140       case XMLOUTPUT_OPENLABEL:
00141          ptr=GetDataPtr(len+4);
00142          *(ptr++)='>';
00143          *(ptr++)='<';
00144          *(ptr++)='/';
00145          mymemcpy(ptr,str,len);
00146          ptr+=len;
00147          *(ptr++)='>';
00148          curcol-=coldelta;
00149          x.status=XMLOUTPUT_AFTERENDLABEL;
00150          return;
00151 
00152       case XMLOUTPUT_AFTERENDLABEL:
00153          GotoNextLine(0);
00154          break;
00155 
00156       case XMLOUTPUT_AFTERDATA:
00157          curcol-=coldelta;
00158          break;
00159 
00160       default:
00161          Error("Invalid end tag");
00162          Exit();
00163       }
00164 
00165       ptr=GetDataPtr(len+3);
00166 
00167       *(ptr++)='<';
00168       *(ptr++)='/';
00169       mymemcpy(ptr,str,len);
00170       ptr+=len;
00171       *(ptr++)='>';
00172       
00173       x.status=XMLOUTPUT_AFTERENDLABEL;
00174    }
00175 
00176    void OUTPUT_STATIC endEmptyElement()
00177    {
00178       char *ptr;
00179       if(x.status!=XMLOUTPUT_OPENLABEL)
00180          
00181          return;
00182 
00183       ptr=GetDataPtr(2);
00184       *(ptr++)='/';
00185       *(ptr++)='>';
00186 
00187       x.status=XMLOUTPUT_AFTERENDLABEL;
00188       curcol-=coldelta;
00189    }
00190 
00191 
00192 
00193    void OUTPUT_STATIC startAttribute(char *str,int len)
00194    {
00195       register char *ptr;
00196 
00197       if(x.status==XMLOUTPUT_OPENATTRIB)
00198       {
00199          ptr=GetDataPtr(len+(x.attribwhitespace ? 3 : 4));
00200          *(ptr++)='"';
00201       }
00202       else
00203       {
00204          if(x.status!=XMLOUTPUT_OPENLABEL)
00205          {
00206             Error("Cannot print attribute outside of start element!");
00207             Exit();
00208          }
00209          ptr=GetDataPtr(len+(x.attribwhitespace ? 2 : 3));
00210       }
00211       if(x.attribwhitespace==0)
00212       {
00213          *(ptr++)=' ';
00214          x.attribwhitespace=0;
00215       }
00216 
00217       mymemcpy(ptr,str,len);
00218       ptr+=len;
00219       *(ptr++)='=';
00220       *(ptr++)='"';
00221 
00222       x.status=XMLOUTPUT_OPENATTRIB;
00223    }
00224 
00225    void OUTPUT_STATIC endAttribute(char *str=NULL,int len=0)
00226    {
00227       if(x.status!=XMLOUTPUT_OPENATTRIB)
00228       {
00229          Error("Could not finish attribute outside of start element!");
00230          Exit();
00231       }
00232       StoreChar('"');
00233       x.status=XMLOUTPUT_OPENLABEL;
00234    }
00235 
00236    void OUTPUT_STATIC characters(char *str,int len)
00237    {
00238       switch(x.status)
00239       {
00240       case XMLOUTPUT_OPENATTRIB:
00241          StoreData(str,len);
00242          return;
00243 
00244       case XMLOUTPUT_OPENLABEL:
00245          StoreChar('>');
00246 
00247       case XMLOUTPUT_AFTERDATA:
00248       case XMLOUTPUT_AFTERENDLABEL:
00249       case XMLOUTPUT_INIT:
00250          StoreData(str,len);
00251       }
00252       x.status=XMLOUTPUT_AFTERDATA;
00253    }
00254 
00255    void OUTPUT_STATIC whitespaces(char *str,int len)
00256    {
00257       characters(str,len);
00258    }
00259 
00260    void OUTPUT_STATIC attribWhitespaces(char *str,int len)
00261    {
00262       char *ptr=GetDataPtr(len);
00263       mymemcpy(ptr,str,len);
00264       x.attribwhitespace=1;
00265    }
00266 
00267 #else
00268    void OUTPUT_STATIC startElement(char *str,int len);
00269    void OUTPUT_STATIC endElement(char *str,int len);
00270    void OUTPUT_STATIC endEmptyElement();  
00271    void OUTPUT_STATIC startAttribute(char *str,int len);
00272    void OUTPUT_STATIC endAttribute(char *str=NULL,int len=0);
00273    void OUTPUT_STATIC characters(char *str,int len);
00274    void OUTPUT_STATIC whitespaces(char *str,int len);
00275    void OUTPUT_STATIC attribWhitespaces(char *str,int len); 
00276 #endif
00277 
00278 };
00279 
00280 #endif