Esempio n. 1
0
  /* ------------------------------------------------------------ */
  protected Object parseArray(Source source) {
    if (source.next() != '[') throw new IllegalStateException();

    int size = 0;
    ArrayList list = null;
    Object item = null;
    boolean coma = true;

    while (source.hasNext()) {
      char c = source.peek();
      switch (c) {
        case ']':
          source.next();
          switch (size) {
            case 0:
              return newArray(0);
            case 1:
              Object array = newArray(1);
              Array.set(array, 0, item);
              return array;
            default:
              return list.toArray(newArray(list.size()));
          }

        case ',':
          if (coma) throw new IllegalStateException();
          coma = true;
          source.next();
          break;

        default:
          if (Character.isWhitespace(c)) source.next();
          else {
            coma = false;
            if (size++ == 0) item = contextForArray().parse(source);
            else if (list == null) {
              list = new ArrayList();
              list.add(item);
              item = contextForArray().parse(source);
              list.add(item);
              item = null;
            } else {
              item = contextForArray().parse(source);
              list.add(item);
              item = null;
            }
          }
      }
    }

    throw new IllegalStateException("unexpected end of array");
  }
Esempio n. 2
0
  /* ------------------------------------------------------------ */
  protected static void complete(String seek, Source source) {
    int i = 0;
    while (source.hasNext() && i < seek.length()) {
      char c = source.next();
      if (c != seek.charAt(i++))
        throw new IllegalStateException("Unexpected '" + c + " while seeking  \"" + seek + "\"");
    }

    if (i < seek.length()) throw new IllegalStateException("Expected \"" + seek + "\"");
  }
Esempio n. 3
0
  /* ------------------------------------------------------------ */
  protected void seekTo(char seek, Source source) {
    while (source.hasNext()) {
      char c = source.peek();
      if (c == seek) return;

      if (!Character.isWhitespace(c))
        throw new IllegalStateException("Unexpected '" + c + " while seeking '" + seek + "'");
      source.next();
    }

    throw new IllegalStateException("Expected '" + seek + "'");
  }
Esempio n. 4
0
  /* ------------------------------------------------------------ */
  protected Object parseObject(Source source) {
    if (source.next() != '{') throw new IllegalStateException();
    Map<String, Object> map = newMap();

    char next = seekTo("\"}", source);

    while (source.hasNext()) {
      if (next == '}') {
        source.next();
        break;
      }

      String name = parseString(source);
      seekTo(':', source);
      source.next();

      Object value = contextFor(name).parse(source);
      map.put(name, value);

      seekTo(",}", source);
      next = source.next();
      if (next == '}') break;
      else next = seekTo("\"}", source);
    }

    String classname = (String) map.get("class");
    if (classname != null) {
      try {
        Class c = Loader.loadClass(JSON.class, classname);
        return convertTo(c, map);
      } catch (ClassNotFoundException e) {
        LOG.warn(e);
      }
    }
    return map;
  }
Esempio n. 5
0
  /* ------------------------------------------------------------ */
  protected char seekTo(String seek, Source source) {
    while (source.hasNext()) {
      char c = source.peek();
      if (seek.indexOf(c) >= 0) {
        return c;
      }

      if (!Character.isWhitespace(c))
        throw new IllegalStateException(
            "Unexpected '" + c + "' while seeking one of '" + seek + "'");
      source.next();
    }

    throw new IllegalStateException("Expected one of '" + seek + "'");
  }
Esempio n. 6
0
  /* ------------------------------------------------------------ */
  public Number parseNumber(Source source) {
    boolean minus = false;
    long number = 0;
    StringBuilder buffer = null;

    longLoop:
    while (source.hasNext()) {
      char c = source.peek();
      switch (c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          number = number * 10 + (c - '0');
          source.next();
          break;

        case '-':
        case '+':
          if (number != 0) throw new IllegalStateException("bad number");
          minus = true;
          source.next();
          break;

        case '.':
        case 'e':
        case 'E':
          buffer = new StringBuilder(16);
          if (minus) buffer.append('-');
          buffer.append(number);
          buffer.append(c);
          source.next();
          break longLoop;

        default:
          break longLoop;
      }
    }

    if (buffer == null) return minus ? -1 * number : number;

    doubleLoop:
    while (source.hasNext()) {
      char c = source.peek();
      switch (c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '-':
        case '.':
        case '+':
        case 'e':
        case 'E':
          buffer.append(c);
          source.next();
          break;

        default:
          break doubleLoop;
      }
    }
    return new Double(buffer.toString());
  }
Esempio n. 7
0
  /* ------------------------------------------------------------ */
  protected String parseString(Source source) {
    if (source.next() != '"') throw new IllegalStateException();

    boolean escape = false;

    StringBuilder b = null;
    final char[] scratch = source.scratchBuffer();

    if (scratch != null) {
      int i = 0;
      while (source.hasNext()) {
        if (i >= scratch.length) {
          // we have filled the scratch buffer, so we must
          // use the StringBuffer for a large string
          b = new StringBuilder(scratch.length * 2);
          b.append(scratch, 0, i);
          break;
        }

        char c = source.next();

        if (escape) {
          escape = false;
          switch (c) {
            case '"':
              scratch[i++] = '"';
              break;
            case '\\':
              scratch[i++] = '\\';
              break;
            case '/':
              scratch[i++] = '/';
              break;
            case 'b':
              scratch[i++] = '\b';
              break;
            case 'f':
              scratch[i++] = '\f';
              break;
            case 'n':
              scratch[i++] = '\n';
              break;
            case 'r':
              scratch[i++] = '\r';
              break;
            case 't':
              scratch[i++] = '\t';
              break;
            case 'u':
              char uc =
                  (char)
                      ((TypeUtil.convertHexDigit((byte) source.next()) << 12)
                          + (TypeUtil.convertHexDigit((byte) source.next()) << 8)
                          + (TypeUtil.convertHexDigit((byte) source.next()) << 4)
                          + (TypeUtil.convertHexDigit((byte) source.next())));
              scratch[i++] = uc;
              break;
            default:
              scratch[i++] = c;
          }
        } else if (c == '\\') {
          escape = true;
          continue;
        } else if (c == '\"') {
          // Return string that fits within scratch buffer
          return toString(scratch, 0, i);
        } else scratch[i++] = c;
      }

      // Missing end quote, but return string anyway ?
      if (b == null) return toString(scratch, 0, i);
    } else b = new StringBuilder(getStringBufferSize());

    // parse large string into string buffer
    final StringBuilder builder = b;
    while (source.hasNext()) {
      char c = source.next();

      if (escape) {
        escape = false;
        switch (c) {
          case '"':
            builder.append('"');
            break;
          case '\\':
            builder.append('\\');
            break;
          case '/':
            builder.append('/');
            break;
          case 'b':
            builder.append('\b');
            break;
          case 'f':
            builder.append('\f');
            break;
          case 'n':
            builder.append('\n');
            break;
          case 'r':
            builder.append('\r');
            break;
          case 't':
            builder.append('\t');
            break;
          case 'u':
            char uc =
                (char)
                    ((TypeUtil.convertHexDigit((byte) source.next()) << 12)
                        + (TypeUtil.convertHexDigit((byte) source.next()) << 8)
                        + (TypeUtil.convertHexDigit((byte) source.next()) << 4)
                        + (TypeUtil.convertHexDigit((byte) source.next())));
            builder.append(uc);
            break;
          default:
            builder.append(c);
        }
      } else if (c == '\\') {
        escape = true;
        continue;
      } else if (c == '\"') break;
      else builder.append(c);
    }
    return builder.toString();
  }
Esempio n. 8
0
  /* ------------------------------------------------------------ */
  public Object parse(Source source) {
    int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"

    while (source.hasNext()) {
      char c = source.peek();

      // handle // or /* comment
      if (comment_state == 1) {
        switch (c) {
          case '/':
            comment_state = -1;
            break;
          case '*':
            comment_state = 2;
        }
      }
      // handle /* */ comment
      else if (comment_state > 1) {
        switch (c) {
          case '*':
            comment_state = 3;
            break;
          case '/':
            if (comment_state == 3) comment_state = 0;
            else comment_state = 2;
            break;
          default:
            comment_state = 2;
        }
      }
      // handle // comment
      else if (comment_state < 0) {
        switch (c) {
          case '\r':
          case '\n':
            comment_state = 0;
            break;
          default:
            break;
        }
      }
      // handle unknown
      else {
        switch (c) {
          case '{':
            return parseObject(source);
          case '[':
            return parseArray(source);
          case '"':
            return parseString(source);
          case '-':
            return parseNumber(source);

          case 'n':
            complete("null", source);
            return null;
          case 't':
            complete("true", source);
            return Boolean.TRUE;
          case 'f':
            complete("false", source);
            return Boolean.FALSE;
          case 'u':
            complete("undefined", source);
            return null;
          case 'N':
            complete("NaN", source);
            return null;

          case '/':
            comment_state = 1;
            break;

          default:
            if (Character.isDigit(c)) return parseNumber(source);
            else if (Character.isWhitespace(c)) break;
            return handleUnknown(source, c);
        }
      }
      source.next();
    }

    return null;
  }
Esempio n. 9
0
  /* ------------------------------------------------------------ */
  public Object parse(Source source, boolean stripOuterComment) {
    int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
    if (!stripOuterComment) return parse(source);

    int strip_state = 1; // 0=no strip, 1=wait for /*, 2= wait for */

    Object o = null;
    while (source.hasNext()) {
      char c = source.peek();

      // handle // or /* comment
      if (comment_state == 1) {
        switch (c) {
          case '/':
            comment_state = -1;
            break;
          case '*':
            comment_state = 2;
            if (strip_state == 1) {
              comment_state = 0;
              strip_state = 2;
            }
        }
      }
      // handle /* */ comment
      else if (comment_state > 1) {
        switch (c) {
          case '*':
            comment_state = 3;
            break;
          case '/':
            if (comment_state == 3) {
              comment_state = 0;
              if (strip_state == 2) return o;
            } else comment_state = 2;
            break;
          default:
            comment_state = 2;
        }
      }
      // handle // comment
      else if (comment_state < 0) {
        switch (c) {
          case '\r':
          case '\n':
            comment_state = 0;
          default:
            break;
        }
      }
      // handle unknown
      else {
        if (!Character.isWhitespace(c)) {
          if (c == '/') comment_state = 1;
          else if (c == '*') comment_state = 3;
          else if (o == null) {
            o = parse(source);
            continue;
          }
        }
      }

      source.next();
    }

    return o;
  }