blob: c5fba6ed882f02ee93ff93a8efb19d972543bd92 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Hisashi MIYASHITA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.model.flash.as;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ASDeserializer {
private static final Map<String, Object> tokenDic = new HashMap<String, Object>();
private static final Object UNDEFINED = "undefined".intern();
private static final Object NULL = "null".intern();
static {
tokenDic.put("true", Boolean.valueOf(true));
tokenDic.put("false", Boolean.valueOf(false));
tokenDic.put("undefined", UNDEFINED);
tokenDic.put("null", NULL);
}
private int idx;
private String str;
private int skipSP() {
while (idx < str.length()) {
char ch = str.charAt(idx);
switch (ch) {
case ' ':
case '\t':
case '\n':
case '\r':
idx++;
break;
default:
return idx;
}
}
return -1;
}
private int getTokenEndIdx() {
int idx2 = idx;
while (idx2 < str.length()) {
char ch = str.charAt(idx2);
switch (ch) {
case ' ':
case '\t':
case '\n':
case '\r':
case ',':
case ':':
case '}':
case ']':
return idx2;
default:
idx2++;
}
}
return idx2;
}
private String deserializeString() {
StringBuffer ret = new StringBuffer();
idx++;
while (idx < str.length()) {
char ch = str.charAt(idx);
switch (ch) {
case '"':
idx++;
return ret.toString();
case '\\':
idx++;
if (idx == str.length()) {
throw new IllegalArgumentException("Abnormal end of the string:" + str);
}
ret.append(str.charAt(idx));
idx++;
break;
default:
ret.append(ch);
idx++;
}
}
throw new IllegalArgumentException("Invalid String:" + str);
}
private Object[] deserializeArray() {
idx++;
ArrayList<Object> ret = new ArrayList<Object>();
while (idx < str.length()) {
skipSP();
char ch = str.charAt(idx);
if (ch == ']') {
idx++;
return ret.toArray(new Object[ret.size()]);
} else {
ret.add(deserialize());
}
skipSP();
ch = str.charAt(idx);
if (ch == ']') {
idx++;
return ret.toArray(new Object[ret.size()]);
}
if (ch != ',') {
throw new IllegalArgumentException("Missing ',':" + str);
}
idx++;
}
throw new IllegalArgumentException("Abnormal end of the array:" + str);
}
private ASObject deserializeASObject() {
idx++;
ASObject ret = new ASObject();
while (idx < str.length()) {
skipSP();
char ch = str.charAt(idx);
if (ch == '}') {
idx++;
return ret;
} else {
String prop = deserializeString();
skipSP();
if (str.charAt(idx) != ':') {
throw new IllegalArgumentException("Missing ':':" + str);
}
idx++;
Object o = deserialize();
ret.put(prop, o);
}
skipSP();
ch = str.charAt(idx);
if (ch == '}') {
idx++;
return ret;
}
if (str.charAt(idx) != ',') {
throw new IllegalArgumentException("Missing ',':" + str);
}
idx++;
}
throw new IllegalArgumentException("Abnormal end of the array:" + str);
}
public Object deserialize() {
int r = skipSP();
if (r < 0) return null;
char ch = str.charAt(idx);
switch (ch) {
case '[':
return deserializeArray();
case '{':
return deserializeASObject();
case '"':
return deserializeString();
default:
int idx2 = getTokenEndIdx();
String tok = str.substring(idx, idx2);
Object o = tokenDic.get(tok);
this.idx = idx2;
if (o == NULL) {
return null;
}
if (o != null) {
return o;
}
try {
int i = Integer.parseInt(tok);
return Integer.valueOf(i);
} catch (NumberFormatException e) {
}
try {
double d = Double.parseDouble(tok);
return new Double(d);
} catch (NumberFormatException e) {
}
throw new IllegalArgumentException(tok + " is not a valid token.");
}
}
public ASDeserializer(String str) {
this.idx = 0;
this.str = str;
}
}