altoslib: Add set_config_data to AltosState
[fw/altos] / altoslib / AltosJson.java
index 6ae7e7dc99de1278f8529bbc64d7d4553d5b8589..94ec2aee6029d245f7b87a888412760f43250787 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,39 +25,39 @@ import java.lang.*;
 import java.lang.reflect.*;
 
 class JsonUtil {
-       StringBuffer quote(StringBuffer result, String a) {
-               result.append("\"");
+       Writer quote(Writer writer, String a) throws IOException {
+               writer.append("\"");
                for (int i = 0; i < a.length(); i++) {
                        char c = a.charAt(i);
 
                        switch (c) {
                        case '"':
                        case '\\':
-                               result.append('\\').append(c);
+                               writer.append('\\').append(c);
                                break;
                        case '\n':
-                               result.append("\\n");
+                               writer.append("\\n");
                                break;
                        default:
-                               result.append(c);
+                               writer.append(c);
                                break;
                        }
                }
-               result.append("\"");
-               return result;
+               writer.append("\"");
+               return writer;
        }
 
-       StringBuffer append(StringBuffer result, AltosJson value, int indent, boolean pretty) {
+       Writer append(Writer result, AltosJson value, int indent, boolean pretty) throws IOException {
                value.append(result, indent, pretty);
                return result;
        }
 
-       StringBuffer append(StringBuffer result, String string) {
+       Writer append(Writer result, String string) throws IOException {
                result.append(string);
                return result;
        }
 
-       StringBuffer indent(StringBuffer result, int indent) {
+       Writer indent(Writer result, int indent) throws IOException {
                result.append("\n");
                for (int i = 0; i < indent; i++)
                        result.append("\t");
@@ -79,7 +80,7 @@ class JsonUtil {
 class JsonHash extends JsonUtil {
        Hashtable<String,AltosJson> hash;
 
-       void append_hash(StringBuffer result, int indent, boolean pretty) {
+       void append_hash(Writer result, int indent, boolean pretty) throws IOException {
                boolean         first = true;
 
                result.append("{");
@@ -124,7 +125,7 @@ class JsonHash extends JsonUtil {
 class JsonArray extends JsonUtil {
        ArrayList<AltosJson> array;
 
-       void append_array(StringBuffer result, int indent, boolean pretty) {
+       void append_array(Writer result, int indent, boolean pretty) throws IOException {
                boolean first = true;
 
                append(result, "[");
@@ -244,7 +245,7 @@ class JsonToken {
                this.sval = sval;
        }
 
-       JsonToken(int token, StringBuffer bval) {
+       JsonToken(int token, Writer bval) {
                this(token, bval.toString());
        }
 }
@@ -253,7 +254,7 @@ class JsonToken {
  * Lexer for json
  */
 class JsonLexer extends JsonUtil {
-       StringReader    f;
+       Reader          f;
        int             line;
        int             ungot = -2;
        StringBuffer    pending_token;
@@ -280,6 +281,9 @@ class JsonLexer extends JsonUtil {
        static keyword[] keywords = {
                new keyword("true", new JsonToken(JsonToken._boolean, true)),
                new keyword("false", new JsonToken(JsonToken._boolean, false)),
+               new keyword("NegInfinity", new JsonToken(JsonToken._double, Double.NEGATIVE_INFINITY)),
+               new keyword("Infinity", new JsonToken(JsonToken._double, Double.POSITIVE_INFINITY)),
+               new keyword("NaN", new JsonToken(JsonToken._double, Double.NaN))
        };
 
        static JsonToken keyword(String word) {
@@ -378,7 +382,7 @@ class JsonLexer extends JsonUtil {
                                                return new JsonToken(JsonToken._long, lval);
                                        }
                                case '"':
-                                       StringBuffer bval = new StringBuffer();
+                                       Writer bval = new StringWriter();
                                        for (;;) {
                                                c = ch();
                                                if (c == '"')
@@ -396,7 +400,7 @@ class JsonLexer extends JsonUtil {
                                                                break;
                                                        }
                                                }
-                                               bval.appendCodePoint(c);
+                                               bval.write(c);
                                        }
                                        return new JsonToken(JsonToken._string, bval);
                                default:
@@ -438,6 +442,12 @@ class JsonLexer extends JsonUtil {
                line = 1;
                token = null;
        }
+
+       JsonLexer(Reader f) {
+               this.f = f;
+               line = 1;
+               token = null;
+       }
 }
 
 /*
@@ -552,6 +562,10 @@ class JsonParse {
        JsonParse(String s) {
                lexer = new JsonLexer(s);
        }
+
+       JsonParse(Reader f) {
+               lexer = new JsonLexer(f);
+       }
 }
 
 public class AltosJson extends JsonUtil {
@@ -574,7 +588,7 @@ public class AltosJson extends JsonUtil {
 
        /* Generate string representation of the value
         */
-       StringBuffer append(StringBuffer result, int indent, boolean pretty) {
+       Writer append(Writer result, int indent, boolean pretty) throws IOException {
                switch (type) {
                case type_hash:
                        hash.append_hash(result, indent, pretty);
@@ -583,10 +597,19 @@ public class AltosJson extends JsonUtil {
                        array.append_array(result, indent, pretty);
                        break;
                case type_double:
-                       String dval = nf_json.format(d_number);
-                       if (dval.equals("-0"))
-                               dval = "0";
-                       result.append(dval);
+                       if (Double.isInfinite(d_number)) {
+                               if (d_number < 0)
+                                       result.append("NegInfinity");
+                               else
+                                       result.append("Infinity");
+                       } else if (Double.isNaN(d_number)) {
+                               result.append("NaN");
+                       } else {
+                               String dval = nf_json.format(d_number);
+                               if (dval.equals("-0"))
+                                       dval = "0";
+                               result.append(dval);
+                       }
                        break;
                case type_long:
                        result.append(new Long(l_number).toString());
@@ -602,9 +625,13 @@ public class AltosJson extends JsonUtil {
        }
 
        private String toString(int indent, boolean pretty) {
-               StringBuffer result = new StringBuffer();
-               append(result, indent, pretty);
-               return result.toString();
+               try {
+                       Writer result = new StringWriter();
+                       append(result, indent, pretty);
+                       return result.toString();
+               } catch (Exception e) {
+                       return null;
+               }
        }
 
        public String toString() {
@@ -615,6 +642,14 @@ public class AltosJson extends JsonUtil {
                return toString(0, true);
        }
 
+       public void write(Writer w, int indent, boolean pretty) throws IOException {
+               append(w, indent, pretty);
+       }
+
+       public void write(Writer w) throws IOException {
+               write(w, 0, true);
+       }
+
        /* Parse string representation to a value
         */
 
@@ -628,6 +663,16 @@ public class AltosJson extends JsonUtil {
                }
        }
 
+       public static AltosJson fromReader(Reader f) {
+               JsonParse       parse = new JsonParse(f);
+               try {
+                       return parse.parse();
+               } catch (IllegalArgumentException ie) {
+                       System.out.printf("json:\n%s\n", ie.getMessage());
+                       return null;
+               }
+       }
+
        /* Accessor functions
         */
        private boolean assert_type(boolean setting, int type, int other_type, String error) {
@@ -1000,7 +1045,32 @@ public class AltosJson extends JsonUtil {
                        assert_array(false);
 
                        Class element_class = c.getComponentType();
-                       if (element_class == Double.TYPE) {
+                       if (element_class == Boolean.TYPE) {
+                               boolean[] array = (boolean[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Boolean) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Byte.TYPE) {
+                               byte[] array = (byte[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Byte) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Character.TYPE) {
+                               char[] array = (char[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Character) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Integer.TYPE) {
+                               int[] array = (int[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Integer) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Long.TYPE) {
+                               long[] array = (long[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Long) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Double.TYPE) {
                                double[] array = (double[]) Array.newInstance(element_class, size());
                                for (int i = 0; i < array.length; i++)
                                        array[i] = (Double) get(i).make(element_class);
@@ -1026,11 +1096,10 @@ public class AltosJson extends JsonUtil {
                                } else {
                                        object = c.newInstance();
                                }
-                               for (; c != null; c = c.getSuperclass()) {
+                               for (; c != Object.class; c = c.getSuperclass()) {
                                        for (Field field : c.getDeclaredFields()) {
                                                String  fieldName = field.getName();
                                                Class   fieldClass = field.getType();
-                                               String  className = fieldClass.getName();
 
                                                if (Modifier.isStatic(field.getModifiers()))
                                                        continue;
@@ -1044,17 +1113,27 @@ public class AltosJson extends JsonUtil {
                                                                field.set(object, val);
                                                        }
                                                } catch (IllegalAccessException ie) {
+                                                       System.out.printf("%s:%s %s\n",
+                                                                         c.getName(), fieldName, ie.toString());
                                                }
                                        }
                                }
                                ret = object;
                        } catch (InvocationTargetException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
                                ret = null;
                        } catch (NoSuchMethodException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
                                ret = null;
                        } catch (InstantiationException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
                                ret = null;
                        } catch (IllegalAccessException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
                                ret = null;
                        }
                }
@@ -1162,11 +1241,13 @@ public class AltosJson extends JsonUtil {
                        }
                } else {
                        assert_hash(true);
-                       for (Class c = object.getClass(); c != null; c = c.getSuperclass()) {
+                       for (Class c = object.getClass(); c != Object.class; c = c.getSuperclass()) {
                                for (Field field : c.getDeclaredFields()) {
                                        String  fieldName = field.getName();
-                                       Class   fieldClass = field.getType();
-                                       String  className = fieldClass.getName();
+
+                                       /* XXX hack to allow fields to be not converted */
+                                       if (fieldName.startsWith("__"))
+                                               continue;
 
                                        /* Skip static fields */
                                        if (Modifier.isStatic(field.getModifiers()))
@@ -1189,6 +1270,8 @@ public class AltosJson extends JsonUtil {
                                                        put(fieldName, json);
                                                }
                                        } catch (IllegalAccessException ie) {
+                                               System.out.printf("%s:%s %s\n",
+                                                                 c.getName(), fieldName, ie.toString());
                                        }
                                }
                        }