diff --git a/.classpath b/.classpath index 1e02a1e..3f0bc57 100644 --- a/.classpath +++ b/.classpath @@ -3,8 +3,8 @@ - + diff --git a/PeerAtCodeParser.jar b/PeerAtCodeParser.jar new file mode 100644 index 0000000..95d9a7f Binary files /dev/null and b/PeerAtCodeParser.jar differ diff --git a/json-simple-1.1.1.jar b/json-simple-1.1.1.jar deleted file mode 100644 index dfd5856..0000000 Binary files a/json-simple-1.1.1.jar and /dev/null differ diff --git a/src/dev/peerat/framework/HttpReader.java b/src/dev/peerat/framework/HttpReader.java index e0e11a5..9fbb6e8 100644 --- a/src/dev/peerat/framework/HttpReader.java +++ b/src/dev/peerat/framework/HttpReader.java @@ -12,11 +12,13 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.json.simple.parser.JSONParser; +import dev.peerat.framework.utils.json.Json; +import dev.peerat.framework.utils.json.JsonParser; public class HttpReader{ private static Pattern HEADER_PATTERN = Pattern.compile("^([^:]*):\\s+(.*)$"); + private static JsonParser JSON_PARSER = new JsonParser(); private Socket socket; private InputStream in; @@ -79,22 +81,11 @@ public class HttpReader{ return result; } - public T readJson() throws Exception{ - String line = ""; - while (ready()){ - char[] c = new char[1]; - read(c); - line += c[0]; - if (c[0] == '}'){ - Object parse; - try { - parse = new JSONParser().parse(line); - if (parse != null) - return (T) parse; - }catch(Exception e){} - } - } - return null; + public J readJson() throws Exception{ + int length = Integer.parseInt(this.headers.get("content-length")); + //to limit + char[] content = new char[length]; + return JSON_PARSER.parse(new String(content)); } /* diff --git a/src/dev/peerat/framework/utils/json/Json.java b/src/dev/peerat/framework/utils/json/Json.java new file mode 100644 index 0000000..c02394d --- /dev/null +++ b/src/dev/peerat/framework/utils/json/Json.java @@ -0,0 +1,3 @@ +package dev.peerat.framework.utils.json; + +public interface Json{} diff --git a/src/dev/peerat/framework/utils/json/JsonArray.java b/src/dev/peerat/framework/utils/json/JsonArray.java new file mode 100644 index 0000000..69b10dc --- /dev/null +++ b/src/dev/peerat/framework/utils/json/JsonArray.java @@ -0,0 +1,24 @@ +package dev.peerat.framework.utils.json; + +import java.util.ArrayList; +import java.util.List; + +public class JsonArray implements Json{ + + private List list; + + public JsonArray(){ + this.list = new ArrayList<>(); + } + + public void add(Object value){ + this.list.add(value); + } + + @Override + public String toString(){ + return list.toString(); + } + + +} diff --git a/src/dev/peerat/framework/utils/json/JsonMap.java b/src/dev/peerat/framework/utils/json/JsonMap.java new file mode 100644 index 0000000..b317ffb --- /dev/null +++ b/src/dev/peerat/framework/utils/json/JsonMap.java @@ -0,0 +1,56 @@ +package dev.peerat.framework.utils.json; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class JsonMap implements Json{ + + private Map map; + + public JsonMap(){ + this.map = new HashMap<>(); + } + + public void set(String key, Object value){ + this.map.put(key, value); + } + + public boolean has(String key){ + return map.containsKey(key); + } + + public E get(String key){ + return (E) map.get(key); + } + + @Override + public String toString(){ + Iterator> iterator = map.entrySet().iterator(); + if(!iterator.hasNext()) return "{}"; + StringBuilder builder= new StringBuilder('{'); + while(iterator.hasNext()){ + Entry entry = iterator.next(); + builder.append('"'); + builder.append(entry.getKey()); + builder.append("\":"); + + Object value = entry.getValue(); + if(value instanceof String){ + builder.append('"'); + builder.append(value); + builder.append('"'); + }else if(value instanceof Character){ + builder.append('\''); + builder.append(value); + builder.append('\''); + }else{ + builder.append(value); + } + if(iterator.hasNext()) builder.append(','); + } + builder.append('}'); + return builder.toString(); + } +} diff --git a/src/dev/peerat/framework/utils/json/JsonParser.java b/src/dev/peerat/framework/utils/json/JsonParser.java new file mode 100644 index 0000000..cf8b207 --- /dev/null +++ b/src/dev/peerat/framework/utils/json/JsonParser.java @@ -0,0 +1,147 @@ +package dev.peerat.framework.utils.json; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import be.jeffcheasey88.peeratcode.parser.Parser; +import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.TokenType; +import be.jeffcheasey88.peeratcode.parser.state.RedirectStateTree; +import be.jeffcheasey88.peeratcode.parser.state.StateTree; + +public class JsonParser extends Parser{ + + private static StateTree base; + + static{ + base = new StateTree<>(); + + StateTree content = new StateTree<>(); + + StateTree content_array = new StateTree<>(); + StateTree content_array_element = content_array.then(new RedirectStateTree<>(content, (global, local) ->{ + List list = global.get(); + if(list == null){ + list = new ArrayList<>(); + global.set(list); + } + list.add(local.get()); + })); + content_array_element.end((parent, bag) -> { + JsonArray json = (JsonArray)parent; + + List list = bag.get(); + for(Object value : list){ + json.add(convert(value)); + } + return null; + }); + content_array_element.then((validator) -> validator.validate((token) -> token.getValue().equals(","))) + .then(content_array_element); + + content.then(new RedirectStateTree<>(base, (global, local) -> global.set(local.get()))).end(); + content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> bag.set(token))).end(); + content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.CHAR), (bag, token) -> bag.set(token))).end(); + content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set(token))).end(); + + StateTree mapper = new StateTree<>(); + StateTree mapper_key = mapper.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> { + Map map = bag.get("map"); + if(map == null){ + map = new HashMap<>(); + bag.set("map", map); + } + map.put(token, null); + bag.set("last", token); + })); + StateTree mapper_value = mapper_key.then((validator) -> validator.validate((token) -> token.getValue().equals(":"))) + .then(new RedirectStateTree<>(content, (global, local) -> { + global.>get("map").put(global.get("last"), local.get()); + })); + + mapper_value.end((parent, bag) -> { + Map map = bag.get("map"); + JsonMap jMap = (JsonMap)parent; + for(Entry entry : map.entrySet()){ + jMap.set(entry.getKey().getValue(), convert(entry.getValue())); + } + return null; + }); + mapper_value.then((validator) -> validator.validate((token) -> token.getValue().equals(","))) + .then(mapper_key); + + + base.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) + .end((parent, bag) -> { + JsonMap result = new JsonMap(); + bag.set(result); + if(parent instanceof JsonContainer) ((JsonContainer)parent).value = result; + return result; + }) + .unique(mapper) + .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) + .end(); + + base.then((validator) -> validator.validate((token) -> token.getValue().equals("["))) + .end((parent, bag) -> { + JsonArray result = new JsonArray(); + bag.set(result); + if(parent instanceof JsonContainer) ((JsonContainer)parent).value = result; + return result; + }) + .unique(content_array) + .unique((validator) -> validator.validate((token) -> token.getValue().equals("]"))) + .end(); + } + + private static Object convert(Object value){ + if(value instanceof Token){ + Token token = (Token) value; + String content = token.getValue(); + if(token.getType().equals(TokenType.STRING)){ + return content; + }else if(token.getType().equals(TokenType.CHAR)){ + return content.charAt(0); + }else{ + try{ + return Long.parseLong(content); + }catch(Exception _){ + try { + return Boolean.parseBoolean(content); + }catch(Exception __){ + try{ + return Double.parseDouble(content); + }catch(Exception ___){} + } + } + } + } + return value; + } + + public JsonParser(){ + setTokenizer(new JsonTokenizer()); + setStateTree(base); + } + + public J parse(String content) throws Exception{ + JsonContainer container = new JsonContainer(); + parse(content, container); + return container.getValue(); + } + + private static class JsonContainer implements Json{ + + private Json value; + + public JsonContainer(){} + + public J getValue(){ + return (J) this.value; + } + + } +} diff --git a/src/dev/peerat/framework/utils/json/JsonTokenizer.java b/src/dev/peerat/framework/utils/json/JsonTokenizer.java new file mode 100644 index 0000000..4271358 --- /dev/null +++ b/src/dev/peerat/framework/utils/json/JsonTokenizer.java @@ -0,0 +1,65 @@ +package dev.peerat.framework.utils.json; + +import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.TokenType; +import be.jeffcheasey88.peeratcode.parser.Tokenizer; + +public class JsonTokenizer extends Tokenizer{ + + @Override + public void parse(String line){ + for(int i = 0; i < line.length(); i++){ + char c = line.charAt(i); + + if(isValidName(c)){ + String buffer = ""+c; + int j = i+1; + for(; j < line.length(); j++){ + c = line.charAt(j); + if(isValidName(c)) buffer+=c; + else break; + } + getTokens().add(new Token(1, i+1, buffer, TokenType.NAME)); + i=j-1; + }else if(Character.isWhitespace(c)) continue; + else{ + if(c == '"'){ + String buffer = ""; + int j = i+1; + for(; j < line.length(); j++){ + c = line.charAt(j); + if(c == '\\'){ + buffer+=c+line.charAt(++j); + } + if(c == '\"') break; + buffer+=c; + } + getTokens().add(new Token(1, i+1, buffer, TokenType.STRING)); + i=j; + continue; + } + if(c == '\''){ + String buffer = ""; + int j = i+1; + for(; j < line.length(); j++){ + c = line.charAt(j); + if(c == '\\'){ + buffer+=c+line.charAt(++j); + } + if(c == '\'') break; + buffer+=c; + } + getTokens().add(new Token(1, i+1, buffer, TokenType.CHAR)); + i=j; + continue; + } + getTokens().add(new Token(1, i+1, ""+c, TokenType.DELIMITER)); + } + } + } + + private boolean isValidName(char c){ + return c == '_' || c == '-' || c == '$' || Character.isAlphabetic(c) || Character.isDigit(c); + } + +}