All Downloads are FREE. Search and download functionalities are using the official Maven repository.

json.com.unbound.common.JSON Maven / Gradle / Ivy

Go to download

This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi

There is a newer version: 42761
Show newest version
package com.unbound.common;

import java.util.*;

public final class JSON
{
  public static Object convert(String in)
  {
    Parser parser = new Parser(in);
    Object item =  parser.parseAny();
    Parser.check(parser.token==0);
    return item;
  }

  public static String convert(Object in)
  {
    StringBuilder sb = new StringBuilder();
    build(in, sb);
    return sb.toString();
  }

  private static void build(Object in, StringBuilder sb)
  {
    if (in==null) sb.append("null");
    else if (in instanceof List) buildList((List)in, sb);
    else if (in instanceof Map) buildMap((Map)in, sb);
    else if (in instanceof Boolean) sb.append(((Boolean)in).booleanValue() ? "true" : "false");
    else if (in instanceof Long) sb.append(((Long)in).toString());
    else if (in instanceof Integer) sb.append(((Integer)in).toString());
    else if (in instanceof Short) sb.append(((Short)in).toString());
    else if (in instanceof Byte) sb.append(((Byte)in).toString());
    else if (in instanceof Double) sb.append(((Double)in).toString());
    else if (in instanceof Float) sb.append(((Float)in).toString());
    else if (in instanceof String) buildString((String)in, sb);
  }

  private static void buildString(String value, StringBuilder sb)
  {
    sb.append('"');
    int length = value.length();
    for (int i=0; i>8) & 0x0f]);
            sb.append(HEX.upChars[c & 0x0f]);
          }
          else
            sb.append(c);
      }
    }
    sb.append('"');
  }

  private static void buildMap(Map map, StringBuilder sb)
  {
    sb.append('{');
    boolean first = true;
    for (Map.Entry entry : map.entrySet())
    {
      if (!first)
      {
        sb.append(',');
        first = false;
      }
      sb.append('"');
      java.lang.String key = entry.getKey();
      sb.append(key, 0, key.length());
      sb.append('"');
      sb.append(':');
      build(entry.getValue(),sb);
    }
    sb.append('}');
  }

  private static void buildList(List array, StringBuilder sb)
  {
    sb.append('[');
    boolean first = true;
    for (Object item : array)
    {
      if (!first)
      {
        sb.append(',');
        first = false;
      }
      build(item, sb);
    }
    sb.append(']');
  }

  private final static class Parser
  {
    private String src;
    private int index;
    private char c;
    private char token;
    private String tokenValue;

    Parser(String src)
    {
      this.src = src;
      index = 0;
      c = ' ';
      token = ' ';
      getNextToken();
    }

    static void check(boolean ok)
    {
      if (!ok) throw new InputMismatchException("JSON conversion error");
    }

    private char currentChar()
    {
      return c;
    }

    private char currentToken()
    {
      check(token!=0);
      return token;
    }

    private void getNextChar()
    {
      if (index >= src.length()) c = 0;
      else c = src.charAt(index++);
    }

    private void readNumber()
    {
      token = '0';
      StringBuilder sb = new StringBuilder();
      for (;;)
      {
        char c = currentChar();
        if ((c<'0' || c>'9') && c!='.' && c!='E' && c!='e' && c!='+' && c!='-') break;
        if (c=='.' || c=='E' || c=='e') token = 'e';
        sb.append(c);
        getNextChar();
      }
      tokenValue = sb.toString();
    }

    private void skipWhiteSpace()
    {
      for (;;)
      {
        char c = currentChar();
        if (c==0) { token=0; return; };
        if (!Character.isWhitespace(c)) break;
        getNextChar();
      }
    }

    private void skipLineComment()
    {
      for (;;)
      {
        char c = currentChar();
        if (c==0) { token=0; return; };
        if (c=='\n' || c=='\r') break;
        getNextChar();
      }
    }

    private void skipBlockComment()
    {
      getNextChar();
      for (;;)
      {
        char c = currentChar();
        if (c==0) { token=0; return; };
        if (c=='*') break;
        getNextChar();
      }
      getNextChar();
      check(currentChar()=='/');
      getNextChar();
    }

    private void skipComment()
    {
      check(currentChar()=='/');
      getNextChar();
      if (currentChar()=='*') skipBlockComment();
      else
      {
        check(currentChar()=='/');
        skipLineComment();
      }
    }

    private void readTokenValue()
    {
      StringBuilder sb = new StringBuilder();
      for (;;)
      {
        char c = currentChar();
        if (c==0) { token=0; return; };
        if (c<'a' || c>'z') break;
        sb.append(c);
        getNextChar();
      }
      tokenValue = sb.toString();
    }

    private void readString()
    {
      StringBuilder sb = new StringBuilder();
      getNextChar();
      while (currentChar()!='"')
      {
        char c1 = currentChar(); getNextChar();

        if (c1=='\\')
        {
          char c2 = currentChar(); getNextChar();

          switch (c2)
          {
            case '\\': case '\'': case '/': case '"': c1 = c2; break;
            case 't': c1 = '\t'; break;
            case 'n': c1 = '\n'; break;
            case 'r': c1 = '\r'; break;
            case 'f': c1 = '\f'; break;
            case 'b': c1 = '\b'; break;
            case 'u':
              int x1 = HEX.from(currentChar()); getNextChar();
              int x2 = HEX.from(currentChar()); getNextChar();
              int x3 = HEX.from(currentChar()); getNextChar();
              int x4 = HEX.from(currentChar()); getNextChar();
              c1 = (char)((x1<<12) | (x2<<8) | (x3<<4) | x4);
              break;

            default:
              check(false);
          }
        }
        sb.append(c1);
      }
      tokenValue = sb.toString();
      getNextChar();
    }

    private void getNextToken()
    {
      for (;;)
      {
        skipWhiteSpace();
        if (currentChar()!='/') break;
        skipComment();
      }

      token = currentChar();
      if (currentChar()>='0' && currentChar()<='9') readNumber();
      else
      {
        switch (currentChar())
        {
          case 'E': case 'e': case '.': case '+': case '-':  readNumber();  break;
          case 't': case 'f': case 'n':                      readTokenValue(); break;
          case '"':                                          readString(); break;
          default:                                           getNextChar();
        }
      }
    }

    Object parseAny()
    {
      char token = currentToken();

      switch (token)
      {
        case '{': return parseObject();
        case '[': return parseArray();
        case '"': return parseString();

        case '0':
        case 'e': return parseNumber();

        case 't':
        case 'f': return parseBoolean();

        case 'n': return parseNull();
      }
      check(false);
      return null;
    }

    private ArrayList parseArray()
    {
      ArrayList array = new ArrayList<>();
      getNextToken();

      for (;;)
      {
        if (currentToken()==']')
        {
          getNextToken();
          break;
        }

        Object item = parseAny();
        array.add(item);

        if (currentToken()==']')
        {
          getNextToken();
          break;
        }

        check(currentToken()==',');
        getNextToken();
      }
      return array;
    }

    Map parseObject()
    {
      Map map = new HashMap<>();
      getNextToken();

      for (;;)
      {
        if (currentToken()=='}')
        {
          getNextToken();
          break;
        }

        check( currentToken() == '"');
        getNextToken();
        String name = tokenValue;

        check(currentToken()==':');
        getNextToken();

        Object item = parseAny();
        map.put(name, item);

        if (currentToken()=='}')
        {
          getNextToken();
          break;
        }

        check(currentToken()==',');
        getNextToken();
      }

      return map;
    }

    private String parseString()
    {
      String result = tokenValue;
      getNextToken();
      return result;
    }

    private Boolean parseBoolean()
    {
      boolean value = currentToken()=='t';
      check(tokenValue.equals(value ? "true" : "false"));
      getNextToken();
      return value;
    }

    private Object parseNull()
    {
      check(tokenValue.equals("null"));
      getNextToken();
      return null;
    }

    private Object parseNumber()
    {
      boolean isDouble = currentToken()=='e';
      Object result;
      if (isDouble) result = Double.valueOf(tokenValue);
      else result = Long.valueOf(tokenValue);
      getNextToken();
      return result;
    }
  }
}