- Timestamp:
- 09/23/13 18:54:07 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
java/main/src/main/java/com/framsticks/params/ParamsUtil.java
r105 r107 2 2 3 3 import java.util.ArrayList; 4 // import java.util.HashMap; 4 5 import java.util.List; 5 6 import java.util.Map; 7 import java.util.TreeMap; 8 import java.util.regex.Matcher; 9 import java.util.regex.Pattern; 6 10 7 11 import javax.annotation.Nonnull; 8 12 13 // import org.apache.logging.log4j.Logger; 14 // import org.apache.logging.log4j.LogManager; 15 9 16 import com.framsticks.util.FramsticksException; 17 import com.framsticks.util.lang.Numbers; 10 18 11 19 … … 16 24 */ 17 25 public abstract class ParamsUtil { 26 // private final static Logger log = LogManager.getLogger(ParamsUtil.class.getName()); 27 18 28 19 29 public static String readSourceToString(Source source) { … … 212 222 return true; 213 223 } 224 if (type.equals(OpaqueObject.class)) { 225 builder.append(value.toString()); 226 return true; 227 } 214 228 throw new FramsticksException().msg("invalid type for serialization").arg("type", type); 215 229 } … … 233 247 } 234 248 249 public static class DeserializationContext { 250 251 public static final Pattern OPAQUE_OBJECT_PATTERN = Pattern.compile("^(\\w+)<0x([a-fA-F0-9]+)>$"); 252 253 @SuppressWarnings("serial") 254 public static class Exception extends FramsticksException { 255 } 256 257 protected final ArrayList<Object> objects = new ArrayList<>(); 258 protected int cursor = 0; 259 protected final String input; 260 261 /** 262 * @param input 263 */ 264 public DeserializationContext(String input) { 265 this.input = input; 266 cursor = 0; 267 } 268 269 protected boolean isFinished() { 270 return cursor == input.length(); 271 } 272 273 protected boolean is(char value) { 274 if (isFinished()) { 275 throw fail().msg("input ended"); 276 } 277 return input.charAt(cursor) == value; 278 } 279 280 protected boolean isOneOf(String values) { 281 if (isFinished()) { 282 throw fail().msg("input ended"); 283 } 284 return values.indexOf(input.charAt(cursor)) != -1; 285 } 286 287 protected char at() { 288 return input.charAt(cursor); 289 } 290 291 protected char at(int pos) { 292 return input.charAt(pos); 293 } 294 295 protected FramsticksException fail() { 296 return new Exception().arg("at", cursor).arg("input", input); 297 } 298 299 protected void force(char value) { 300 if (!is(value)) { 301 throw fail().msg("invalid character").arg("expected", value).arg("found", at()); 302 } 303 next(); 304 } 305 306 protected boolean isAndNext(char value) { 307 if (!is(value)) { 308 return false; 309 } 310 next(); 311 return true; 312 } 313 314 protected void next() { 315 ++cursor; 316 // log.info("at: {}|{}", input.substring(0, cursor), input.substring(cursor)); 317 } 318 319 protected void goToNext(char value) { 320 while (cursor < input.length()) { 321 if (is(value)) { 322 return; 323 } 324 next(); 325 } 326 throw fail().msg("passed end").arg("searching", value); 327 } 328 329 330 protected String forceStringRemaining() { 331 int start = cursor; 332 while (true) { 333 goToNext('"'); 334 if (at(cursor - 1) != '\\') { 335 next(); 336 return input.substring(start, cursor - 1); 337 } 338 next(); 339 // it is finishing that loop, because of throwing in goToNext() 340 } 341 // throw fail(); 342 } 343 344 public Object deserialize() { 345 if (isAndNext('[')) { 346 List<Object> list = new ArrayList<>(); 347 objects.add(list); 348 while (!isAndNext(']')) { 349 if (!list.isEmpty()) { 350 force(','); 351 } 352 Object child = deserialize(); 353 list.add(child); 354 } 355 return list; 356 } 357 358 if (isAndNext('{')) { 359 Map<String, Object> map = new TreeMap<>(); 360 objects.add(map); 361 while (!isAndNext('}')) { 362 if (!map.isEmpty()) { 363 force(','); 364 } 365 force('"'); 366 String key = forceStringRemaining(); 367 force(':'); 368 Object value = deserialize(); 369 map.put(key, value); 370 } 371 return map; 372 } 373 374 if (isAndNext('"')) { 375 return forceStringRemaining(); 376 } 377 int start = cursor; 378 while (!isFinished() && !isOneOf("]},")) { 379 next(); 380 } 381 if (start == cursor) { 382 throw fail().msg("empty value"); 383 } 384 385 String value = input.substring(start, cursor); 386 if (value.equals("null")) { 387 //TODO: add this to list? 388 return null; 389 } 390 391 Matcher matcher = OPAQUE_OBJECT_PATTERN.matcher(value); 392 if (matcher.matches()) { 393 return new OpaqueObject(matcher.group(1), Long.parseLong(matcher.group(2), 16)); 394 } 395 396 397 Object number = DeserializationContext.tryParseNumber(value); 398 if (number != null) { 399 return number; 400 } 401 402 if (value.charAt(0) == '^') { 403 Integer reference = Numbers.parse(value.substring(1), Integer.class); 404 if (reference == null) { 405 throw fail().msg("invalid reference").arg("reference", reference); 406 } 407 return objects.get(reference); 408 } 409 //TODO: parse ^ 410 //TODO: parse opaque object 411 throw fail().msg("unknown entity"); 412 413 } 414 415 public static Object tryParseNumber(String value) { 416 Integer i = Numbers.parse(value, Integer.class); 417 if (i != null) { 418 return i; 419 } 420 421 Double d = Numbers.parse(value, Double.class); 422 if (d != null) { 423 return d; 424 } 425 426 return null; 427 } 428 } 429 430 431 public static Object deserialize(String value) { 432 Object number = DeserializationContext.tryParseNumber(value); 433 if (number != null) { 434 return number; 435 } 436 437 if (!value.startsWith(SERIALIZED)) { 438 return value; 439 } 440 return new DeserializationContext(value.substring(SERIALIZED.length())).deserialize(); 441 } 442 235 443 public static <T> T deserialize(String value, Class<T> type) { 236 return null; 444 Object object = deserialize(value); 445 446 return type.cast(object); 237 447 } 238 448
Note: See TracChangeset
for help on using the changeset viewer.