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