00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include <iostream>
00028 #include <string>
00029 #include <cstdlib>
00030 #include <cstdio>
00031 #include "muo_convert.h"
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00048 krmuo::Converter::Converter()
00049 : mUnConvertedToken(""),
00050 mConvertedToken(""),
00051 mConvertedString(""),
00052 mUtf8String(""),
00053 mTokenMap(NULL)
00054 {
00055 mUtf8Sign[0]=0;
00056 }
00057
00061 krmuo::Converter::~Converter()
00062 {
00063 }
00064
00065
00066
00067
00068
00080 const string krmuo::Converter::decode(const string& pUnDecodedString)
00081 {
00082 assert(mTokenMap);
00083 mUnConvertedStringEnd=pUnDecodedString.end();
00084 mUnConvertedStringIterator=pUnDecodedString.begin();
00085 mConvertedString="";
00086 unsigned char sign;
00087 while(getNextUnDecodedToken(mUnConvertedToken))
00088 {
00089 if (isDecodableEmbeddedUtf8Token(mUnConvertedToken,sign))
00090 mConvertedString+=sign;
00091 else if (mTokenMap->isDecodableToken(mUnConvertedToken))
00092 mConvertedString+=mTokenMap->decodeToken(mUnConvertedToken);
00093 else
00094 mConvertedString+=mUnConvertedToken;
00095 }
00096 return mConvertedString;
00097 }
00098
00109 const string krmuo::Converter::encode(const string& pUnEncodedString)
00110 {
00111 assert(mTokenMap);
00112 mUnConvertedStringIterator=pUnEncodedString.begin();
00113 mConvertedString="";
00114 while(mUnConvertedStringIterator!=pUnEncodedString.end())
00115 {
00116 if (mTokenMap->isEncodableSign((unsigned char)*mUnConvertedStringIterator))
00117 mConvertedString+=mTokenMap->encodeSign((unsigned char)*mUnConvertedStringIterator);
00118 else if (isUtf8EncodableSign((unsigned char)*mUnConvertedStringIterator,mUtf8String))
00119 mConvertedString+=mUtf8String;
00120 else
00121 mConvertedString+=(unsigned char)*mUnConvertedStringIterator;
00122 mUnConvertedStringIterator++;
00123 }
00124 return mConvertedString;
00125 }
00126
00133 bool krmuo::Converter::isDecodableEmbeddedUtf8Token
00134 ( const string& pUtf8Token,
00135 unsigned char& pSign
00136 )
00137 {
00138 if (pUtf8Token.size()<3)
00139 return false;
00140
00141 string::const_iterator tokenSign=pUtf8Token.begin();
00142 if (((unsigned char)* tokenSign) != ((unsigned char)'&'))
00143 return false;
00144
00145 tokenSign++;
00146 if (((unsigned char) *tokenSign) != ((unsigned char)'#'))
00147 return false;
00148
00149 tokenSign++;
00150
00151
00152 enum NumberStil { UNKNOWN, HEX, OCTAL, DECIMAL } numberStil=UNKNOWN;
00153
00154 if ( ((unsigned char) toupper(*tokenSign)) == (unsigned char)'X' )
00155 {
00156 numberStil=HEX;
00157 tokenSign++;
00158 }
00159 else if (((unsigned char) toupper(*tokenSign)) == (unsigned char)'O' )
00160 {
00161 numberStil=OCTAL;
00162 tokenSign++;
00163 }
00164 else if ( isdigit(*tokenSign) )
00165 {
00166 numberStil=DECIMAL;
00167 }
00168
00169 if (numberStil==UNKNOWN)
00170 return false;
00171
00172 string utf8DecodedToken="";
00173 while( (tokenSign !=pUtf8Token.end())
00174 && ( ((unsigned char)*tokenSign)
00175 != ((unsigned char)';')
00176 )
00177 )
00178 {
00179 utf8DecodedToken+=*tokenSign;
00180 tokenSign++;
00181 }
00182
00183 unsigned int signValue=0;
00184 switch(numberStil)
00185 {
00186 case HEX:
00187 sscanf(utf8DecodedToken.c_str(),"%x",&signValue);
00188 break;
00189 case OCTAL:
00190 sscanf(utf8DecodedToken.c_str(),"%o",&signValue);
00191 break;
00192 default:
00193 sscanf(utf8DecodedToken.c_str(),"%u",&signValue);
00194 }
00195 pSign=(unsigned char) signValue;
00196 return true;
00197 }
00198
00206 bool krmuo::Converter::getNextUnDecodedToken(string& pUnDecodedToken)
00207 {
00208
00209 if (mUnConvertedStringIterator==mUnConvertedStringEnd)
00210 return false;
00211
00212 pUnDecodedToken="";
00213
00214
00215 string::const_iterator
00216 unDecodedParseIterator=mUnConvertedStringIterator;
00217
00218
00219 if ( ( (unsigned char)*unDecodedParseIterator )
00220 == ( (unsigned char) '&')
00221 )
00222 {
00223 bool doParse=true;
00224
00225 while(doParse)
00226 {
00227
00228 if ( (unDecodedParseIterator==mUnConvertedStringEnd)
00229 ||
00230 ( (unsigned char)*unDecodedParseIterator
00231 <= (unsigned char)' '
00232 ) )
00233 {
00234
00235
00236 unDecodedParseIterator=mUnConvertedStringIterator;
00237 pUnDecodedToken="";
00238
00239
00240
00241
00242 doParse=false;
00243 }
00244 else
00245 {
00246
00247 if ( (unsigned char)*unDecodedParseIterator
00248 == (unsigned char)';'
00249 )
00250 {
00251
00252
00253 doParse=false;
00254 }
00255 else
00256 {
00257
00258
00259 pUnDecodedToken+=*unDecodedParseIterator;
00260 unDecodedParseIterator++;
00261 }
00262 }
00263 }
00264 mUnConvertedStringIterator=unDecodedParseIterator;
00265 }
00266
00267
00268
00269
00270 pUnDecodedToken+=*mUnConvertedStringIterator;
00271 mUnConvertedStringIterator++;
00272 return true;
00273 }
00274
00281 bool krmuo::Converter::isUtf8EncodableSign(const unsigned char pSign, string& pUtf8Token)
00282 {
00283 if (pSign < 0x80)
00284 return false;
00285 sprintf(mUtf8Sign,"&#%02d;", pSign);
00286 pUtf8Token=mUtf8Sign;
00287 return true;
00288 }
00289
00290
00291
00292
00293
00300 krmuo::HtmlConverter::HtmlConverter()
00301 {
00302 mTokenMap=&mHtmlCodeTokenMap;
00303 }
00304
00308 krmuo::HtmlConverter::~HtmlConverter()
00309 {
00310 }
00311
00312
00313
00314
00315
00322 krmuo::XmlConverter::XmlConverter()
00323 {
00324 mTokenMap=&mXmlCodeTokenMap;
00325 }
00326
00330 krmuo::XmlConverter::~XmlConverter()
00331 {
00332 }
00333
00334
00335
00336
00337
00347 krmuo::UrlConverter::UrlConverter()
00348 {
00349 mTokenMap=&mUrlCodeTokenMap;
00350 }
00351
00355 krmuo::UrlConverter::~UrlConverter()
00356 {
00357 }
00358
00359
00371 const string krmuo::UrlConverter::decode(const string& pUnDecodedString)
00372 {
00373
00374 mUnConvertedStringEnd=pUnDecodedString.end();
00375 mUnConvertedStringIterator=pUnDecodedString.begin();
00376 mConvertedString="";
00377 unsigned char sign;
00378 while(getNextUnDecodedToken(mUnConvertedToken))
00379 {
00380
00381 if (isDecodableEmbeddedUtf8Token(mUnConvertedToken,sign))
00382 mConvertedString+=sign;
00383 else if (mUrlCodeTokenMap.isDecodableToken(mUnConvertedToken))
00384 mConvertedString+=mUrlCodeTokenMap.decodeToken(mUnConvertedToken);
00385 else
00386 mConvertedString+=mUnConvertedToken;
00387 }
00388 return mConvertedString;
00389 }
00390
00401 const string krmuo::UrlConverter::encode(const string& pUnEncodedString)
00402 {
00403 mUnConvertedStringIterator=pUnEncodedString.begin();
00404 mConvertedString="";
00405 while(mUnConvertedStringIterator!=pUnEncodedString.end())
00406 {
00407 if (mUrlCodeTokenMap.isEncodableSign((unsigned char)*mUnConvertedStringIterator))
00408 mConvertedString+=mUrlCodeTokenMap.encodeSign((unsigned char)*mUnConvertedStringIterator);
00409 else if (isUtf8EncodableSign((unsigned char)*mUnConvertedStringIterator,mUtf8String))
00410 mConvertedString+=mUtf8String;
00411 else
00412 mConvertedString+=(unsigned char)*mUnConvertedStringIterator;
00413 mUnConvertedStringIterator++;
00414 }
00415 return mConvertedString;
00416 }
00417
00429 bool krmuo::UrlConverter::getNextUnDecodedToken(string& pUnDecodedToken)
00430 {
00431
00432 if (mUnConvertedStringIterator==mUnConvertedStringEnd)
00433 return false;
00434
00435 pUnDecodedToken="";
00436
00437
00438 string::const_iterator
00439 unDecodedParseIterator=mUnConvertedStringIterator;
00440
00441
00442 if ( ( (unsigned char)*unDecodedParseIterator )
00443 == ( (unsigned char) '%')
00444 )
00445 {
00446 unDecodedParseIterator++;
00447 if (unDecodedParseIterator==mUnConvertedStringEnd)
00448 unDecodedParseIterator=mUnConvertedStringIterator;
00449 else
00450 {
00451 pUnDecodedToken="%";
00452 pUnDecodedToken+=*unDecodedParseIterator;
00453 unDecodedParseIterator++;
00454 if (unDecodedParseIterator==mUnConvertedStringEnd)
00455 unDecodedParseIterator=mUnConvertedStringIterator;
00456 }
00457 }
00458 mUnConvertedStringIterator=unDecodedParseIterator;
00459
00460
00461
00462
00463 pUnDecodedToken+=*mUnConvertedStringIterator;
00464 mUnConvertedStringIterator++;
00465 return true;
00466 }
00467
00474 bool krmuo::UrlConverter::isUtf8EncodableSign(const unsigned char pSign, string& pUtf8Token)
00475 {
00476 if (pSign < 0x80)
00477 return false;
00478 sprintf(mUtf8Sign,"%c%02x",'%',(unsigned int)pSign);
00479 pUtf8Token=mUtf8Sign;
00480 return true;
00481 }
00482
00489 bool krmuo::UrlConverter::isDecodableEmbeddedUtf8Token
00490 ( const string& pUtf8Token,
00491 unsigned char& pSign
00492 )
00493 {
00494 if (pUtf8Token.size()<3)
00495 return false;
00496
00497 string::const_iterator tokenSign=pUtf8Token.begin();
00498 if (((unsigned char)* tokenSign) != ((unsigned char)'%'))
00499 return false;
00500
00501 tokenSign++;
00502
00503 string utf8DecodedToken="";
00504 while(tokenSign !=pUtf8Token.end())
00505 {
00506 utf8DecodedToken+=*tokenSign;
00507 tokenSign++;
00508 }
00509
00510 unsigned int signValue=0;
00511 sscanf(utf8DecodedToken.c_str(),"%x",&signValue);
00512 pSign=(unsigned char) signValue;
00513 return true;
00514 }