1 28 29 package com.caucho.es; 30 31 import com.caucho.es.parser.Parser; 32 import com.caucho.vfs.ReadStream; 33 import com.caucho.vfs.Vfs; 34 35 import java.io.IOException ; 36 37 40 class NativeGlobal extends Native { 41 static final int EVAL = 2; 42 static final int PARSE_INT = 3; 43 static final int PARSE_FLOAT = 4; 44 static final int ESCAPE = 5; 45 static final int UNESCAPE = 6; 46 static final int IS_NAN = 7; 47 static final int IS_FINITE = 8; 48 49 static final int PRINT = 9; 50 static final int SYSTEM = PRINT + 1; 51 52 55 NativeGlobal(String name, int n, int len) 56 { 57 super(name, len); 58 59 this.n = n; 60 } 61 62 65 static void create(Global resin) 66 { 67 put(resin, "eval", EVAL, 1); 68 put(resin, "parseInt", PARSE_INT, 2); 69 put(resin, "parseFloat", PARSE_FLOAT, 1); 70 put(resin, "escape", ESCAPE, 1); 71 put(resin, "unescape", UNESCAPE, 1); 72 put(resin, "isNaN", IS_NAN, 1); 73 put(resin, "isFinite", IS_FINITE, 1); 74 75 put(resin, "print", PRINT, 1); 76 put(resin, "system", SYSTEM, 1); 77 } 78 79 private static void put(Global resin, String name, int n, int len) 80 { 81 ESId id = ESId.intern(name); 82 83 resin.addProperty(id, new NativeGlobal(name, n, len)); 84 } 85 86 public ESBase call(Call eval, int length) throws Throwable 87 { 88 switch (n) { 89 case EVAL: 90 return eval(eval, length); 91 92 case PARSE_INT: 93 return parseInt(eval, length); 94 95 case PARSE_FLOAT: 96 if (length < 1) 97 return ESNumber.NaN; 98 else { 99 return ESNumber.create(ESString.parseFloat(eval.getArg(0).toStr())); 100 } 101 102 case ESCAPE: 103 return escape(eval, length); 104 105 case UNESCAPE: 106 return unescape(eval, length); 107 108 case IS_NAN: 109 if (length < 1) 110 return esUndefined; 111 else 112 return ESBoolean.create(Double.isNaN(eval.getArg(0).toNum())); 113 114 case IS_FINITE: 115 if (length < 1) 116 return esUndefined; 117 else { 118 double value = eval.getArg(0).toNum(); 119 if (Double.isNaN(value)) 120 return ESBoolean.create(false); 121 else if (value == 1.0/0.0) 122 return ESBoolean.create(false); 123 else if (value == -1.0/0.0) 124 return ESBoolean.create(false); 125 else 126 return ESBoolean.create(true); 127 } 128 129 case PRINT: 130 System.out.print(eval.getArg(0).toStr().toString()); 131 return esNull; 132 133 case SYSTEM: 134 String arg = eval.getArg(0).toStr().toString(); 135 String []args = new String [3]; 136 Process process; 137 try { 138 args[0] = "sh"; 139 args[1] = "-c"; 140 args[2] = arg; 141 process = Runtime.getRuntime().exec(args); 142 return ESNumber.create(process.waitFor()); 143 } catch (Exception e) { 144 throw new ESWrapperException(e); 145 } 146 147 default: 148 throw new ESException("Unknown object function"); 149 } 150 } 151 152 private ESBase eval(Call eval, int length) throws Throwable 153 { 154 if (length < 1) 155 return esUndefined; 156 157 ESBase arg = eval.getArg(0); 158 if (! (arg instanceof ESString)) 159 return arg; 160 161 String string = arg.toString(); 162 163 Global resin = Global.getGlobalProto(); 164 ESBase context = eval.getFunctionContext(); 165 Script script = null; 166 ReadStream is = null; 167 try { 168 Parser parser = new Parser(); 169 is = Vfs.openString(string); 170 script = parser.parseEval(is, "eval", 1); 171 } catch (IOException e) { 172 e.printStackTrace(); 173 } finally { 174 if (is != null) 175 is.close(); 176 } 177 178 ESCallable jsClass = script.initClass(resin, eval.getGlobal()); 179 180 return jsClass.call(2, eval.caller, 0); 181 } 182 183 private ESBase parseInt(Call eval, int length) throws Throwable 184 { 185 if (length < 1) 186 return ESNumber.NaN; 187 188 ESString string = eval.getArg(0).toStr(); 189 int len = string.length(); 190 191 int i = 0; 192 for (; i < len && Character.isSpaceChar(string.charAt(i)); i++) { 193 } 194 195 int sign = 1; 196 if (i < len && string.charAt(i) == '+') { 197 i++; 198 } else if (i < len && string.charAt(i) == '-') { 199 sign = -1; 200 i++; 201 } 202 203 int radix = 0; 204 if (length > 1) { 205 radix = eval.getArg(1).toInt32(); 206 if (radix == 0) { 207 } 208 else if (radix < 2 || radix > 36) 209 return ESNumber.NaN; 210 else if (radix == 16 && i + 1 < length && 211 string.charAt(i) == '0' && 212 (string.charAt(i + 1) == 'x' || 213 string.charAt(i + 1) == 'X')) 214 i += 2; 215 } 216 217 if (radix != 0) { 218 } 219 else if (i >= len) 220 radix = 10; 221 else if (string.charAt(i) != '0') 222 radix = 10; 223 else if (i + 1 < len && 224 (string.charAt(i + 1) == 'x' || string.charAt(i + 1) == 'X')) { 225 radix = 16; 226 i += 2; 227 } else { 228 radix = 8; 229 } 230 231 long value = 0; 232 boolean hasDigit = false; 233 for (; i < len; i++) { 234 int ch = string.charAt(i); 235 236 if (radix <= 10 && ('0' <= ch && ch <= '0' + radix - 1)) { 237 value = radix * value + string.charAt(i) - '0'; 238 hasDigit = true; 239 } else if (radix > 10 && ('0' <= ch && ch <= '9')) { 240 value = radix * value + string.charAt(i) - '0'; 241 hasDigit = true; 242 } else if (radix > 10 && ('a' <= ch && ch <= 'a' + radix - 11)) { 243 value = radix * value + string.charAt(i) - 'a' + 10; 244 hasDigit = true; 245 } else if (radix > 10 && ('A' <= ch && ch <= 'A' + radix - 11)) { 246 value = radix * value + string.charAt(i) - 'A' + 10; 247 hasDigit = true; 248 } else 249 break; 250 } 251 252 if (hasDigit) 253 return ESNumber.create((double) sign * value); 254 else 255 return ESNumber.NaN; 256 } 257 258 static ESBase escape(Call eval, int length) throws Throwable 259 { 260 if (length < 1) 261 return esUndefined; 262 263 ESString string = eval.getArg(0).toStr(); 264 StringBuffer sbuf = new StringBuffer (); 265 266 for (int i = 0; i < string.length(); i++) { 267 int ch = string.charAt(i); 268 269 if (ch >= 'a' && ch <= 'z' || 270 ch >= 'A' && ch <= 'Z' || 271 ch >= '0' && ch <= '9' || 272 ch == '@' || ch == '*' || ch == '.' || ch == '_' || 273 ch == '+' || ch == '-' || ch == '/') { 274 sbuf.append((char) ch); 275 } else if (ch < 256) { 276 sbuf.append('%'); 277 sbuf.append(Integer.toHexString(ch >> 4)); 278 sbuf.append(Integer.toHexString(ch & 0xf)); 279 } else { 280 sbuf.append("%u"); 281 sbuf.append(Integer.toHexString(ch >> 12)); 282 sbuf.append(Integer.toHexString((ch >> 8) & 0xf)); 283 sbuf.append(Integer.toHexString((ch >> 4) & 0xf)); 284 sbuf.append(Integer.toHexString(ch & 0xf)); 285 } 286 } 287 288 return ESString.create(sbuf.toString()); 289 } 290 291 static ESBase unescape(Call eval, int length) throws Throwable 292 { 293 if (length < 1) 294 return esUndefined; 295 296 ESString string = eval.getArg(0).toStr(); 297 StringBuffer sbuf = new StringBuffer (); 298 299 for (int i = 0; i < string.length(); i++) { 300 int ch = string.charAt(i); 301 302 if (ch == '%' && i + 2 < string.length()) { 303 int limit = 2; 304 int start = 1; 305 306 if (string.charAt(i + 1) == 'u') { 307 limit = 4; 308 start = 2; 309 } 310 311 int newCh = 0; 312 int j = 0; 313 for (; j < limit && i + j + start < string.length(); j++) { 314 if ((ch = string.charAt(i + j + start)) >= '0' && ch <= '9') 315 newCh = 16 * newCh + ch - '0'; 316 else if (ch >= 'a' && ch <= 'f') 317 newCh = 16 * newCh + ch - 'a' + 10; 318 else if (ch >= 'A' && ch <= 'F') 319 newCh = 16 * newCh + ch - 'A' + 10; 320 else 321 break; 322 } 323 324 if (j != limit) { 325 sbuf.append('%'); 326 } else { 327 sbuf.append((char) newCh); 328 i += limit + start - 1; 329 } 330 } 331 else 332 sbuf.append((char) ch); 333 } 334 335 return ESString.create(sbuf.toString()); 336 } 337 } 338 | Popular Tags |