Revision: 20761
          http://sourceforge.net/p/jmol/code/20761
Author:   hansonr
Date:     2015-09-09 03:46:44 +0000 (Wed, 09 Sep 2015)
Log Message:
-----------
Jmol.___JmolVersion="14.3.16_2015.09.08"

code: Efficient JSON parser javajs.util.JSONParser

Modified Paths:
--------------
    trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java
    trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties
    trunk/Jmol/src/org/jmol/viewer/Viewer.java

Added Paths:
-----------
    trunk/Jmol/src/javajs/util/JSJSONParser.java
    trunk/Jmol/src/javajs/util/JSONException.java

Added: trunk/Jmol/src/javajs/util/JSJSONParser.java
===================================================================
--- trunk/Jmol/src/javajs/util/JSJSONParser.java                                
(rev 0)
+++ trunk/Jmol/src/javajs/util/JSJSONParser.java        2015-09-09 03:46:44 UTC 
(rev 20761)
@@ -0,0 +1,316 @@
+package javajs.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+/**
+ * a very simple JSON parser for JSON objects that are compatible with 
JavaScript
+ * A gross simplification of https://github.com/douglascrockford/JSON-java
+ * 
+ * A SUBSET of JSON with similarly to window.JSON.parse():
+ * 
+ *  -- requires quoted strings for keys and values
+ *  
+ *  -- does not allow /xxx/ objects
+ *  
+ *  
+ */
+public class JSJSONParser {
+
+  private String str;
+  private int index;
+  private int len;
+
+  public JSJSONParser () {
+    // for reflection
+  }
+  
+  /**
+   * requires { "key":"value", "key":"value",....}
+   * 
+   * @param str
+   * 
+   * @return Map or null
+   */
+  @SuppressWarnings("unchecked")
+  public Map<String, Object> parseMap(String str) {
+    index = 0;
+    this.str = str;
+    len = str.length();
+    if (getChar() != '{')
+      return null;
+    returnChar();
+    return (Map<String, Object>) getValue(false);
+  }
+  
+  /**
+   * Could return Integer, Double, Boolean, String, Map<String, Object>, 
Lst<Object>, or null
+   * 
+   * @param str
+   * @return a object equivalent to the JSON string str
+   * 
+   */
+  public Object parse(String str) {
+    index = 0;
+    this.str = str;
+    len = str.length();
+    return getValue(false);
+  }
+
+  private char next() {
+    return (index < len ? str.charAt(index++) : '\0');
+  }
+
+  private void returnChar() {
+    index--;
+  }
+
+  /**
+   * Get the next char in the string, skipping whitespace.
+   * 
+   * @throws JSONException
+   * @return one character, or 0 if there are no more characters.
+   */
+  private char getChar() throws JSONException {
+    for (;;) {
+      char c = next();
+      if (c == 0 || c > ' ') {
+        return c;
+      }
+    }
+  }
+
+  /**
+   * only allowing the following values:
+   * 
+   * {...} object
+   * 
+   * [...] array
+   * 
+   * Integer
+   * 
+   * Double
+   * 
+   * "quoted string"
+   * 
+   * 
+   * @param isKey if we should allow {...} and [...]
+   * @return a subclass of Object
+   * @throws JSONException
+   */
+  private Object getValue(boolean isKey) throws JSONException {
+    int i = index;
+    char c = getChar();
+    switch (c) {
+    case '\0':
+      return null;
+    case '"':
+    case '\'':
+      return getString(c);
+    case '{':
+      if (!isKey)
+        return getObject();
+      c = 0;
+      break;
+    case '[':
+      if (!isKey)
+        return getArray();
+      c = 0;
+      break;
+    default:
+      // standard syntax is assumed; not checking all possible invalid keys
+      // for example, "-" is not allowed in JavaScript, which is what this is 
for
+      returnChar();
+      while (c >= ' ' && "[,]{:}'\"".indexOf(c) < 0)
+        c = next();
+      returnChar();
+      if (isKey && c != ':')
+        c = 0;
+      break;
+    }
+    if (isKey && c == 0)
+      throw new JSONException("invalid key");
+
+    String string = str.substring(i, index);
+
+    // check for the only valid simple words: true, false, null (lower case)
+    // and in this case, only for 
+
+    if (!isKey) {
+      if (string.equals("true")) {
+        return Boolean.TRUE;
+      }
+      if (string.equals("false")) {
+        return Boolean.FALSE;
+      }
+      if (string.equals("null")) {
+        return null;
+      }
+    }
+    //  only numbers from here on:
+
+    c = string.charAt(0);
+    if (c >= '0' && c <= '9' || c == '-')
+      try {
+        if (string.indexOf('.') < 0 && string.indexOf('e') < 0
+            && string.indexOf('E') < 0)
+          return new Integer(string);
+        // not allowing infinity or NaN
+        Double d = Double.valueOf(string);
+        if (!d.isInfinite() && !d.isNaN())
+          return d;
+      } catch (Exception e) {
+      }
+    // not a valid number
+    throw new JSONException("invalid value");
+  }
+
+  private String getString(char quote) throws JSONException {
+    char c;
+    SB sb = null;
+    int i0 = index;
+    for (;;) {
+      int i1 = index;
+      switch (c = next()) {
+      case '\0':
+      case '\n':
+      case '\r':
+        throw syntaxError("Unterminated string");
+      case '\\':
+        switch (c = next()) {
+        case '"':
+        case '\'':
+        case '\\':
+        case '/':
+          break;
+        case 'b':
+          c = '\b';
+          break;
+        case 't':
+          c = '\t';
+          break;
+        case 'n':
+          c = '\n';
+          break;
+        case 'f':
+          c = '\f';
+          break;
+        case 'r':
+          c = '\r';
+          break;
+        case 'u':
+          int i = index;
+          index += 4;
+          try {
+            c = (char) Integer.parseInt(str.substring(i, index), 16);
+          } catch (Exception e) {
+            throw syntaxError("Substring bounds error");
+          }
+          break;
+        default:
+          throw syntaxError("Illegal escape.");
+        }
+        break;
+      default:
+        if (c == quote)
+          return (sb == null ? str.substring(i0, i1) : sb.toString());
+        break;
+      }
+      if (index > i1 + 1) {
+        if (sb == null) {
+          sb = new SB();
+          sb.append(str.substring(i0, i1));
+        }
+      }
+      if (sb != null)
+        sb.appendC(c);
+    }
+  }
+
+  private Object getObject() {
+    Map<String, Object> map = new HashMap<String, Object>();
+    String key = null;
+    switch (getChar()) {
+    case '}':
+      return map;
+    case 0:
+      throw new JSONException("invalid object");
+    }
+    returnChar();
+    boolean isKey = false;
+    for (;;) {
+      if ((isKey = !isKey) == true)
+        key = getValue(true).toString();
+      else
+        map.put(key, getValue(false));
+      switch (getChar()) {
+      case '}':
+        return map;
+      case ':':
+        if (isKey)
+          continue;
+        isKey = true;
+        //$FALL-THROUGH$
+      case ',':
+        if (!isKey)
+          continue;
+        //$FALL-THROUGH$
+      default:
+        throw syntaxError("Expected ',' or ':' or '}'");
+      }
+    }
+  }
+
+  private Object getArray() {
+    Lst<Object> l = new Lst<Object>();
+    switch (getChar()) {
+    case ']':
+      return l;
+    case 0:
+      throw new JSONException("invalid array");
+    }
+    returnChar();
+    boolean isNull = false;
+    for (;;) {
+      if (isNull) {
+        l.addLast(null);
+        isNull = false;
+      } else {
+        l.addLast(getValue(false));
+      }
+      switch (getChar()) {
+      case ',':
+        switch (getChar()) {
+        case ']':
+          // terminal ,
+          return l;
+        case ',':
+          // empty value
+          isNull = true;
+          //$FALL-THROUGH$
+        default:
+          returnChar();
+        }
+        continue;
+      case ']':
+        return l;
+      default:
+        throw syntaxError("Expected ',' or ']'");
+      }
+    }
+  }
+
+  /**
+   * Make a JSONException to signal a syntax error.
+   * 
+   * @param message
+   *        The error message.
+   * @return A JSONException object, suitable for throwing
+   */
+  public JSONException syntaxError(String message) {
+    return new JSONException(message + " for " + str.substring(0, 
Math.min(index,  len)));
+  }
+
+}


Property changes on: trunk/Jmol/src/javajs/util/JSJSONParser.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/Jmol/src/javajs/util/JSONException.java
===================================================================
--- trunk/Jmol/src/javajs/util/JSONException.java                               
(rev 0)
+++ trunk/Jmol/src/javajs/util/JSONException.java       2015-09-09 03:46:44 UTC 
(rev 20761)
@@ -0,0 +1,8 @@
+package javajs.util;
+
+public class JSONException extends RuntimeException {
+    public JSONException(String message) {
+        super(message);
+    }
+
+}


Property changes on: trunk/Jmol/src/javajs/util/JSONException.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java     
2015-09-08 06:25:42 UTC (rev 20760)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java     
2015-09-09 03:46:44 UTC (rev 20761)
@@ -31,10 +31,13 @@
 import org.jmol.api.JmolFilesReaderInterface;
 
 import javajs.api.GenericBinaryDocument;
+import javajs.api.Interface;
 import javajs.util.Lst;
 
 import org.jmol.script.SV;
 import org.jmol.util.Logger;
+
+import javajs.util.JSJSONParser;
 import javajs.util.P3;
 import javajs.util.PT;
 import javajs.util.Rdr;
@@ -46,7 +49,6 @@
 
 import java.util.Map;
 
-
 public class SmarterJmolAdapter extends JmolAdapter {
 
   /**************************************************************
@@ -207,7 +209,7 @@
           // hack to determine type:
           String type = (f.contains("version\":\"DSSR") ? "dssr" : f
               .contains("/outliers/") ? "validation" : "domains");
-          SV x = vwr.evaluateExpressionAsVariable(f);
+          SV x = vwr.parseJSON(f);
           if (x != null && x.getMap() != null)
             htParams.put(type, x);
           continue;

Modified: trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java   2015-09-08 06:25:42 UTC 
(rev 20760)
+++ trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java   2015-09-09 03:46:44 UTC 
(rev 20761)
@@ -1324,7 +1324,7 @@
     Object annotv = cache.get(key);
     if (annotv == null && ann != null) {
       annotv = (ann instanceof SV || ann instanceof Hashtable ? ann
-              : vwr.evaluateExpressionAsVariable(ann));
+              : vwr.parseJSON((String) ann));
       cache.put(key, annotv);
     }
     return (annotv instanceof SV || annotv instanceof Hashtable ? annotv : 
null);

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-09-08 06:25:42 UTC 
(rev 20760)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-09-09 03:46:44 UTC 
(rev 20761)
@@ -58,8 +58,12 @@
 
 TODO: image off  stops JSmol
 
-Jmol.___JmolVersion="14.3.16_2015.09.06"
+Jmol.___JmolVersion="14.3.16_2015.09.08"
 
+code: Efficient JSON parser javajs.util.JSONParser
+
+JmolVersion="14.3.16_2015.09.06"
+
 new feature: 3DNA DSSR JSON mode 
  -- 
http://x3dna.bio.columbia.edu/dssr/report.php?id=1ehz&opts=--more%20--json=ebi-no-str-id
  -- uses unit ids

Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Viewer.java  2015-09-08 06:25:42 UTC (rev 
20760)
+++ trunk/Jmol/src/org/jmol/viewer/Viewer.java  2015-09-09 03:46:44 UTC (rev 
20761)
@@ -45,6 +45,7 @@
 import javajs.awt.Font;
 import javajs.util.CU;
 import javajs.util.DF;
+import javajs.util.JSJSONParser;
 import javajs.util.Lst;
 import javajs.util.M3;
 import javajs.util.M4;
@@ -9345,7 +9346,7 @@
       jmolpopup.jpiUpdateComputedMenus();
   }
 
-  JmolChimeMessenger jcm;
+  private JmolChimeMessenger jcm;
 
   public JmolChimeMessenger getChimeMessenger() {
     return (jcm == null ? jcm = ((JmolChimeMessenger) Interface.getInterface(
@@ -9357,4 +9358,11 @@
         false));
   }
 
+  private JSJSONParser jsonParser;
+  
+  public SV parseJSON(String ann) {
+    if (jsonParser == null)
+      jsonParser = ((JSJSONParser) 
Interface.getInterface("javajs.util.JSJSONParser", this, "script"));
+    return SV.getVariable(jsonParser.parseMap(ann));
+  }
 }

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Monitor Your Dynamic Infrastructure at Any Scale With Datadog!
Get real-time metrics from all of your servers, apps and tools
in one place.
SourceForge users - Click here to start your Free Trial of Datadog now!
http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to