/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.ui.html; import totalcross.util.*; /** A class that can be used to convert escape characters in a Html string. * @since SuperWaba 5.71 */ public class EscapeHtml // guich@571_10 { /** The temporary buffer used by the convertion methods. */ public static StringBuffer sbuf = new StringBuffer(1000); /** When passing the escaped string to a SOAP service, you must change this to * <pre> * EscapeHtml.amp = "&"; * </pre> * and then set back to null when done. * @since TotalCross 1.14 */ public static String amp; // guich@tc114_10 /** Converts special chars into escaped sequences. Note that the space is NOT converted. */ public static final String escape(String s) { if (amp == null) amp = "&"; StringBuffer sb = sbuf; sbuf.setLength(0); for (int i = 0, n = s.length(); i < n; i++) { char c = s.charAt(i); switch (c) { case 0 : break; //flsobral@tc120_58: ignore character of value 0, because it is not a valid value. case 39 : sb.append(amp).append("#39;"); break; // ''' case 60 : sb.append(amp).append("lt;"); break; // '<' case 62 : sb.append(amp).append("gt;"); break; // '>' case 173 : sb.append(amp).append("shy;"); break; // '�' case 34 : sb.append(amp).append("quot;"); break; // '"' case 38 : sb.append(amp).append("amp;"); break; // '&' case 161 : sb.append(amp).append("iexcl;"); break; // '�' case 166 : sb.append(amp).append("brvbar;"); break; // '�' case 168 : sb.append(amp).append("uml;"); break; // '�' case 175 : sb.append(amp).append("macr;"); break; // '�' case 180 : sb.append(amp).append("acute;"); break; // '�' case 184 : sb.append(amp).append("cedil;"); break; // '�' case 191 : sb.append(amp).append("iquest;"); break; // '�' case 177 : sb.append(amp).append("plusmn;"); break; // '�' case 171 : sb.append(amp).append("laquo;"); break; // '�' case 187 : sb.append(amp).append("raquo;"); break; // '�' case 215 : sb.append(amp).append("times;"); break; // '�' case 247 : sb.append(amp).append("divide;"); break; // '�' case 162 : sb.append(amp).append("cent;"); break; // '�' case 163 : sb.append(amp).append("pound;"); break; // '�' case 164 : sb.append(amp).append("curren;"); break; // '�' case 165 : sb.append(amp).append("yen;"); break; // '�' case 167 : sb.append(amp).append("sect;"); break; // '�' case 169 : sb.append(amp).append("copy;"); break; // '�' case 172 : sb.append(amp).append("not;"); break; // '�' case 174 : sb.append(amp).append("reg;"); break; // '�' case 176 : sb.append(amp).append("deg;"); break; // '�' case 181 : sb.append(amp).append("micro;"); break; // '�' case 182 : sb.append(amp).append("para;"); break; // '�' case 183 : sb.append(amp).append("middot;"); break; // '�' case 8364: sb.append(amp).append("euro;"); break; // '�' case 188 : sb.append(amp).append("frac14;"); break; // '�' case 189 : sb.append(amp).append("frac12;"); break; // '�' case 190 : sb.append(amp).append("frac34;"); break; // '�' case 185 : sb.append(amp).append("sup1;"); break; // '�' case 178 : sb.append(amp).append("sup2;"); break; // '�' case 179 : sb.append(amp).append("sup3;"); break; // '�' case 225 : sb.append(amp).append("aacute;"); break; // '�' case 193 : sb.append(amp).append("Aacute;"); break; // '�' case 226 : sb.append(amp).append("acirc;"); break; // '�' case 194 : sb.append(amp).append("Acirc;"); break; // '�' case 224 : sb.append(amp).append("agrave;"); break; // '�' case 192 : sb.append(amp).append("Agrave;"); break; // '�' case 229 : sb.append(amp).append("aring;"); break; // '�' case 197 : sb.append(amp).append("Aring;"); break; // '�' case 227 : sb.append(amp).append("atilde;"); break; // '�' case 195 : sb.append(amp).append("Atilde;"); break; // '�' case 228 : sb.append(amp).append("auml;"); break; // '�' case 196 : sb.append(amp).append("Auml;"); break; // '�' case 170 : sb.append(amp).append("ordf;"); break; // '�' case 230 : sb.append(amp).append("aelig;"); break; // '�' case 198 : sb.append(amp).append("AElig;"); break; // '�' case 231 : sb.append(amp).append("ccedil;"); break; // '�' case 199 : sb.append(amp).append("Ccedil;"); break; // '�' case 208 : sb.append(amp).append("ETH;"); break; // '�' case 240 : sb.append(amp).append("eth;"); break; // '�' case 233 : sb.append(amp).append("eacute;"); break; // '�' case 201 : sb.append(amp).append("Eacute;"); break; // '�' case 234 : sb.append(amp).append("ecirc;"); break; // '�' case 202 : sb.append(amp).append("Ecirc;"); break; // '�' case 232 : sb.append(amp).append("egrave;"); break; // '�' case 200 : sb.append(amp).append("Egrave;"); break; // '�' case 235 : sb.append(amp).append("euml;"); break; // '�' case 203 : sb.append(amp).append("Euml;"); break; // '�' case 237 : sb.append(amp).append("iacute;"); break; // '�' case 205 : sb.append(amp).append("Iacute;"); break; // '�' case 238 : sb.append(amp).append("icirc;"); break; // '�' case 206 : sb.append(amp).append("Icirc;"); break; // '�' case 236 : sb.append(amp).append("igrave;"); break; // '�' case 204 : sb.append(amp).append("Igrave;"); break; // '�' case 239 : sb.append(amp).append("iuml;"); break; // '�' case 207 : sb.append(amp).append("Iuml;"); break; // '�' case 241 : sb.append(amp).append("ntilde;"); break; // '�' case 209 : sb.append(amp).append("Ntilde;"); break; // '�' case 243 : sb.append(amp).append("oacute;"); break; // '�' case 211 : sb.append(amp).append("Oacute;"); break; // '�' case 244 : sb.append(amp).append("ocirc;"); break; // '�' case 212 : sb.append(amp).append("Ocirc;"); break; // '�' case 242 : sb.append(amp).append("ograve;"); break; // '�' case 210 : sb.append(amp).append("Ograve;"); break; // '�' case 186 : sb.append(amp).append("ordm;"); break; // '�' case 248 : sb.append(amp).append("oslash;"); break; // '�' case 216 : sb.append(amp).append("Oslash;"); break; // '�' case 245 : sb.append(amp).append("otilde;"); break; // '�' case 213 : sb.append(amp).append("Otilde;"); break; // '�' case 246 : sb.append(amp).append("ouml;"); break; // '�' case 214 : sb.append(amp).append("Ouml;"); break; // '�' case 223 : sb.append(amp).append("szlig;"); break; // '�' case 254 : sb.append(amp).append("thorn;"); break; // '�' case 222 : sb.append(amp).append("THORN;"); break; // '�' case 250 : sb.append(amp).append("uacute;"); break; // '�' case 218 : sb.append(amp).append("Uacute;"); break; // '�' case 251 : sb.append(amp).append("ucirc;"); break; // '�' case 219 : sb.append(amp).append("Ucirc;"); break; // '�' case 249 : sb.append(amp).append("ugrave;"); break; // '�' case 217 : sb.append(amp).append("Ugrave;"); break; // '�' case 252 : sb.append(amp).append("uuml;"); break; // '�' case 220 : sb.append(amp).append("Uuml;"); break; // '�' case 253 : sb.append(amp).append("yacute;"); break; // '�' case 221 : sb.append(amp).append("Yacute;"); break; // '�' case 255 : sb.append(amp).append("yuml;"); break; // '�' default : sb.append(c); break; } } return sb.toString(); } private static IntHashtable ht; static { ht = new IntHashtable(235); // 10 collisions ht.put("#39" ,39 ); // ''' ht.put("lt" ,60 ); // '<' ht.put("gt" ,62 ); // '>' ht.put("shy" ,173 ); // '�' ht.put("quot" ,34 ); // '"' ht.put("amp" ,38 ); // '&' ht.put("iexcl" ,161 ); // '�' ht.put("brvbar" ,166 ); // '�' ht.put("uml" ,168 ); // '�' ht.put("macr" ,175 ); // '�' ht.put("acute" ,180 ); // '�' ht.put("cedil" ,184 ); // '�' ht.put("iquest" ,191 ); // '�' ht.put("plusmn" ,177 ); // '�' ht.put("laquo" ,171 ); // '�' ht.put("raquo" ,187 ); // '�' ht.put("times" ,215 ); // '�' ht.put("divide" ,247 ); // '�' ht.put("cent" ,162 ); // '�' ht.put("pound" ,163 ); // '�' ht.put("curren" ,164 ); // '�' ht.put("yen" ,165 ); // '�' ht.put("sect" ,167 ); // '�' ht.put("copy" ,169 ); // '�' ht.put("not" ,172 ); // '�' ht.put("reg" ,174 ); // '�' ht.put("deg" ,176 ); // '�' ht.put("micro" ,181 ); // '�' ht.put("para" ,182 ); // '�' ht.put("middot" ,183 ); // '�' ht.put("euro" ,8364 ); // '�' ht.put("frac14" ,188 ); // '�' ht.put("frac12" ,189 ); // '�' ht.put("frac34" ,190 ); // '�' ht.put("sup1" ,185 ); // '�' ht.put("sup2" ,178 ); // '�' ht.put("sup3" ,179 ); // '�' ht.put("aacute" ,225 ); // '�' ht.put("Aacute" ,193 ); // '�' ht.put("acirc" ,226 ); // '�' ht.put("Acirc" ,194 ); // '�' ht.put("agrave" ,224 ); // '�' ht.put("Agrave" ,192 ); // '�' ht.put("aring" ,229 ); // '�' ht.put("Aring" ,197 ); // '�' ht.put("atilde" ,227 ); // '�' ht.put("Atilde" ,195 ); // '�' ht.put("auml" ,228 ); // '�' ht.put("Auml" ,196 ); // '�' ht.put("ordf" ,170 ); // '�' ht.put("aelig" ,230 ); // '�' ht.put("AElig" ,198 ); // '�' ht.put("ccedil" ,231 ); // '�' ht.put("Ccedil" ,199 ); // '�' ht.put("ETH" ,208 ); // '�' ht.put("eth" ,240 ); // '�' ht.put("eacute" ,233 ); // '�' ht.put("Eacute" ,201 ); // '�' ht.put("ecirc" ,234 ); // '�' ht.put("Ecirc" ,202 ); // '�' ht.put("egrave" ,232 ); // '�' ht.put("Egrave" ,200 ); // '�' ht.put("euml" ,235 ); // '�' ht.put("Euml" ,203 ); // '�' ht.put("iacute" ,237 ); // '�' ht.put("Iacute" ,205 ); // '�' ht.put("icirc" ,238 ); // '�' ht.put("Icirc" ,206 ); // '�' ht.put("igrave" ,236 ); // '�' ht.put("Igrave" ,204 ); // '�' ht.put("iuml" ,239 ); // '�' ht.put("Iuml" ,207 ); // '�' ht.put("ntilde" ,241 ); // '�' ht.put("Ntilde" ,209 ); // '�' ht.put("oacute" ,243 ); // '�' ht.put("Oacute" ,211 ); // '�' ht.put("ocirc" ,244 ); // '�' ht.put("Ocirc" ,212 ); // '�' ht.put("ograve" ,242 ); // '�' ht.put("Ograve" ,210 ); // '�' ht.put("ordm" ,186 ); // '�' ht.put("oslash" ,248 ); // '�' ht.put("Oslash" ,216 ); // '�' ht.put("otilde" ,245 ); // '�' ht.put("Otilde" ,213 ); // '�' ht.put("ouml" ,246 ); // '�' ht.put("Ouml" ,214 ); // '�' ht.put("szlig" ,223 ); // '�' ht.put("thorn" ,254 ); // '�' ht.put("THORN" ,222 ); // '�' ht.put("uacute" ,250 ); // '�' ht.put("Uacute" ,218 ); // '�' ht.put("ucirc" ,251 ); // '�' ht.put("Ucirc" ,219 ); // '�' ht.put("ugrave" ,249 ); // '�' ht.put("Ugrave" ,217 ); // '�' ht.put("uuml" ,252 ); // '�' ht.put("Uuml" ,220 ); // '�' ht.put("yacute" ,253 ); // '�' ht.put("Yacute" ,221 ); // '�' ht.put("yuml" ,255 ); // '�' } /** Converts escaped sequences into special chars. Note that the space IS converted if it appears escaped. */ public static final String unescape(String escaped) { //totalcross.sys.Vm.debug("coll: "+ht.collisions); char []chars = escaped.toCharArray(); StringBuffer sb = sbuf; sbuf.setLength(0); int last =0; int i = 0; while (true) { int s0 = escaped.indexOf('&',i); if (s0 == -1) break; int sf = escaped.indexOf(';',s0); if (sf == -1) break; int len = sf-s0-1; if (2 <= len && len <= 6) // is this a valid symbol? { // compute the hash to avoid creating a string int hash = 0; for (int j = s0+1; j < sf; j++) hash = (hash<<5) - hash + chars[j]; //String token = escaped.substring(s0+1,sf); int hash = token.hashCode(); try { int to = ht.get(hash); if (s0 > last) sb.append(chars,last,s0-last); sb.append((char)to); last = sf+1; } catch (ElementNotFoundException e) {} i = sf+1; } else i++; } if (i < chars.length) sb.append(chars,i,chars.length-i); return sb.toString(); } }