Skip to content
Permalink
Browse files

Add method to string class to convert JSON into Genyris structures

  • Loading branch information...
birchb1024 committed Apr 19, 2019
1 parent 3fcdb07 commit e3a4768a75922ed9f3b079936a59124ab9cb6483
@@ -43,6 +43,7 @@
<include name="commons-io-2.4.jar" />
<include name="httpcore-4.4.3.jar" />
<include name="httpclient-4.5.1.jar" />
<include name="org.json.jar" />
</fileset>

<!-- Properties files from the classpath -->
@@ -0,0 +1,8 @@
#
# Example
#
@prefix web "http://www.genyris.org/lang/web#"

var response (left (web:get 'https://api.ipify.org/?format=json'))
var decode (response(.readAll))
print (decode(.fromJSON))!ip
BIN +63.1 KB needed/org.json.jar
Binary file not shown.
@@ -65,6 +65,8 @@
public static final String JOIN = "join";
public static final String SPLIT = "split";
public static final String TOINTS = "toInts";
public static final String FROMJSON = "fromJSON";
public static final String TOJSON = "toJSON";
public static final String FROMINTS = "fromInts";
public static final String TOLOWERCASE = "toLowerCase";
public static final String CONCAT = "+";
@@ -41,6 +41,7 @@ public static void bindFunctionsAndMethods(Interpreter interpreter) throws Unbou
interpreter.bindMethodInstance(Constants.STRING, new FromIntsMethod(interpreter));
interpreter.bindMethodInstance(Constants.STRING, new SliceMethod(interpreter));
interpreter.bindMethodInstance(Constants.STRING, new JoinMethod(interpreter));
interpreter.bindMethodInstance(Constants.STRING, new FromJSONMethod(interpreter));
}

}
@@ -0,0 +1,110 @@
// Copyright 2008 Peter William Birch <birchb@genyis.org>
//
// This software may be used and distributed according to the terms
// of the Genyris License, in the file "LICENSE", incorporated herein by reference.
//
package org.genyris.string;

import org.genyris.core.*;
import org.genyris.exception.GenyrisException;
import org.genyris.interp.Closure;
import org.genyris.interp.Environment;
import org.genyris.interp.Interpreter;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import org.json.JSONTokener;

import java.util.Iterator;

public class FromJSONMethod extends AbstractStringMethod {

public static String getStaticName() {return Constants.FROMJSON;};

public FromJSONMethod(Interpreter interp) {
super(interp, getStaticName());
}

public Exp bindAndExecute(Closure proc, Exp[] arguments, Environment env)
throws GenyrisException {

Class[] types = { };
checkArgumentTypes(types, arguments);
String theString = getSelfString(env).toString();
try {
JSONTokener lexer = new JSONTokener(theString);
char ch = lexer.nextClean();
if ( ch == '{') {
JSONObject jo = new JSONObject(theString);
return convertJSON(jo, env);
}
else if (ch == '[') {
JSONArray jo = new JSONArray(theString);
return convertJSON(jo, env);
}
else {
throw new GenyrisException("Expexting non-atomic JSON - got " + theString);
}
}
catch (JSONException e) {
throw new GenyrisException(e.getMessage());
}
}


public Exp convertJSON(Object obj, Environment env) throws GenyrisException
{
try {
if( obj instanceof Integer ) {
return new Bignum((Integer)obj);
}
else if( obj instanceof Long ) {
return new Bignum((Long)obj);
}
else if( obj instanceof Float ) {
return new Bignum((Float)obj);
}
else if( obj instanceof Double ) {
return new Bignum((Double)obj);
}
else if( obj instanceof String ) {
return new StrinG((String)obj);
}
else if( obj instanceof Boolean ) {
return (Boolean)obj ? TRUE : NIL;
}
else if (obj == JSONObject.NULL) {
return NIL;
}
else if( obj instanceof JSONObject ) {
JSONObject jo = (JSONObject)obj;
if( jo.isEmpty() ) {
return NIL;
}
Dictionary dict = new Dictionary(env);
Iterator keys = jo.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
DynamicSymbol key_sym = new DynamicSymbol(env.getSymbolTable().internString(key));
Object value = jo.get(key);
dict.defineDynamicVariable(key_sym, convertJSON(value, env));
}
return dict;
}
else if( obj instanceof JSONArray) {
Exp head = NIL;
JSONArray ja = (JSONArray)obj;
for( int index = ja.length()-1; index >= 0 ; index--) {
head = Pair.cons(convertJSON(ja.get(index), env), head);
}
return head;
}
else {
throw new GenyrisException("Unknown JSON type" + obj.toString());
}
}
catch (JSONException e) {
throw new GenyrisException(e.getMessage());
}
}
}
@@ -5,6 +5,8 @@

import org.genyris.exception.GenyrisException;
import org.genyris.test.interp.TestUtilities;
import org.json.JSONObject;


public class StringTests extends TestCase {

@@ -74,6 +76,31 @@ public void testStringToInts() throws GenyrisException {
checkEval("('\r\n'(.toInts 'ASCII'))", "(13 10)");

}

public void testStringFromJSONbad() throws GenyrisException {
checkEvalBad("(''(.fromJSON))");
checkEvalBad("('{\"ZZ\"'(.fromJSON))");
checkEvalBad("('[]'(.fromJSON))");
}
public void testStringFromJSON() throws GenyrisException {
checkEval("('{}'(.fromJSON))", "nil");

checkEval("('{\"alpha\": 1, \"bravo\": NULL, \"charlie\" : \"C\" }'(.fromJSON))", "(dict (.alpha = 1) (.bravo = nil) (.charlie = 'C'))");
checkEval("('{\"alpha\": { \"bravo\": NULL, \"charlie\" : \"C\" }}'(.fromJSON))", "(dict (.alpha = (dict (.bravo = nil) (.charlie = 'C'))))");
checkEval("('{\"yes\": True, \"no\" : False}'(.fromJSON))", "(dict (.no = nil) (.yes = true))");
checkEval("('{\"int\": 12, \"float\" : 1.233453e37 }'(.fromJSON)!int)", "12");
checkEval("(scale ('{\"int\": 12, \"float\" : 1.233453e3 }'(.fromJSON)!float) 4)", "1233.453");

checkEval("('[]'(.fromJSON))", "nil");
checkEval("('[ 1, True, False, null, \"A\"]'(.fromJSON))", "(1 true nil nil 'A')");
checkEval("('[ 42, { \"A\" : 1} ]'(.fromJSON))", "(42 (dict (.A = 1)))");

checkEval("('{\"array\": [1,2,3],}'(.fromJSON))", "(dict (.array = (1 2 3)))");
checkEval("('{\"array\": [],}'(.fromJSON))", "(dict (.array = nil))");
checkEval("('{\"array\": [1,2,3],}'(.fromJSON))", "(dict (.array = (1 2 3)))");

}

public void testStringToIntsInternational() throws GenyrisException {
checkEval("('0123456789'(.toInts 'GBK'))", "(48 49 50 51 52 53 54 55 56 57)");
checkEval("('1 2 3 4 5'(.toInts 'UTF-16LE'))", "(49 0 32 0 50 0 32 0 51 0 32 0 52 0 32 0 53 0)");

0 comments on commit e3a4768

Please sign in to comment.
You can’t perform that action at this time.