From 1000527a89d7df44bc803f1e0b3b74100a3cd192 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Mon, 17 Apr 2017 10:42:10 -0700 Subject: [PATCH 01/15] remove outdated comment --- src/main/java/me/doubledutch/lazyjson/LazyNode.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index e6517db..92e732a 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -7,9 +7,6 @@ import java.nio.charset.StandardCharsets; /** * The LazyNode is the primary output of the LazyParser. - * It should probably be named LazyNode instead of LazyNode, but as the - * project evolved, the name stuck and I have ironically been too lazy to - * change it! */ public final class LazyNode{ // Token types used for classification during parsing From 71850284fb00af992432a8487adca0602e1c9ccd Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Mon, 17 Apr 2017 10:47:30 -0700 Subject: [PATCH 02/15] add dirty flag --- src/main/java/me/doubledutch/lazyjson/LazyNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 92e732a..6acd4a6 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -27,6 +27,8 @@ public final class LazyNode{ protected byte type; + protected boolean dirty=false; + // Start and end index into source string for this token. // For an object or array, the end index will be the end of the entire // object or array. From d9efefd17e24776a82bbf88f983018d8a49e74d3 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Mon, 17 Apr 2017 10:51:33 -0700 Subject: [PATCH 03/15] dirty check on lazynode --- .../java/me/doubledutch/lazyjson/LazyNode.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 6acd4a6..1f4e5c3 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -52,6 +52,21 @@ protected LazyNode(byte type,int startIndex){ this.type=type; } + protected boolean isDirty(){ + if(dirty){ + return true; + } + if(child==null){ + return false; + } + LazyNode pointer=child; + while(pointer!=null){ + if(pointer.isDirty())return true; + pointer=child.next; + } + return false; + } + /** * Add a new child to the current linked list of child tokens * From 8263a41289230f770f41b5bca5291f700e992931 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Mon, 17 Apr 2017 17:25:45 -0700 Subject: [PATCH 04/15] first steps to string modifications --- build.gradle | 2 +- .../me/doubledutch/lazyjson/LazyElement.java | 7 ++- .../me/doubledutch/lazyjson/LazyNode.java | 13 +++- .../me/doubledutch/lazyjson/LazyObject.java | 59 ++++++++++++++++--- .../resources/lazyjson_version.properties | 8 +-- .../me/doubledutch/lazyjson/ModifyTest.java | 27 +++++++++ 6 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 src/test/java/me/doubledutch/lazyjson/ModifyTest.java diff --git a/build.gradle b/build.gradle index 140516f..1a3388c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -version = '1.3.0' +version = '2.0.0' group = "me.doubledutch" archivesBaseName = "lazyjson" diff --git a/src/main/java/me/doubledutch/lazyjson/LazyElement.java b/src/main/java/me/doubledutch/lazyjson/LazyElement.java index f4ac268..1fd3595 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyElement.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyElement.java @@ -7,6 +7,7 @@ public abstract class LazyElement{ protected LazyNode root; protected char[] cbuf; + protected StringBuilder dirtyBuf=null; // Cache value for length private int length=-1; @@ -88,7 +89,11 @@ public int length(){ * @return as string representation of this object as given in the source string */ public String toString(){ - return new String(cbuf,root.startIndex,root.endIndex-root.startIndex); + if(root.isDirty()){ + return "crap"; + }else{ + return new String(cbuf,root.startIndex,root.endIndex-root.startIndex); + } } /** diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 1f4e5c3..1291971 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -32,7 +32,7 @@ public final class LazyNode{ // Start and end index into source string for this token. // For an object or array, the end index will be the end of the entire // object or array. - protected final int startIndex; + protected int startIndex; protected int endIndex=-1; // Children are stored as a linked list by maintaining the first and last @@ -62,7 +62,7 @@ protected boolean isDirty(){ LazyNode pointer=child; while(pointer!=null){ if(pointer.isDirty())return true; - pointer=child.next; + pointer=pointer.next; } return false; } @@ -266,6 +266,10 @@ protected double getDoubleValue(char[] source) throws LazyException{ return d; } + protected String getStringValue(char[] source){ + return getStringValue(source,null); + } + /** * Extracts a string containing the characters given by this token. If the * token was marked as having escaped characters, they will be unescaped @@ -274,10 +278,13 @@ protected double getDoubleValue(char[] source) throws LazyException{ * @param source the source character array for this token * @return the string value held by this token */ - protected String getStringValue(char[] source){ + protected String getStringValue(char[] source,StringBuilder dirtyBuf){ if(type==VALUE_NULL){ return null; }else if(!(type==VALUE_ESTRING||type==EFIELD)){ + if(dirty){ + return dirtyBuf.substring(startIndex,endIndex); + } return new String(source,startIndex,endIndex-startIndex); }else{ StringBuilder buf=new StringBuilder(endIndex-startIndex); diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 7262c33..137bce0 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -65,6 +65,40 @@ public LazyType getType(String key) throws LazyException{ return null; } + public LazyObject put(String key,String value) throws LazyException{ + if(dirtyBuf==null){ + dirtyBuf=new StringBuilder(); + } + LazyNode token=getOptionalFieldToken(key); + if(token==null){ + // new field + token=LazyNode.cField(dirtyBuf.length()); + // TODO: we should be encoding the value + dirtyBuf.append(key); + token.endIndex=dirtyBuf.length(); + token.dirty=true; + LazyNode tokenChild=LazyNode.cStringValue(dirtyBuf.length()); + // TODO: we should be encoding the value + dirtyBuf.append(value); + tokenChild.endIndex=dirtyBuf.length(); + tokenChild.dirty=true; + token.child=tokenChild; + token.lastChild=tokenChild; + root.lastChild.next=token; + root.lastChild=token; + }else{ + // replace existing field + token.dirty=true; + token.type=LazyNode.VALUE_STRING; // TODO: use ESTRING when needed + + token.startIndex=dirtyBuf.length(); + // TODO: we should be encoding the value + dirtyBuf.append(value); + token.endIndex=dirtyBuf.length(); + } + return this; + } + /** * Returns the string value stored in this object for the given key. * @@ -74,7 +108,7 @@ public LazyType getType(String key) throws LazyException{ */ public String getString(String key) throws LazyException{ LazyNode token=getFieldToken(key); - return token.getStringValue(cbuf); + return token.getStringValue(cbuf,dirtyBuf); } /** @@ -88,7 +122,7 @@ public String optString(String key){ LazyNode token=getOptionalFieldToken(key); if(token==null)return null; if(token.type==LazyNode.VALUE_NULL)return null; - return token.getStringValue(cbuf); + return token.getStringValue(cbuf,dirtyBuf); } /** @@ -103,7 +137,7 @@ public String optString(String key,String defaultValue){ LazyNode token=getOptionalFieldToken(key); if(token==null)return defaultValue; if(token.type==LazyNode.VALUE_NULL)return defaultValue; - return token.getStringValue(cbuf); + return token.getStringValue(cbuf,dirtyBuf); } /** @@ -408,7 +442,7 @@ public int hashCode(){ */ private boolean keyMatch(String key,LazyNode token){ if(token.type==LazyNode.EFIELD){ - String field=token.getStringValue(cbuf); + String field=token.getStringValue(cbuf,dirtyBuf); return field.equals(key); }else{ // Quickly check the length first @@ -417,10 +451,19 @@ private boolean keyMatch(String key,LazyNode token){ return false; } // Now go through the field character for character to compare - for(int i=0;i Date: Tue, 18 Apr 2017 09:46:18 -0700 Subject: [PATCH 05/15] refactor modify object code --- .../me/doubledutch/lazyjson/LazyArray.java | 10 +- .../me/doubledutch/lazyjson/LazyElement.java | 9 +- .../me/doubledutch/lazyjson/LazyObject.java | 112 ++++++++++++++---- .../resources/lazyjson_version.properties | 6 +- .../me/doubledutch/lazyjson/ModifyTest.java | 12 ++ 5 files changed, 119 insertions(+), 30 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index 8b26870..503d548 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -24,8 +24,16 @@ public LazyArray(String raw) throws LazyException{ cbuf=parser.cbuf; } + protected LazyArray(LazyNode root,char[] source,StringBuilder dirtySource){ + super(root,source,dirtySource); + } + protected LazyArray(LazyNode root,char[] source){ - super(root,source); + super(root,source,null); + } + + protected String serializeElementToString(){ + return "Crap, not yet!"; } /** diff --git a/src/main/java/me/doubledutch/lazyjson/LazyElement.java b/src/main/java/me/doubledutch/lazyjson/LazyElement.java index 1fd3595..8f71bef 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyElement.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyElement.java @@ -12,9 +12,10 @@ public abstract class LazyElement{ // Cache value for length private int length=-1; - protected LazyElement(LazyNode root,char[] source){ + protected LazyElement(LazyNode root,char[] source,StringBuilder dirtySource){ this.root=root; this.cbuf=source; + this.dirtyBuf=dirtySource; } protected LazyElement() throws LazyException{ @@ -82,15 +83,17 @@ public int length(){ return length; } + protected abstract String serializeElementToString(); + /** * Returns a raw string extracted from the source string that covers the - * start and end index of this object. + * start and end index of this element. * * @return as string representation of this object as given in the source string */ public String toString(){ if(root.isDirty()){ - return "crap"; + return serializeElementToString(); }else{ return new String(cbuf,root.startIndex,root.endIndex-root.startIndex); } diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 137bce0..4ee98a8 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -28,8 +28,19 @@ public LazyObject(String raw) throws LazyException{ // source=raw; } + public LazyObject() throws LazyException{ + LazyParser parser=new LazyParser("{}"); + parser.tokenize(); + root=parser.root; + cbuf=parser.cbuf; + } + protected LazyObject(LazyNode root,char[] source){ - super(root,source); + super(root,source,null); + } + + protected LazyObject(LazyNode root,char[] source,StringBuilder dirtySource){ + super(root,source,dirtySource); } @@ -65,37 +76,73 @@ public LazyType getType(String key) throws LazyException{ return null; } - public LazyObject put(String key,String value) throws LazyException{ - if(dirtyBuf==null){ - dirtyBuf=new StringBuilder(); + protected String serializeElementToString(){ + StringBuilder buf=new StringBuilder(); + buf.append("{"); + LazyNode pointer=root.child; + boolean first=true; + while(pointer!=null){ + if(first){ + first=false; + }else{ + buf.append(","); + } + buf.append("\""); + buf.append(pointer.getStringValue(cbuf,dirtyBuf)); + buf.append("\":"); + if(pointer.child.type==LazyNode.OBJECT){ + buf.append(new LazyObject(pointer.child,cbuf,dirtyBuf).toString()); + }else if(pointer.child.type==LazyNode.ARRAY){ + buf.append(new LazyArray(pointer.child,cbuf,dirtyBuf).toString()); + }else if(pointer.child.type==LazyNode.VALUE_STRING || pointer.child.type==LazyNode.VALUE_ESTRING){ + buf.append("\""); + buf.append(pointer.child.getStringValue(cbuf,dirtyBuf)); + buf.append("\""); + }else{ + buf.append(pointer.child.getStringValue(cbuf,dirtyBuf)); + } + pointer=pointer.next; } - LazyNode token=getOptionalFieldToken(key); + buf.append("}"); + return buf.toString(); + } + + private void attachField(String key,LazyNode child) throws LazyException{ + LazyNode token=getOptionalField(key); if(token==null){ // new field token=LazyNode.cField(dirtyBuf.length()); + token.dirty=true; // TODO: we should be encoding the value dirtyBuf.append(key); token.endIndex=dirtyBuf.length(); - token.dirty=true; - LazyNode tokenChild=LazyNode.cStringValue(dirtyBuf.length()); - // TODO: we should be encoding the value - dirtyBuf.append(value); - tokenChild.endIndex=dirtyBuf.length(); - tokenChild.dirty=true; - token.child=tokenChild; - token.lastChild=tokenChild; - root.lastChild.next=token; - root.lastChild=token; - }else{ - // replace existing field - token.dirty=true; - token.type=LazyNode.VALUE_STRING; // TODO: use ESTRING when needed + if(root.child==null){ + root.child=token; + root.lastChild=token; + }else{ + root.lastChild.next=token; + root.lastChild=token; + } + } + token.child=child; + token.lastChild=child; + } - token.startIndex=dirtyBuf.length(); - // TODO: we should be encoding the value - dirtyBuf.append(value); - token.endIndex=dirtyBuf.length(); + private LazyNode appendAndSetDirtyString(byte type,String value) throws LazyException{ + if(dirtyBuf==null){ + dirtyBuf=new StringBuilder(); } + LazyNode child=new LazyNode(type,dirtyBuf.length()); + dirtyBuf.append(value); + child.endIndex=dirtyBuf.length(); + child.dirty=true; + return child; + } + + public LazyObject put(String key,String value) throws LazyException{ + // TODO: correctly detect and encode string values + LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_STRING,value); + attachField(key,child); return this; } @@ -528,6 +575,25 @@ private LazyNode getOptionalFieldToken(String key){ return null; } + /** + * Fields for an object are attached as children on the token representing + * the object itself. This method finds the correct field for a given key. + * This is a utility method used internally to extract field values. + * + * @param key the name of the desired field + * @return the first child of the matching field token if one exists, null otherwise + */ + private LazyNode getOptionalField(String key){ + LazyNode child=root.child; + while(child!=null){ + if(keyMatch(key,child)){ + return child; + } + child=child.next; + } + return null; + } + /* // For debug purposes only public String toString(int pad){ diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index 68c745b..fd4fe5d 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Mon Apr 17 17:24:23 PDT 2017 +#Tue Apr 18 09:46:03 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-18T00\:24\:23Z -BUILD_NUMBER=731 +BUILD_DATE=2017-04-18T16\:46\:03Z +BUILD_NUMBER=752 diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index daba4b8..e3ddb31 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -14,6 +14,7 @@ public void changeStringTest() throws LazyException{ assertEquals(obj.getString("foo"),"bar"); obj.put("foo","Hello World"); assertEquals(obj.getString("foo"),"Hello World"); + assertEquals(obj.toString(),"{\"foo\":\"Hello World\",\"baz\":42}"); } @Test @@ -23,5 +24,16 @@ public void addStringTest() throws LazyException{ obj.put("test","Hello World"); assertEquals(obj.getString("test"),"Hello World"); assertEquals(obj.getString("foo"),"bar"); + assertEquals(obj.toString(),"{\"foo\":\"bar\",\"baz\":42,\"test\":\"Hello World\"}"); + } + + @Test + public void buildObjectTest() throws LazyException{ + LazyObject obj=new LazyObject(); + obj.put("foo","bar"); + obj.put("test","Hello World"); + assertEquals(obj.getString("test"),"Hello World"); + assertEquals(obj.getString("foo"),"bar"); + assertEquals(obj.toString(),"{\"foo\":\"bar\",\"test\":\"Hello World\"}"); } } \ No newline at end of file From 834c17dddad00847f29608f6bcba3de2ccebb857 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Tue, 18 Apr 2017 10:30:27 -0700 Subject: [PATCH 06/15] Add more mutable value types --- .../me/doubledutch/lazyjson/LazyNode.java | 94 ++++++++++++++----- .../me/doubledutch/lazyjson/LazyObject.java | 58 ++++++++++-- .../resources/lazyjson_version.properties | 6 +- .../me/doubledutch/lazyjson/ModifyTest.java | 11 ++- 4 files changed, 132 insertions(+), 37 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 1291971..4850cdc 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -190,6 +190,10 @@ protected static LazyNode cValueNull(int index){ return new LazyNode(VALUE_NULL,index); } + protected int getIntValue(char[] source) throws LazyException{ + return getIntValue(source,null); + } + /** * Parses the characters of this token and attempts to construct an integer * value from them. @@ -198,27 +202,47 @@ protected static LazyNode cValueNull(int index){ * @return the integer value if it could be parsed * @throws LazyException if the value could not be parsed */ - protected int getIntValue(char[] source) throws LazyException{ + protected int getIntValue(char[] source,StringBuilder dirtyBuf) throws LazyException{ if(type!=VALUE_INTEGER)throw new LazyException("Not an integer",startIndex); int i=startIndex; boolean sign=false; - if(source[i]=='-'){ - sign=true; - i++; - } int value=0; - for(;i'9')throw new LazyException("'"+getStringValue(source)+"' is not a valid integer",startIndex); - value+='0'-c; - if(i+1'9')throw new LazyException("'"+getStringValue(source)+"' is not a valid integer",startIndex); + value+='0'-c; + if(i+1'9')throw new LazyException("'"+getStringValue(source)+"' is not a valid integer",startIndex); + value+='0'-c; + if(i+1'9')throw new LazyException("'"+getStringValue(source)+"' is not a valid integer",startIndex); + value+='0'-c; + if(i+1'9')throw new LazyException("'"+getStringValue(source)+"' is not a valid integer",startIndex); + value+='0'-c; + if(i+1 Date: Tue, 18 Apr 2017 17:14:56 -0700 Subject: [PATCH 07/15] first steps towards merging buffers --- .../me/doubledutch/lazyjson/LazyElement.java | 13 +++ .../me/doubledutch/lazyjson/LazyObject.java | 84 +++++++++++++++++-- .../resources/lazyjson_version.properties | 6 +- .../me/doubledutch/lazyjson/ModifyTest.java | 22 ++++- 4 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyElement.java b/src/main/java/me/doubledutch/lazyjson/LazyElement.java index 8f71bef..53ec9ad 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyElement.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyElement.java @@ -8,6 +8,7 @@ public abstract class LazyElement{ protected LazyNode root; protected char[] cbuf; protected StringBuilder dirtyBuf=null; + protected LazyElement parent; // Cache value for length private int length=-1; @@ -22,6 +23,18 @@ protected LazyElement() throws LazyException{ } + protected StringBuilder getDirtyBuf(){ + if(dirtyBuf!=null){ + return dirtyBuf; + } + if(parent!=null){ + dirtyBuf=parent.getDirtyBuf(); + return dirtyBuf; + } + dirtyBuf=new StringBuilder(); + return dirtyBuf; + } + protected char[] getCharBuffer(){ return cbuf; } diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 5f1d10a..8d38e94 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -11,6 +11,7 @@ * An object used to parse and inspect JSON data given in the form of a string. */ public class LazyObject extends LazyElement{ + public static final Object NULL=new Object(); /** * Create a new Lazy JSON object based on the JSON representation in the given string. * @@ -102,6 +103,8 @@ protected String serializeElementToString(){ buf.append("true"); }else if(pointer.child.type==LazyNode.VALUE_FALSE){ buf.append("false"); + }else if(pointer.child.type==LazyNode.VALUE_NULL){ + buf.append("null"); }else{ buf.append(pointer.child.getStringValue(cbuf,dirtyBuf)); } @@ -112,6 +115,8 @@ protected String serializeElementToString(){ } private void attachField(String key,LazyNode child) throws LazyException{ + // TODO: change to avoid this constant check + dirtyBuf=getDirtyBuf(); LazyNode token=getOptionalField(key); if(token==null){ // new field @@ -133,9 +138,7 @@ private void attachField(String key,LazyNode child) throws LazyException{ } private LazyNode appendAndSetDirtyString(byte type,String value) throws LazyException{ - if(dirtyBuf==null){ - dirtyBuf=new StringBuilder(); - } + dirtyBuf=getDirtyBuf(); LazyNode child=new LazyNode(type,dirtyBuf.length()); dirtyBuf.append(value); child.endIndex=dirtyBuf.length(); @@ -186,6 +189,65 @@ public LazyObject put(String key,boolean value) throws LazyException{ return this; } + public LazyObject put(String key,LazyObject value) throws LazyException{ + // StringBuilder db1=getDirtyBuf(); + // StringBuilder db2=getDirtyBuf(); + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + attachField(key,value.root); + System.out.println("all is the same"); + }else if(value.cbuf==cbuf && dirtyBuf==null && value.dirtyBuf!=null){ + // Same source, dirty value + dirtyBuf=value.dirtyBuf; + value.root.dirty=true; + attachField(key,value.root); + }else if(value.cbuf==cbuf && dirtyBuf!=null && value.dirtyBuf==null){ + // Same source, dirty self + value.root.dirty=true; + attachField(key,value.root); + }else{ + System.out.println("not matching put conditions"); + } + // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); + // attachField(key,child); + return this; + } + + public LazyObject put(String key,LazyArray value) throws LazyException{ + // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); + // attachField(key,child); + return this; + } + + public LazyObject put(String key,Object value) throws LazyException{ + if(value==NULL){ + LazyNode child=LazyNode.cValueNull(-1); + child.dirty=true; + attachField(key,child); + return this; + } + // TODO: look into faster ways of branching by type + if(value instanceof java.lang.Integer){ + return put(key,((Integer)value).intValue()); + } + if(value instanceof java.lang.Long){ + return put(key,((Long)value).longValue()); + } + if(value instanceof java.lang.Float){ + return put(key,((Float)value).floatValue()); + } + if(value instanceof java.lang.Double){ + return put(key,((Double)value).doubleValue()); + } + if(value instanceof java.lang.Boolean){ + return put(key,((Boolean)value).booleanValue()); + } + if(value instanceof java.lang.String){ + return put(key,(String)value); + } + throw new LazyException("Unsupported object type"); + } + /** * Returns the string value stored in this object for the given key. * @@ -419,7 +481,9 @@ public boolean optBoolean(String key,boolean defaultValue){ public LazyObject getJSONObject(String key) throws LazyException{ LazyNode token=getFieldToken(key); if(token.type!=LazyNode.OBJECT)throw new LazyException("Requested value is not an object",token); - return new LazyObject(token,cbuf); + LazyObject obj=new LazyObject(token,cbuf,dirtyBuf); + obj.parent=this; + return obj; } /** @@ -434,7 +498,9 @@ public LazyObject optJSONObject(String key) throws LazyException{ if(token==null)return null; if(token.type==LazyNode.VALUE_NULL)return null; if(token.type!=LazyNode.OBJECT)throw new LazyException("Requested value is not an object",token); - return new LazyObject(token,cbuf); + LazyObject obj=new LazyObject(token,cbuf,dirtyBuf); + obj.parent=this; + return obj; } /** @@ -447,7 +513,9 @@ public LazyObject optJSONObject(String key) throws LazyException{ public LazyArray getJSONArray(String key) throws LazyException{ LazyNode token=getFieldToken(key); if(token.type!=LazyNode.ARRAY)throw new LazyException("Requested value is not an array",token); - return new LazyArray(token,cbuf); + LazyArray arr=new LazyArray(token,cbuf,dirtyBuf); + arr.parent=this; + return arr; } /** @@ -462,7 +530,9 @@ public LazyArray optJSONArray(String key) throws LazyException{ if(token==null)return null; if(token.type==LazyNode.VALUE_NULL)return null; if(token.type!=LazyNode.ARRAY)throw new LazyException("Requested value is not an array",token); - return new LazyArray(token,cbuf); + LazyArray arr=new LazyArray(token,cbuf,dirtyBuf); + arr.parent=this; + return arr; } /** diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index edc6ba6..fecf92a 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Tue Apr 18 10:25:12 PDT 2017 +#Tue Apr 18 17:14:20 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-18T17\:25\:12Z -BUILD_NUMBER=765 +BUILD_DATE=2017-04-19T00\:14\:20Z +BUILD_NUMBER=787 diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index 7f7733d..17dad22 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -36,6 +36,7 @@ public void buildObjectTest() throws LazyException{ obj.put("fval",false); obj.put("tval",true); obj.put("test","Hello World"); + obj.put("nval",LazyObject.NULL); assertEquals(obj.getString("test"),"Hello World"); assertEquals(obj.getInt("baz"),42); assertEquals(obj.getLong("baz"),42l); @@ -43,6 +44,25 @@ public void buildObjectTest() throws LazyException{ assertEquals(obj.getBoolean("fval"),false); assertEquals(obj.getBoolean("tval"),true); assertEquals(obj.getString("foo"),"bar"); - assertEquals(obj.toString(),"{\"foo\":\"bar\",\"baz\":42,\"dval\":3.1415,\"fval\":false,\"tval\":true,\"test\":\"Hello World\"}"); + assertEquals(obj.toString(),"{\"foo\":\"bar\",\"baz\":42,\"dval\":3.1415,\"fval\":false,\"tval\":true,\"test\":\"Hello World\",\"nval\":null}"); + } + + @Test + public void cleanObjectToObject() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; + LazyObject obj=new LazyObject(str); + obj.put("test",obj.getJSONObject("baz")); + assertEquals(obj.getJSONObject("test").getInt("foo"),9); + } + + @Test + public void dirtyObjectToObjectSameBuf() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; + LazyObject obj=new LazyObject(str); + obj.getJSONObject("baz").put("foo",10); + System.out.println(obj.toString()); + obj.put("test",obj.getJSONObject("baz")); + System.out.println(obj.toString()); + assertEquals(obj.getJSONObject("test").getInt("foo"),10); } } \ No newline at end of file From bfdb6a64dc4255063c2d08709e1166298fbf584b Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Tue, 18 Apr 2017 17:59:30 -0700 Subject: [PATCH 08/15] merge objects from separate sources --- .../java/me/doubledutch/lazyjson/LazyNode.java | 15 +++++++++++++++ .../java/me/doubledutch/lazyjson/LazyObject.java | 9 ++++++--- src/main/resources/lazyjson_version.properties | 6 +++--- .../java/me/doubledutch/lazyjson/ModifyTest.java | 13 +++++++++++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 4850cdc..e366554 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -52,6 +52,21 @@ protected LazyNode(byte type,int startIndex){ this.type=type; } + protected void moveInto(StringBuilder buf,char[] source,StringBuilder dirtyBuf){ + if(endIndex>-1){ + int newIndex=buf.length(); + buf.append( getStringValue(source,dirtyBuf)); + startIndex=newIndex; + endIndex=buf.length(); + } + dirty=true; + LazyNode pointer=child; + while(pointer!=null){ + pointer.moveInto(buf,source,dirtyBuf); + pointer=pointer.next; + } + } + protected boolean isDirty(){ if(dirty){ return true; diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 8d38e94..1ae2e89 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -195,7 +195,6 @@ public LazyObject put(String key,LazyObject value) throws LazyException{ if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ value.root.dirty=true; attachField(key,value.root); - System.out.println("all is the same"); }else if(value.cbuf==cbuf && dirtyBuf==null && value.dirtyBuf!=null){ // Same source, dirty value dirtyBuf=value.dirtyBuf; @@ -205,8 +204,12 @@ public LazyObject put(String key,LazyObject value) throws LazyException{ // Same source, dirty self value.root.dirty=true; attachField(key,value.root); - }else{ - System.out.println("not matching put conditions"); + }else if(value.cbuf!=cbuf){ + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + attachField(key,value.root); + // System.out.println("not matching put conditions"); } // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); // attachField(key,child); diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index fecf92a..db15e10 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Tue Apr 18 17:14:20 PDT 2017 +#Tue Apr 18 17:59:02 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-19T00\:14\:20Z -BUILD_NUMBER=787 +BUILD_DATE=2017-04-19T00\:59\:02Z +BUILD_NUMBER=792 diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index 17dad22..ccf1a77 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -60,9 +60,18 @@ public void dirtyObjectToObjectSameBuf() throws LazyException{ String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; LazyObject obj=new LazyObject(str); obj.getJSONObject("baz").put("foo",10); - System.out.println(obj.toString()); obj.put("test",obj.getJSONObject("baz")); - System.out.println(obj.toString()); assertEquals(obj.getJSONObject("test").getInt("foo"),10); } + + @Test + public void separateBufObjectToObject() throws LazyException{ + String str1="{\"foo\":\"bar\"}"; + String str2="{\"baz\":{\"foo\":9}}"; + LazyObject obj1=new LazyObject(str1); + LazyObject obj2=new LazyObject(str2); + + obj1.put("test",obj2.getJSONObject("baz")); + assertEquals(obj1.getJSONObject("test").getInt("foo"),9); + } } \ No newline at end of file From 14d3ec163adf1453083a34d5085ca11dea9a5231 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Wed, 19 Apr 2017 16:28:56 -0700 Subject: [PATCH 09/15] add get and opt methods on lazyobject --- .../me/doubledutch/lazyjson/LazyObject.java | 42 +++++++++++++++++-- .../resources/lazyjson_version.properties | 6 +-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 1ae2e89..283d7de 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -77,6 +77,43 @@ public LazyType getType(String key) throws LazyException{ return null; } + public Object opt(String key) throws LazyException{ + LazyNode token=getOptionalFieldToken(key); + if(token!=null){ + switch(token.type){ + case LazyNode.OBJECT: return new LazyObject(token,cbuf,dirtyBuf); + case LazyNode.ARRAY: return new LazyArray(token,cbuf,dirtyBuf); + case LazyNode.VALUE_TRUE: return (Boolean)true; + case LazyNode.VALUE_FALSE: return (Boolean)false; + case LazyNode.VALUE_NULL: return null; + case LazyNode.VALUE_STRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_ESTRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_INTEGER: return (Integer)token.getIntValue(cbuf,dirtyBuf); + case LazyNode.VALUE_FLOAT: return (Double)token.getDoubleValue(cbuf,dirtyBuf); + } + } + return null; + } + + public Object get(String key) throws LazyException{ + LazyNode token=getFieldToken(key); + if(token!=null){ + switch(token.type){ + case LazyNode.OBJECT: return new LazyObject(token,cbuf,dirtyBuf); + case LazyNode.ARRAY: return new LazyArray(token,cbuf,dirtyBuf); + case LazyNode.VALUE_TRUE: return (Boolean)true; + case LazyNode.VALUE_FALSE: return (Boolean)false; + case LazyNode.VALUE_NULL: return null; + case LazyNode.VALUE_STRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_ESTRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_INTEGER: return (Integer)token.getIntValue(cbuf,dirtyBuf); + case LazyNode.VALUE_FLOAT: return (Double)token.getDoubleValue(cbuf,dirtyBuf); + } + } + // Should never happen + return null; + } + protected String serializeElementToString(){ StringBuilder buf=new StringBuilder(); buf.append("{"); @@ -190,8 +227,6 @@ public LazyObject put(String key,boolean value) throws LazyException{ } public LazyObject put(String key,LazyObject value) throws LazyException{ - // StringBuilder db1=getDirtyBuf(); - // StringBuilder db2=getDirtyBuf(); if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ value.root.dirty=true; attachField(key,value.root); @@ -205,12 +240,13 @@ public LazyObject put(String key,LazyObject value) throws LazyException{ value.root.dirty=true; attachField(key,value.root); }else if(value.cbuf!=cbuf){ + // Differen't sources StringBuilder buf=getDirtyBuf(); value.root.moveInto(buf,value.cbuf,value.dirtyBuf); value.root.dirty=true; attachField(key,value.root); // System.out.println("not matching put conditions"); - } + }else throw new LazyException("Unknown data merge condition :-( :-( :-("); // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); // attachField(key,child); return this; diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index db15e10..16d62d6 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Tue Apr 18 17:59:02 PDT 2017 +#Wed Apr 19 16:26:04 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-19T00\:59\:02Z -BUILD_NUMBER=792 +BUILD_DATE=2017-04-19T23\:26\:04Z +BUILD_NUMBER=795 From 077af9dc27419064521ab946b03125c725d4c1f5 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Wed, 19 Apr 2017 17:42:59 -0700 Subject: [PATCH 10/15] implement remove --- .../me/doubledutch/lazyjson/LazyObject.java | 21 +++++++++++++++++++ .../resources/lazyjson_version.properties | 6 +++--- .../doubledutch/lazyjson/LazyObjectTest.java | 8 +++++++ .../me/doubledutch/lazyjson/ModifyTest.java | 9 ++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index 283d7de..6034e68 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -114,6 +114,27 @@ public Object get(String key) throws LazyException{ return null; } + public Object remove(String key) throws LazyException{ + Object obj=opt(key); // TODO: should this be get instead of opt? + LazyNode token=getOptionalField(key); + if(token!=null){ + System.out.println("found the token!"); + LazyNode pointer=this.root.child; + if(pointer==token){ + root.child=token.next; + }else{ + while(pointer!=null){ + if(pointer.next==token){ + pointer.next=token.next; + } + pointer=pointer.next; + } + } + root.dirty=true; + } + return obj; + } + protected String serializeElementToString(){ StringBuilder buf=new StringBuilder(); buf.append("{"); diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index 16d62d6..5fa4e16 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Wed Apr 19 16:26:04 PDT 2017 +#Wed Apr 19 17:42:22 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-19T23\:26\:04Z -BUILD_NUMBER=795 +BUILD_DATE=2017-04-20T00\:42\:22Z +BUILD_NUMBER=801 diff --git a/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java b/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java index 722284e..ca7768f 100644 --- a/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java +++ b/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java @@ -44,6 +44,14 @@ public void testMissingFields() throws LazyException{ obj.getString("bar"); } + @Test + public void objectGet() throws LazyException{ + String str="{\"foo\":9,\"bar\":true}"; + LazyObject obj=new LazyObject(str); + assertTrue(obj.get("foo") instanceof Integer); + assertTrue(obj.get("bar") instanceof Boolean); + } + @Test public void optionalArrayTest() throws LazyException{ String str="{\"foo\":[],\"bar\":null}"; diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index ccf1a77..82be9a6 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -47,6 +47,15 @@ public void buildObjectTest() throws LazyException{ assertEquals(obj.toString(),"{\"foo\":\"bar\",\"baz\":42,\"dval\":3.1415,\"fval\":false,\"tval\":true,\"test\":\"Hello World\",\"nval\":null}"); } + @Test + public void removeKeyTest() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; + LazyObject obj=new LazyObject(str); + obj.remove("baz"); + assertFalse(obj.has("baz")); + assertEquals(obj.getString("foo"),"bar"); + } + @Test public void cleanObjectToObject() throws LazyException{ String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; From 5da94ca54b430ea1f5413775a546c3f2c806fc4c Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Thu, 20 Apr 2017 10:37:40 -0700 Subject: [PATCH 11/15] initial array put methods --- .../me/doubledutch/lazyjson/LazyArray.java | 117 ++++++++++++++++++ .../me/doubledutch/lazyjson/LazyElement.java | 9 ++ .../me/doubledutch/lazyjson/LazyObject.java | 9 -- .../resources/lazyjson_version.properties | 6 +- .../doubledutch/lazyjson/LazyArrayTest.java | 8 ++ 5 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index 503d548..35f158e 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -98,6 +98,123 @@ public LazyType getType(int index) throws LazyException{ return null; } + public Object get(int index) throws LazyException{ + LazyNode token=getValueToken(index); + if(token!=null){ + switch(token.type){ + case LazyNode.OBJECT: return new LazyObject(token,cbuf,dirtyBuf); + case LazyNode.ARRAY: return new LazyArray(token,cbuf,dirtyBuf); + case LazyNode.VALUE_TRUE: return (Boolean)true; + case LazyNode.VALUE_FALSE: return (Boolean)false; + case LazyNode.VALUE_NULL: return null; + case LazyNode.VALUE_STRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_ESTRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_INTEGER: return (Integer)token.getIntValue(cbuf,dirtyBuf); + case LazyNode.VALUE_FLOAT: return (Double)token.getDoubleValue(cbuf,dirtyBuf); + } + } + // Should never happen + return null; + } + + public Object opt(int index) throws LazyException{ + LazyNode token=getOptionalValueToken(index); + if(token!=null){ + switch(token.type){ + case LazyNode.OBJECT: return new LazyObject(token,cbuf,dirtyBuf); + case LazyNode.ARRAY: return new LazyArray(token,cbuf,dirtyBuf); + case LazyNode.VALUE_TRUE: return (Boolean)true; + case LazyNode.VALUE_FALSE: return (Boolean)false; + case LazyNode.VALUE_NULL: return null; + case LazyNode.VALUE_STRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_ESTRING: return token.getStringValue(cbuf,dirtyBuf); + case LazyNode.VALUE_INTEGER: return (Integer)token.getIntValue(cbuf,dirtyBuf); + case LazyNode.VALUE_FLOAT: return (Double)token.getDoubleValue(cbuf,dirtyBuf); + } + } + return null; + } + + private void appendChild(LazyNode token) throws LazyException{ + if(root.child==null){ + root.child=token; + root.lastChild=token; + }else{ + root.lastChild.next=token; + root.lastChild=token; + } + root.dirty=true; + } + + private void insertChild(int index,LazyNode token) throws LazyException{ + root.dirty=true; + if(index==0){ + token.next=root.child; + root.child=token; + return; + } + int current=0; + LazyNode pointer=root.child; + if(pointer==null)throw new LazyException("Trying to put at index "+index+" on an empty LazyArray"); + while(current Date: Thu, 20 Apr 2017 12:23:38 -0700 Subject: [PATCH 12/15] improve test coverage --- .../me/doubledutch/lazyjson/LazyArray.java | 91 +++++++++++++++---- .../me/doubledutch/lazyjson/LazyNode.java | 3 - .../resources/lazyjson_version.properties | 6 +- .../doubledutch/lazyjson/LazyArrayTest.java | 35 ++++++- .../doubledutch/lazyjson/LazyObjectTest.java | 55 ++++++++++- .../me/doubledutch/lazyjson/LazyTypeTest.java | 6 ++ .../me/doubledutch/lazyjson/ModifyTest.java | 77 +++++++++++++++- .../lazyjson/compressor/TemplateTest.java | 4 +- 8 files changed, 247 insertions(+), 30 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index 35f158e..b7a590f 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -24,6 +24,13 @@ public LazyArray(String raw) throws LazyException{ cbuf=parser.cbuf; } + public LazyArray() throws LazyException{ + LazyParser parser=new LazyParser("[]"); + parser.tokenize(); + root=parser.root; + cbuf=parser.cbuf; + } + protected LazyArray(LazyNode root,char[] source,StringBuilder dirtySource){ super(root,source,dirtySource); } @@ -153,7 +160,7 @@ private void insertChild(int index,LazyNode token) throws LazyException{ root.child=token; return; } - int current=0; + int current=1; LazyNode pointer=root.child; if(pointer==null)throw new LazyException("Trying to put at index "+index+" on an empty LazyArray"); while(current Date: Thu, 20 Apr 2017 13:20:26 -0700 Subject: [PATCH 13/15] increase test coverage --- .../java/me/doubledutch/lazyjson/LazyArray.java | 4 ++-- src/main/resources/lazyjson_version.properties | 6 +++--- .../java/me/doubledutch/lazyjson/LazyArrayTest.java | 11 +++++++++-- .../me/doubledutch/lazyjson/LazyObjectTest.java | 11 +++++++++-- .../java/me/doubledutch/lazyjson/ModifyTest.java | 13 +++++++++++++ 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index b7a590f..6620222 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -34,10 +34,10 @@ public LazyArray() throws LazyException{ protected LazyArray(LazyNode root,char[] source,StringBuilder dirtySource){ super(root,source,dirtySource); } - + /* protected LazyArray(LazyNode root,char[] source){ super(root,source,null); - } + }*/ protected String serializeElementToString(){ return "Crap, not yet!"; diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index d00d1bb..34577b1 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Thu Apr 20 12:21:55 PDT 2017 +#Thu Apr 20 13:19:42 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-20T19\:21\:55Z -BUILD_NUMBER=847 +BUILD_DATE=2017-04-20T20\:19\:42Z +BUILD_NUMBER=856 diff --git a/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java b/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java index 400baa1..463bdf4 100644 --- a/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java +++ b/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java @@ -40,7 +40,7 @@ public void testInnerEquals() throws LazyException{ @Test public void arrayGet() throws LazyException{ - String str="[\"foo\",9,true,false,3.1415,null]"; + String str="[\"foo\",9,true,false,3.1415,null,{\"foo\":42},[2,2,2],\"\\n\"]"; LazyArray arr=new LazyArray(str); assertTrue(arr.get(0) instanceof String); assertTrue(arr.get(1) instanceof Integer); @@ -48,11 +48,14 @@ public void arrayGet() throws LazyException{ assertTrue(arr.get(3) instanceof Boolean); assertTrue(arr.get(4) instanceof Double); assertNull(arr.get(5)); + assertTrue(arr.get(6) instanceof LazyObject); + assertTrue(arr.get(7) instanceof LazyArray); + assertTrue(arr.get(8) instanceof String); } @Test public void arrayOpt() throws LazyException{ - String str="[\"foo\",9,true,false,3.1415,null]"; + String str="[\"foo\",9,true,false,3.1415,null,{\"foo\":42},[2,2,2],\"\\n\"]"; LazyArray arr=new LazyArray(str); assertTrue(arr.opt(0) instanceof String); assertTrue(arr.opt(1) instanceof Integer); @@ -60,6 +63,10 @@ public void arrayOpt() throws LazyException{ assertTrue(arr.opt(3) instanceof Boolean); assertTrue(arr.opt(4) instanceof Double); assertNull(arr.opt(5)); + assertTrue(arr.opt(6) instanceof LazyObject); + assertTrue(arr.opt(7) instanceof LazyArray); + assertTrue(arr.opt(8) instanceof String); + assertNull(arr.opt(9)); } @Test(expected=LazyException.class) diff --git a/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java b/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java index 522bb41..ec2d4b6 100644 --- a/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java +++ b/src/test/java/me/doubledutch/lazyjson/LazyObjectTest.java @@ -82,7 +82,7 @@ public void testMissingFields() throws LazyException{ @Test public void objectGet() throws LazyException{ - String str="{\"foo\":9,\"bar\":true,\"baz\":3.1415,\"sval\":\"hello world\",\"fval\":false,\"nval\":null}"; + String str="{\"foo\":9,\"bar\":true,\"baz\":3.1415,\"sval\":\"hello world\",\"fval\":false,\"nval\":null,\"aval\":[2,2,4],\"oval\":{\"foo\":42},\"eval\":\"\\n\"}"; LazyObject obj=new LazyObject(str); assertTrue(obj.get("foo") instanceof Integer); assertTrue(obj.get("bar") instanceof Boolean); @@ -90,11 +90,14 @@ public void objectGet() throws LazyException{ assertTrue(obj.get("sval") instanceof String); assertTrue(obj.get("fval") instanceof Boolean); assertNull(obj.get("nval")); + assertTrue(obj.get("aval") instanceof LazyArray); + assertTrue(obj.get("oval") instanceof LazyObject); + assertTrue(obj.get("eval") instanceof String); } @Test public void objectOpt() throws LazyException{ - String str="{\"foo\":9,\"bar\":true,\"baz\":3.1415,\"sval\":\"hello world\",\"fval\":false,\"nval\":null}"; + String str="{\"foo\":9,\"bar\":true,\"baz\":3.1415,\"sval\":\"hello world\",\"fval\":false,\"nval\":null,\"aval\":[2,2,4],\"oval\":{\"foo\":42},\"eval\":\"\\n\"}"; LazyObject obj=new LazyObject(str); assertTrue(obj.opt("foo") instanceof Integer); assertTrue(obj.opt("bar") instanceof Boolean); @@ -102,6 +105,10 @@ public void objectOpt() throws LazyException{ assertTrue(obj.opt("sval") instanceof String); assertTrue(obj.opt("fval") instanceof Boolean); assertNull(obj.opt("nval")); + assertTrue(obj.opt("aval") instanceof LazyArray); + assertTrue(obj.opt("oval") instanceof LazyObject); + assertTrue(obj.opt("eval") instanceof String); + assertNull(obj.opt("does-not-exist")); } diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index 094a74e..5537c68 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -111,6 +111,19 @@ public void insertArrayTest() throws LazyException{ assertEquals(arr.getBoolean(6),false); } + @Test(expected=LazyException.class) + public void badInsertArrayTestA() throws LazyException{ + LazyArray arr=new LazyArray("[]"); + arr.put(1,"foo"); + } + + @Test(expected=LazyException.class) + public void badInsertArrayTestB() throws LazyException{ + LazyArray arr=new LazyArray("[2,4]"); + arr.put(19,"foo"); + } + + @Test public void removeKeyTest() throws LazyException{ String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; From d2084c836d1179af0b6166a8aa7e410536dfbde7 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Thu, 20 Apr 2017 15:03:51 -0700 Subject: [PATCH 14/15] complete modification interface --- .../me/doubledutch/lazyjson/LazyArray.java | 104 +++++++++++++++++- .../me/doubledutch/lazyjson/LazyNode.java | 8 +- .../me/doubledutch/lazyjson/LazyObject.java | 28 +++-- .../resources/lazyjson_version.properties | 6 +- .../doubledutch/lazyjson/LazyArrayTest.java | 20 ++++ .../me/doubledutch/lazyjson/LazyTypeTest.java | 6 +- .../me/doubledutch/lazyjson/ModifyTest.java | 91 ++++++++++++++- 7 files changed, 236 insertions(+), 27 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index 6620222..9f64214 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -40,7 +40,37 @@ protected LazyArray(LazyNode root,char[] source){ }*/ protected String serializeElementToString(){ - return "Crap, not yet!"; + StringBuilder buf=new StringBuilder(); + buf.append("["); + LazyNode pointer=root.child; + boolean first=true; + while(pointer!=null){ + if(first){ + first=false; + }else{ + buf.append(","); + } + if(pointer.type==LazyNode.OBJECT){ + buf.append(new LazyObject(pointer,cbuf,dirtyBuf).toString()); + }else if(pointer.type==LazyNode.ARRAY){ + buf.append(new LazyArray(pointer,cbuf,dirtyBuf).toString()); + }else if(pointer.type==LazyNode.VALUE_STRING || pointer.type==LazyNode.VALUE_ESTRING){ + buf.append("\""); + buf.append(pointer.getStringValue(cbuf,dirtyBuf)); + buf.append("\""); + }else if(pointer.type==LazyNode.VALUE_TRUE){ + buf.append("true"); + }else if(pointer.type==LazyNode.VALUE_FALSE){ + buf.append("false"); + }else if(pointer.type==LazyNode.VALUE_NULL){ + buf.append("null"); + }else{ + buf.append(pointer.getStringValue(cbuf,dirtyBuf)); + } + pointer=pointer.next; + } + buf.append("]"); + return buf.toString(); } /** @@ -151,6 +181,8 @@ private void appendChild(LazyNode token) throws LazyException{ root.lastChild=token; } root.dirty=true; + selectToken=null; + selectInt=-1; } private void insertChild(int index,LazyNode token) throws LazyException{ @@ -170,6 +202,8 @@ private void insertChild(int index,LazyNode token) throws LazyException{ } token.next=pointer.next; pointer.next=token; + selectToken=null; + selectInt=-1; } public LazyArray put(String value) throws LazyException{ @@ -215,10 +249,32 @@ public LazyArray put(boolean value) throws LazyException{ } public LazyArray put(LazyArray value) throws LazyException{ + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + appendChild(value.root); + }else if(value.cbuf!=cbuf){ + // Differen't sources + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + appendChild(value.root); + // System.out.println("not matching put conditions"); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } public LazyArray put(LazyObject value) throws LazyException{ + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + appendChild(value.root); + }else if(value.cbuf!=cbuf){ + // Differen't sources + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + appendChild(value.root); + // System.out.println("not matching put conditions"); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } @@ -265,13 +321,59 @@ public LazyArray put(int index,boolean value) throws LazyException{ } public LazyArray put(int index,LazyArray value) throws LazyException{ + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + insertChild(index,value.root); + }else if(value.cbuf!=cbuf){ + // Differen't sources + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + insertChild(index,value.root); + // System.out.println("not matching put conditions"); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } public LazyArray put(int index,LazyObject value) throws LazyException{ + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + insertChild(index,value.root); + }else if(value.cbuf!=cbuf){ + // Differen't sources + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + insertChild(index,value.root); + // System.out.println("not matching put conditions"); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } + public Object remove(int index) throws LazyException{ + Object obj=opt(index); // TODO: should this be get instead of opt? + LazyNode token=getOptionalValueToken(index); + if(token!=null){ + // System.out.println("found the token!"); + LazyNode pointer=this.root.child; + if(pointer==token){ + System.out.println("yes, it was the first"); + root.child=token.next; + }else{ + while(pointer!=null){ + if(pointer.next==token){ + pointer.next=token.next; + } + pointer=pointer.next; + } + } + root.dirty=true; + } + selectToken=null; + selectInt=-1; + return obj; + } + /** * Returns the JSON array stored at the given index. * diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 1efd9b6..2f01e03 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -53,9 +53,9 @@ protected LazyNode(byte type,int startIndex){ } protected void moveInto(StringBuilder buf,char[] source,StringBuilder dirtyBuf){ - if(endIndex>-1){ + if(endIndex>-1 && type!=OBJECT && type!=ARRAY){ int newIndex=buf.length(); - buf.append( getStringValue(source,dirtyBuf)); + buf.append(getStringValue(source,dirtyBuf)); startIndex=newIndex; endIndex=buf.length(); } @@ -201,10 +201,10 @@ protected static LazyNode cValueFalse(int index){ protected static LazyNode cValueNull(int index){ return new LazyNode(VALUE_NULL,index); } - + /* protected int getIntValue(char[] source) throws LazyException{ return getIntValue(source,null); - } + }*/ /** * Parses the characters of this token and attempts to construct an integer diff --git a/src/main/java/me/doubledutch/lazyjson/LazyObject.java b/src/main/java/me/doubledutch/lazyjson/LazyObject.java index dc855b9..db8f3b9 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyObject.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyObject.java @@ -118,7 +118,7 @@ public Object remove(String key) throws LazyException{ Object obj=opt(key); // TODO: should this be get instead of opt? LazyNode token=getOptionalField(key); if(token!=null){ - System.out.println("found the token!"); + // System.out.println("found the token!"); LazyNode pointer=this.root.child; if(pointer==token){ root.child=token.next; @@ -242,15 +242,6 @@ public LazyObject put(String key,LazyObject value) throws LazyException{ if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ value.root.dirty=true; attachField(key,value.root); - }else if(value.cbuf==cbuf && dirtyBuf==null && value.dirtyBuf!=null){ - // Same source, dirty value - dirtyBuf=value.dirtyBuf; - value.root.dirty=true; - attachField(key,value.root); - }else if(value.cbuf==cbuf && dirtyBuf!=null && value.dirtyBuf==null){ - // Same source, dirty self - value.root.dirty=true; - attachField(key,value.root); }else if(value.cbuf!=cbuf){ // Differen't sources StringBuilder buf=getDirtyBuf(); @@ -258,15 +249,22 @@ public LazyObject put(String key,LazyObject value) throws LazyException{ value.root.dirty=true; attachField(key,value.root); // System.out.println("not matching put conditions"); - }else throw new LazyException("Unknown data merge condition :-( :-( :-("); - // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); - // attachField(key,child); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } public LazyObject put(String key,LazyArray value) throws LazyException{ - // LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_FLOAT,Double.toString(value)); - // attachField(key,child); + if(value.cbuf==cbuf && value.dirtyBuf==dirtyBuf){ + value.root.dirty=true; + attachField(key,value.root); + }else if(value.cbuf!=cbuf){ + // Differen't sources + StringBuilder buf=getDirtyBuf(); + value.root.moveInto(buf,value.cbuf,value.dirtyBuf); + value.root.dirty=true; + attachField(key,value.root); + // System.out.println("not matching put conditions"); + }// else throw new LazyException("Unknown data merge condition :-( :-( :-("); return this; } diff --git a/src/main/resources/lazyjson_version.properties b/src/main/resources/lazyjson_version.properties index 34577b1..12ee17a 100644 --- a/src/main/resources/lazyjson_version.properties +++ b/src/main/resources/lazyjson_version.properties @@ -1,4 +1,4 @@ -#Thu Apr 20 13:19:42 PDT 2017 +#Thu Apr 20 15:00:53 PDT 2017 BUILD_VERSION=2.0.0 -BUILD_DATE=2017-04-20T20\:19\:42Z -BUILD_NUMBER=856 +BUILD_DATE=2017-04-20T22\:00\:53Z +BUILD_NUMBER=900 diff --git a/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java b/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java index 463bdf4..050b481 100644 --- a/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java +++ b/src/test/java/me/doubledutch/lazyjson/LazyArrayTest.java @@ -23,6 +23,26 @@ public void testLength() throws LazyException{ assertEquals(3,array.length()); } + @Test + public void testHashCode() throws LazyException{ + String str1="[false,null,true]"; + String str2="[2,[2,2,4],\"foo\"]"; + LazyArray arr1=new LazyArray(str1); + LazyArray arr2=new LazyArray(str2); + assertNotEquals(arr1.hashCode(),arr2.hashCode()); + } + + @Test + public void testRemove() throws LazyException{ + String str="[2,false,null,true,9]"; + LazyArray array=new LazyArray(str); + array.remove(0); + assertEquals(4,array.length()); + assertEquals(9,array.getInt(3)); + array.remove(2); + assertEquals(9,array.getInt(2)); + } + @Test public void testInnerEquals() throws LazyException{ String str1="[9,false,[3,4,5]]"; diff --git a/src/test/java/me/doubledutch/lazyjson/LazyTypeTest.java b/src/test/java/me/doubledutch/lazyjson/LazyTypeTest.java index ceacc01..6e14616 100644 --- a/src/test/java/me/doubledutch/lazyjson/LazyTypeTest.java +++ b/src/test/java/me/doubledutch/lazyjson/LazyTypeTest.java @@ -11,10 +11,11 @@ public class LazyTypeTest{ @Test public void testObjectValueTypes() throws LazyException{ - LazyObject obj=new LazyObject("{\"foo\":42,\"bar\":3.1415,\"baz\":\"Hello World!\",\"bonk\":false,\"test\":null,\"obj\":{},\"arr\":[]}"); + LazyObject obj=new LazyObject("{\"foo\":42,\"bar\":3.1415,\"baz\":\"Hello World!\",\"baz2\":\"\\n\",\"bonk\":false,\"test\":null,\"obj\":{},\"arr\":[]}"); assertEquals(obj.getType("foo"),LazyType.INTEGER); assertEquals(obj.getType("bar"),LazyType.FLOAT); assertEquals(obj.getType("baz"),LazyType.STRING); + assertEquals(obj.getType("baz2"),LazyType.STRING); assertEquals(obj.getType("bonk"),LazyType.BOOLEAN); assertEquals(obj.getType("test"),LazyType.NULL); assertEquals(obj.getType("obj"),LazyType.OBJECT); @@ -23,7 +24,7 @@ public void testObjectValueTypes() throws LazyException{ @Test public void testArrayValueTypes() throws LazyException{ - LazyArray arr=new LazyArray("[42,3.1415,\"Hello World!\",false,null,{},[]]"); + LazyArray arr=new LazyArray("[42,3.1415,\"Hello World!\",false,null,{},[],\"\\n\"]"); assertEquals(arr.getType(0),LazyType.INTEGER); assertEquals(arr.getType(1),LazyType.FLOAT); assertEquals(arr.getType(2),LazyType.STRING); @@ -31,6 +32,7 @@ public void testArrayValueTypes() throws LazyException{ assertEquals(arr.getType(4),LazyType.NULL); assertEquals(arr.getType(5),LazyType.OBJECT); assertEquals(arr.getType(6),LazyType.ARRAY); + assertEquals(arr.getType(7),LazyType.STRING); } diff --git a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java index 5537c68..b4c7db7 100644 --- a/src/test/java/me/doubledutch/lazyjson/ModifyTest.java +++ b/src/test/java/me/doubledutch/lazyjson/ModifyTest.java @@ -9,12 +9,12 @@ public class ModifyTest{ @Test public void changeStringTest() throws LazyException{ - String str="{\"foo\":\"bar\",\"baz\":42}"; + String str="{\"foo\":\"bar\",\"baz\":42,\"aval\":[2,2,4],\"oval\":{\"foo\":9}}"; LazyObject obj=new LazyObject(str); assertEquals(obj.getString("foo"),"bar"); obj.put("foo","Hello World"); assertEquals(obj.getString("foo"),"Hello World"); - assertEquals(obj.toString(),"{\"foo\":\"Hello World\",\"baz\":42}"); + assertEquals(obj.toString(),"{\"foo\":\"Hello World\",\"baz\":42,\"aval\":[2,2,4],\"oval\":{\"foo\":9}}"); } @Test @@ -81,6 +81,8 @@ public void buildArrayTest() throws LazyException{ arr.put(2.9); arr.put(true); arr.put(false); + arr.put(new LazyArray("[2,2,4]")); + arr.put(new LazyObject("{\"foo\":42}")); // arr.put(LazyObject.NULL); assertEquals(arr.getString(0),"foo"); assertEquals(arr.getInt(1),42); @@ -89,6 +91,14 @@ public void buildArrayTest() throws LazyException{ assertEquals(arr.getDouble(4),2.9,0.0001); assertEquals(arr.getBoolean(5),true); assertEquals(arr.getBoolean(6),false); + assertEquals(arr.toString(),"[\"foo\",42,99,3.1415,2.9,true,false,[2,2,4],{\"foo\":42}]"); + } + + @Test + public void serializeArrayTest() throws LazyException{ + LazyArray arr=new LazyArray("[null,{\"foo\":3},[2,2,4]]"); + arr.put(42); + assertEquals(arr.toString(),"[null,{\"foo\":3},[2,2,4],42]"); } @Test @@ -101,6 +111,8 @@ public void insertArrayTest() throws LazyException{ arr.put(4,2.9); arr.put(5,true); arr.put(6,false); + arr.put(7,new LazyArray("[2,2,4]")); + arr.put(8,new LazyObject("{\"foo\":42}")); // arr.put(LazyObject.NULL); assertEquals(arr.getString(0),"foo"); assertEquals(arr.getInt(1),42); @@ -123,6 +135,12 @@ public void badInsertArrayTestB() throws LazyException{ arr.put(19,"foo"); } + @Test(expected=LazyException.class) + public void badObjectInsert() throws LazyException{ + LazyObject obj=new LazyObject("{}"); + obj.put("foo",new File("./")); + } + @Test public void removeKeyTest() throws LazyException{ @@ -142,6 +160,75 @@ public void removeFirstKeyTest() throws LazyException{ assertTrue(obj.has("baz")); } + @Test + public void cleanArrayToObject() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":[9,2,4]}"; + LazyObject obj=new LazyObject(str); + obj.put("test",obj.getJSONArray("baz")); + assertEquals(obj.getJSONArray("test").getInt(0),9); + } + + @Test + public void cleanArrayToArray() throws LazyException{ + String str="[\"bar\",[9,2,4]]"; + LazyArray arr=new LazyArray(str); + arr.put(arr.getJSONArray(1)); + assertEquals(arr.getJSONArray(2).getInt(0),9); + } + + @Test + public void cleanObjectToArray() throws LazyException{ + String str="[\"bar\",[9,2,4],{\"foo\":42}]"; + LazyArray arr=new LazyArray(str); + arr.put(arr.getJSONObject(2)); + assertEquals(arr.getJSONObject(3).getInt("foo"),42); + } + + @Test + public void cleanArrayToArrayIndex() throws LazyException{ + String str="[\"bar\",[9,2,4]]"; + LazyArray arr=new LazyArray(str); + arr.put(0,arr.getJSONArray(1)); + assertEquals(arr.getJSONArray(0).getInt(0),9); + } + + @Test + public void cleanObjectToArrayIndex() throws LazyException{ + String str="[\"bar\",[9,2,4],{\"foo\":42}]"; + LazyArray arr=new LazyArray(str); + arr.put(0,arr.getJSONObject(2)); + assertEquals(arr.getJSONObject(0).getInt("foo"),42); + } + + @Test + public void dirtyArrayToObject() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":[9,2,4]}"; + LazyObject obj=new LazyObject(str); + obj.getJSONArray("baz").put(42); + obj.put("test",obj.getJSONArray("baz")); + assertEquals(obj.getJSONArray("test").getInt(3),42); + } + + @Test + public void differentBufArrayToObject() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":[9,2,4]}"; + LazyObject obj=new LazyObject(str); + String str2="[3,3,6,42]"; + obj.put("test",new LazyArray(str2)); + assertEquals(obj.getJSONArray("test").getInt(3),42); + } + + @Test + public void differentBufDirtyArrayToObject() throws LazyException{ + String str="{\"foo\":\"bar\",\"baz\":[9,2,4]}"; + LazyObject obj=new LazyObject(str); + String str2="[3,3,6,42]"; + LazyArray arr=new LazyArray(str2); + arr.put(0); + obj.put("test",arr); + assertEquals(obj.getJSONArray("test").getInt(3),42); + } + @Test public void cleanObjectToObject() throws LazyException{ String str="{\"foo\":\"bar\",\"baz\":{\"foo\":9}}"; From dd556ad5cbbec28666b35fe9017abbe348b95688 Mon Sep 17 00:00:00 2001 From: Kasper Jeppe Jeppesen Date: Thu, 20 Apr 2017 16:30:56 -0700 Subject: [PATCH 15/15] bugfix string quoting --- .../me/doubledutch/lazyjson/LazyArray.java | 14 ++- .../me/doubledutch/lazyjson/LazyElement.java | 59 +++++++++++++ .../me/doubledutch/lazyjson/LazyNode.java | 87 +++++++++++++------ .../me/doubledutch/lazyjson/LazyObject.java | 10 ++- .../resources/lazyjson_version.properties | 6 +- .../me/doubledutch/lazyjson/ModifyTest.java | 10 +++ 6 files changed, 153 insertions(+), 33 deletions(-) diff --git a/src/main/java/me/doubledutch/lazyjson/LazyArray.java b/src/main/java/me/doubledutch/lazyjson/LazyArray.java index 9f64214..8277520 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyArray.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyArray.java @@ -207,7 +207,12 @@ private void insertChild(int index,LazyNode token) throws LazyException{ } public LazyArray put(String value) throws LazyException{ - LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_STRING,value); + LazyNode child=null; + if(shouldQuoteString(value)){ + child=appendAndSetDirtyString(LazyNode.VALUE_ESTRING,quoteString(value)); + }else{ + child=appendAndSetDirtyString(LazyNode.VALUE_STRING,value); + } appendChild(child); return this; } @@ -279,7 +284,12 @@ public LazyArray put(LazyObject value) throws LazyException{ } public LazyArray put(int index,String value) throws LazyException{ - LazyNode child=appendAndSetDirtyString(LazyNode.VALUE_STRING,value); + LazyNode child=null; + if(shouldQuoteString(value)){ + child=appendAndSetDirtyString(LazyNode.VALUE_ESTRING,quoteString(value)); + }else{ + child=appendAndSetDirtyString(LazyNode.VALUE_STRING,value); + } insertChild(index,child); return this; } diff --git a/src/main/java/me/doubledutch/lazyjson/LazyElement.java b/src/main/java/me/doubledutch/lazyjson/LazyElement.java index 39ea5f7..7a48ffc 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyElement.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyElement.java @@ -83,6 +83,65 @@ public static LazyElement parse(String str) throws LazyException{ throw new LazyException("The given string is not a JSON object or array"); } + protected static boolean shouldQuoteString(String str){ + boolean found=false; + int length=str.length(); + char[] cbuf=new char[length]; + str.getChars(0,length,cbuf,0); + for(int i=0;i= '\u0080' && c<'\u00a0') || (c>='\u2000' && c<'\u2100')){ + found=true; + } + } + return found; + } + + protected static String quoteString(String str){ + StringBuffer buf=new StringBuffer(); + int length=str.length(); + char[] cbuf=new char[length]; + str.getChars(0,length,cbuf,0); + + for(int i=0; i= '\u0080' && c<'\u00a0') || (c>='\u2000' && c<'\u2100')){ + String tmp="000"+Integer.toHexString(c); + buf.append("\\u"+tmp.substring(tmp.length()-4)); + }else{*/ + buf.append(c); + //} + } + } + return buf.toString(); + } + public static LazyElement readFromTemplate(Template t,ByteBuffer buf,DictionaryCache dict) throws LazyException{ String str=t.read(buf,dict); // System.out.println(str); diff --git a/src/main/java/me/doubledutch/lazyjson/LazyNode.java b/src/main/java/me/doubledutch/lazyjson/LazyNode.java index 2f01e03..a7e8499 100644 --- a/src/main/java/me/doubledutch/lazyjson/LazyNode.java +++ b/src/main/java/me/doubledutch/lazyjson/LazyNode.java @@ -346,38 +346,71 @@ protected String getStringValue(char[] source,StringBuilder dirtyBuf){ return new String(source,startIndex,endIndex-startIndex); }else{ StringBuilder buf=new StringBuilder(endIndex-startIndex); - for(int i=startIndex;i