Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
   *
   * This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  package org.mozilla.javascript;
  
 
 import java.util.List;
This class implements the JSON native object. See ECMA 15.12.

Author(s):
Matthew Crumley, Raphael Speyer
 
 public final class NativeJSON extends IdScriptableObject
 {
     static final long serialVersionUID = -4567599697595654984L;
 
     private static final Object JSON_TAG = "JSON";
 
     private static final int MAX_STRINGIFY_GAP_LENGTH = 10;
 
     static void init(Scriptable scopeboolean sealed)
     {
         NativeJSON obj = new NativeJSON();
         obj.activatePrototypeMap();
         obj.setPrototype(getObjectPrototype(scope));
         obj.setParentScope(scope);
         if (sealed) { obj.sealObject(); }
         ScriptableObject.defineProperty(scope"JSON"obj,
                                         .);
     }
 
     private NativeJSON()
     {
     }
 
     @Override
     public String getClassName() { return "JSON"; }
 
     @Override
     protected void initPrototypeId(int id)
     {
         if (id <= ) {
             String name;
             int arity;
             switch (id) {
               case :  arity = 0; name = "toSource";  break;
               case :     arity = 2; name = "parse";     break;
               case arity = 3; name = "stringify"break;
               defaultthrow new IllegalStateException(String.valueOf(id));
             }
             initPrototypeMethod(idnamearity);
         } else {
             throw new IllegalStateException(String.valueOf(id));
         }
     }
 
     @Override
     public Object execIdCall(IdFunctionObject fContext cxScriptable scope,
                              Scriptable thisObjObject[] args)
     {
         if (!f.hasTag()) {
             return super.execIdCall(fcxscopethisObjargs);
         }
         int methodId = f.methodId();
         switch (methodId) {
             case :
                 return "JSON";
 
             case : {
                 String jtext = ScriptRuntime.toString(args, 0);
                 Object reviver = null;
                 if (args.length > 1) {
                     reviver = args[1];
                 }
                 if (reviver instanceof Callable) {
                   return parse(cxscopejtext, (Callablereviver);
                 } else {
                   return parse(cxscopejtext);
                 }
             }
 
             case : {
                 Object value = nullreplacer = nullspace = null;
                 switch (args.length) {
                     default:
                     case 3: space = args[2];
                     case 2: replacer = args[1];
                     case 1: value = args[0];
                     case 0:
                }
                return stringify(cxscopevaluereplacerspace);
            }
            defaultthrow new IllegalStateException(String.valueOf(methodId));
        }
    }
    private static Object parse(Context cxScriptable scopeString jtext) {
      try {
        return new JsonParser(cxscope).parseValue(jtext);
      } catch (JsonParser.ParseException ex) {
        throw ScriptRuntime.constructError("SyntaxError"ex.getMessage());
      }
    }
    public static Object parse(Context cxScriptable scopeString jtext,
                               Callable reviver)
    {
      Object unfiltered = parse(cxscopejtext);
      Scriptable root = cx.newObject(scope);
      root.put(""rootunfiltered);
      return walk(cxscopereviverroot"");
    }
    private static Object walk(Context cxScriptable scopeCallable reviver,
                               Scriptable holderObject name)
    {
        final Object property;
        if (name instanceof Number) {
            property = holder.get( ((Numbername).intValue(), holder);
        } else {
            property = holder.get( ((Stringname), holder);
        }
        if (property instanceof Scriptable) {
            Scriptable val = ((Scriptableproperty);
            if (val instanceof NativeArray) {
                long len = ((NativeArrayval).getLength();
                for (long i = 0; i < leni++) {
                    // indices greater than MAX_INT are represented as strings
                    if (i > .) {
                        String id = Long.toString(i);
                        Object newElement = walk(cxscoperevivervalid);
                        if (newElement == .) {
                            val.delete(id);
                        } else {
                            val.put(idvalnewElement);
                        }
                    } else {
                        int idx = (inti;
                        Object newElement = walk(cxscoperevivervalidx);
                        if (newElement == .) {
                            val.delete(idx);
                        } else {
                            val.put(idxvalnewElement);
                        }
                    }
                }
            } else {
                Object[] keys = val.getIds();
                for (Object p : keys) {
                    Object newElement = walk(cxscoperevivervalp);
                    if (newElement == .) {
                        if (p instanceof Number)
                          val.delete(((Numberp).intValue());
                        else
                          val.delete((Stringp);
                    } else {
                        if (p instanceof Number)
                          val.put(((Numberp).intValue(), valnewElement);
                        else
                          val.put((StringpvalnewElement);
                    }
                }
            }
        }
        return reviver.call(cxscopeholdernew Object[] { nameproperty });
    }
    private static String repeat(char cint count) {
      char chars[] = new char[count];
      Arrays.fill(charsc);
      return new String(chars);
    }
    private static class StringifyState {
        StringifyState(Context cxScriptable scopeString indentString gap,
                       Callable replacerList<ObjectpropertyList,
                       Object space)
        {
            this. = cx;
            this. = scope;
            this. = indent;
            this. = gap;
            this. = replacer;
            this. = propertyList;
            this. = space;
        }
        Stack<Scriptablestack = new Stack<Scriptable>();
        String indent;
        String gap;
        Callable replacer;
        List<ObjectpropertyList;
        Object space;
        Context cx;
        Scriptable scope;
    }
    public static Object stringify(Context cxScriptable scopeObject value,
                                   Object replacerObject space)
    {
        String indent = "";
        String gap = "";
        List<ObjectpropertyList = null;
        Callable replacerFunction = null;
        if (replacer instanceof Callable) {
          replacerFunction = (Callablereplacer;
        } else if (replacer instanceof NativeArray) {
          propertyList = new LinkedList<Object>();
          NativeArray replacerArray = (NativeArrayreplacer;
          for (int i : replacerArray.getIndexIds()) {
            Object v = replacerArray.get(ireplacerArray);
            if (v instanceof String || v instanceof Number) {
              propertyList.add(v);
            } else if (v instanceof NativeString || v instanceof NativeNumber) {
              propertyList.add(ScriptRuntime.toString(v));
            }
          }
        }
        if (space instanceof NativeNumber) {
            space = ScriptRuntime.toNumber(space);
        } else if (space instanceof NativeString) {
            space = ScriptRuntime.toString(space);
        }
        if (space instanceof Number) {
            int gapLength = (int) ScriptRuntime.toInteger(space);
            gapLength = Math.min(gapLength);
            gap = (gapLength > 0) ? repeat(' 'gapLength) : "";
            space = gapLength;
        } else if (space instanceof String) {
            gap = (Stringspace;
            if (gap.length() > ) {
              gap = gap.substring(0, );
            }
        }
        StringifyState state = new StringifyState(cxscope,
            indent,
            gap,
            replacerFunction,
            propertyList,
            space);
        ScriptableObject wrapper = new NativeObject();
        wrapper.setParentScope(scope);
        wrapper.setPrototype(ScriptableObject.getObjectPrototype(scope));
        wrapper.defineProperty(""value, 0);
        return str(""wrapperstate);
    }
    private static Object str(Object keyScriptable holder,
                              StringifyState state)
    {
        Object value = null;
        if (key instanceof String) {
            value = getProperty(holder, (Stringkey);
        } else {
            value = getProperty(holder, ((Numberkey).intValue());
        }
        if (value instanceof Scriptable) {
            Object toJSON = getProperty((Scriptablevalue"toJSON");
            if (toJSON instanceof Callable) {
                value = callMethod(state.cx, (Scriptablevalue"toJSON",
                                   new Object[] { key });
            }
        }
        if (state.replacer != null) {
            value = state.replacer.call(state.cxstate.scopeholder,
                                        new Object[] { keyvalue });
        }
        if (value instanceof NativeNumber) {
            value = ScriptRuntime.toNumber(value);
        } else if (value instanceof NativeString) {
            value = ScriptRuntime.toString(value);
        } else if (value instanceof NativeBoolean) {
            value = ((NativeBooleanvalue).getDefaultValue(.);
        }
        if (value == nullreturn "null";
        if (value.equals(.)) return "true";
        if (value.equals(.)) return "false";
        if (value instanceof CharSequence) {
            return quote(value.toString());
        }
        if (value instanceof Number) {
            double d = ((Numbervalue).doubleValue();
            if (d == d && d != . &&
                d != .)
            {
                return ScriptRuntime.toString(value);
            } else {
                return "null";
            }
        }
        if (value instanceof Scriptable && !(value instanceof Callable)) {
            if (value instanceof NativeArray) {
                return ja((NativeArrayvaluestate);
            }
            return jo((Scriptablevaluestate);
        }
        return .;
    }
    private static String join(Collection<ObjectobjsString delimiter) {
        if (objs == null || objs.isEmpty()) {
            return "";
        }
        Iterator<Objectiter = objs.iterator();
        if (!iter.hasNext()) return "";
        StringBuilder builder = new StringBuilder(iter.next().toString());
        while (iter.hasNext()) {
            builder.append(delimiter).append(iter.next().toString());
        }
        return builder.toString();
    }
    private static String jo(Scriptable valueStringifyState state) {
        if (state.stack.search(value) != -1) {
            throw ScriptRuntime.typeError0("msg.cyclic.value");
        }
        state.stack.push(value);
        String stepback = state.indent;
        state.indent = state.indent + state.gap;
        Object[] k = null;
        if (state.propertyList != null) {
            k = state.propertyList.toArray();
        } else {
            k = value.getIds();
        }
        List<Objectpartial = new LinkedList<Object>();
        for (Object p : k) {
            Object strP = str(pvaluestate);
            if (strP != .) {
                String member = quote(p.toString()) + ":";
                if (state.gap.length() > 0) {
                    member = member + " ";
                }
                member = member + strP;
                partial.add(member);
            }
        }
        final String finalValue;
        if (partial.isEmpty()) {
            finalValue = "{}";
        } else {
            if (state.gap.length() == 0) {
                finalValue = '{' + join(partial",") + '}';
            } else {
                String separator = ",\n" + state.indent;
                String properties = join(partialseparator);
                finalValue = "{\n" + state.indent + properties + '\n' +
                    stepback + '}';
            }
        }
        state.stack.pop();
        state.indent = stepback;
        return finalValue;
    }
    private static String ja(NativeArray valueStringifyState state) {
        if (state.stack.search(value) != -1) {
            throw ScriptRuntime.typeError0("msg.cyclic.value");
        }
        state.stack.push(value);
        String stepback = state.indent;
        state.indent = state.indent + state.gap;
        List<Objectpartial = new LinkedList<Object>();
        long len = value.getLength();
        for (long index = 0; index < lenindex++) {
            Object strP;
            if (index > .) {
                strP = str(Long.toString(index), valuestate);
            } else {
                strP = str((intindexvaluestate);
            }
            if (strP == .) {
                partial.add("null");
            } else {
                partial.add(strP);
            }
        }
        final String finalValue;
        if (partial.isEmpty()) {
            finalValue = "[]";
        } else {
            if (state.gap.length() == 0) {
                finalValue = '[' + join(partial",") + ']';
            } else {
                String separator = ",\n" + state.indent;
                String properties = join(partialseparator);
                finalValue = "[\n" + state.indent + properties + '\n' + stepback + ']';
            }
        }
        state.stack.pop();
        state.indent = stepback;
        return finalValue;
    }
    private static String quote(String string) {
        StringBuffer product = new StringBuffer(string.length()+2); // two extra chars for " on either side
        product.append('"');
        int length = string.length();
        for (int i = 0; i < lengthi++) {
            char c = string.charAt(i);
            switch (c) {
                case '"':
                    product.append("\\\"");
                    break;
                case '\\':
                    product.append("\\\\");
                    break;
                case '\b':
                    product.append("\\b");
                    break;
                case '\f':
                    product.append("\\f");
                    break;
                case '\n':
                    product.append("\\n");
                    break;
                case '\r':
                    product.append("\\r");
                    break;
                case '\t':
                    product.append("\\t");
                    break;
                default:
                    if (c < ' ') {
                        product.append("\\u");
                        String hex = String.format("%04x", (intc);
                        product.append(hex);
                    }
                    else {
                        product.append(c);
                    }
                    break;
            }
        }
        product.append('"');
        return product.toString();
    }
// #string_id_map#
    @Override
    protected int findPrototypeId(String s)
    {
        int id;
// #generated# Last update: 2009-05-25 16:01:00 EDT
        {   id = 0; String X = null;
            L: switch (s.length()) {
            case 5: X="parse";id=break L;
            case 8: X="toSource";id=break L;
            case 9: X="stringify";id=break L;
            }
            if (X!=null && X!=s && !X.equals(s)) id = 0;
        }
// #/generated#
        return id;
    }
    private static final int
        Id_toSource     = 1,
        Id_parse        = 2,
        Id_stringify    = 3,
        LAST_METHOD_ID  = 3,
        MAX_ID          = 3;
// #/string_id_map#
New to GrepCode? Check out our FAQ X