1 29 30 package com.caucho.quercus.lib; 31 32 import com.caucho.quercus.env.*; 33 import com.caucho.util.L10N; 34 import com.caucho.util.LruCache; 35 36 import java.io.IOException ; 37 import java.util.logging.Logger ; 38 39 public final class UnserializeReader { 40 private static final L10N L = new L10N(UnserializeReader.class); 41 private static final Logger log 42 = Logger.getLogger(UnserializeReader.class.getName()); 43 44 private static final LruCache<StringKey,StringValue> _keyCache 45 = new LruCache<StringKey,StringValue>(4096); 46 47 private final char []_buffer; 48 private final int _length; 49 50 private int _index; 51 private StringKey _key = new StringKey(); 52 53 public UnserializeReader(StringValue s) 54 { 55 _buffer = s.toCharArray(); 56 _length = s.length(); 57 } 58 59 public UnserializeReader(String s) 60 { 61 _buffer = s.toCharArray(); 62 _length = s.length(); 63 } 64 65 public Value unserialize(Env env) 66 throws IOException 67 { 68 int ch = read(); 69 70 switch (ch) { 71 case 'b': 72 { 73 expect(':'); 74 long v = readInt(); 75 expect(';'); 76 77 return v == 0 ? BooleanValue.FALSE : BooleanValue.TRUE; 78 } 79 80 case 's': 81 { 82 expect(':'); 83 int len = (int) readInt(); 84 expect(':'); 85 expect('"'); 86 87 StringValue s = readStringValue(len); 88 89 expect('"'); 90 expect(';'); 91 92 return s; 93 } 94 95 case 'i': 96 { 97 expect(':'); 98 99 long value = readInt(); 100 101 expect(';'); 102 103 return LongValue.create(value); 104 } 105 106 case 'd': 107 { 108 expect(':'); 109 110 StringBuilder sb = new StringBuilder (); 111 for (ch = read(); ch >= 0 && ch != ';'; ch = read()) { 112 sb.append((char) ch); 113 } 114 115 if (ch != ';') 116 throw new IOException (L.l("expected ';'")); 117 118 return new DoubleValue(Double.parseDouble(sb.toString())); 119 } 120 121 case 'a': 122 { 123 expect(':'); 124 long len = readInt(); 125 expect(':'); 126 expect('{'); 127 128 ArrayValue array = new ArrayValueImpl((int) len); 129 for (int i = 0; i < len; i++) { 130 Value key = unserializeKey(env); 131 Value value = unserialize(env); 132 133 array.put(key, value); 134 } 135 136 expect('}'); 137 138 return array; 139 } 140 141 case 'O': 142 { 143 expect(':'); 144 int len = (int) readInt(); 145 expect(':'); 146 expect('"'); 147 148 String className = readString(len); 149 150 expect('"'); 151 expect(':'); 152 long count = readInt(); 153 expect(':'); 154 expect('{'); 155 156 QuercusClass qClass = env.findClass(className); 157 Value obj; 158 159 if (qClass != null) 160 obj = qClass.newInstance(env); 161 else { 162 log.fine(L.l("{0} is an undefined class in unserialize", 163 className)); 164 165 obj = env.createObject(); 166 obj.putField(env, 167 "__Quercus_Incomplete_Class_name", 168 new StringValueImpl(className)); 169 } 170 171 for (int i = 0; i < count; i++) { 172 String key = unserializeString(); 173 Value value = unserialize(env); 174 175 obj.putField(env, key, value); 176 } 177 178 expect('}'); 179 180 return obj; 181 } 182 183 case 'N': 184 { 185 expect(';'); 186 187 return NullValue.NULL; 188 } 189 190 default: 191 return BooleanValue.FALSE; 192 } 193 } 194 195 public Value unserializeKey(Env env) 196 throws IOException 197 { 198 int ch = read(); 199 200 switch (ch) { 201 case 's': 202 { 203 expect(':'); 204 int len = (int) readInt(); 205 expect(':'); 206 expect('"'); 207 208 StringValue v; 209 210 if (len < 32) { 211 _key.init(_buffer, _index, len); 212 213 v = _keyCache.get(_key); 214 215 if (v != null) { 216 _index += len; 217 } 218 else { 219 StringKey key = new StringKey(_buffer, _index, len); 220 221 String s = readString(len); 222 v = new InternStringValue(s); 223 224 _keyCache.put(key, v); 225 } 226 } 227 else { 228 String s = readString(len); 229 v = new StringValueImpl(s); 230 } 231 232 expect('"'); 233 expect(';'); 234 235 return v; 236 } 237 238 case 'i': 239 { 240 expect(':'); 241 242 long value = readInt(); 243 244 expect(';'); 245 246 return LongValue.create(value); 247 } 248 249 default: 250 return BooleanValue.FALSE; 251 } 252 } 253 254 private String unserializeString() 255 throws IOException 256 { 257 expect('s'); 258 expect(':'); 259 int len = (int) readInt(); 260 expect(':'); 261 expect('"'); 262 263 String s = readString(len); 264 265 expect('"'); 266 expect(';'); 267 268 return s; 269 } 270 271 public final void expect(int expectCh) 272 throws IOException 273 { 274 if (_length <= _index) 275 throw new IOException (L.l("expected '{0}' at end of string", 276 String.valueOf((char) expectCh))); 277 278 int ch = _buffer[_index++]; 279 280 if (ch != expectCh) { 281 throw new IOException (L.l("expected '{0}' at '{1}'", 282 String.valueOf((char) expectCh), 283 String.valueOf((char) ch))); 284 } 285 } 286 287 public final long readInt() 288 { 289 int ch = read(); 290 291 long sign = 1; 292 long value = 0; 293 294 if (ch == '-') { 295 sign = -1; 296 ch = read(); 297 } 298 else if (ch == '+') { 299 ch = read(); 300 } 301 302 for (; '0' <= ch && ch <= '9'; ch = read()) { 303 value = 10 * value + ch - '0'; 304 } 305 306 unread(); 307 308 return sign * value; 309 } 310 311 public final String readString(int len) 312 { 313 String s = new String (_buffer, _index, len); 314 315 _index += len; 316 317 return s; 318 } 319 320 public final StringValue readStringValue(int len) 321 { 322 StringValue s = new StringBuilderValue(_buffer, _index, len, true); 323 324 _index += len; 325 326 return s; 327 } 328 329 public final int read() 330 { 331 if (_index < _length) 332 return _buffer[_index++]; 333 else 334 return -1; 335 } 336 337 public final int read(char []buffer, int offset, int length) 338 { 339 System.arraycopy(_buffer, _index, buffer, offset, length); 340 341 _index += length; 342 343 return length; 344 } 345 346 public final void unread() 347 { 348 _index--; 349 } 350 351 public final static class StringKey { 352 char []_buffer; 353 int _offset; 354 int _length; 355 356 StringKey() 357 { 358 } 359 360 StringKey(char []buffer, int offset, int length) 361 { 362 _buffer = new char[length]; 363 System.arraycopy(buffer, offset, _buffer, 0, length); 364 _offset = 0; 365 _length = length; 366 } 367 368 void init(char []buffer, int offset, int length) 369 { 370 _buffer = buffer; 371 _offset = offset; 372 _length = length; 373 } 374 375 public int hashCode() 376 { 377 char []buffer = _buffer; 378 int offset = _offset; 379 int end = offset + _length; 380 int hash = 17; 381 382 for (; offset < end; offset++) 383 hash = 65521 * hash + buffer[offset]; 384 385 return hash; 386 } 387 388 public boolean equals(Object o) 389 { 390 if (! (o instanceof StringKey)) 391 return false; 392 393 StringKey key = (StringKey) o; 394 395 int length = _length; 396 397 if (length != key._length) 398 return false; 399 400 char []aBuf = _buffer; 401 char []bBuf = key._buffer; 402 403 int aOffset = _offset; 404 int bOffset = key._offset; 405 406 int aEnd = aOffset + length; 407 408 while (aOffset < aEnd) { 409 if (aBuf[aOffset++] != bBuf[bOffset++]) 410 return false; 411 } 412 413 return true; 414 } 415 } 416 } 417 418 419 | Popular Tags |