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