Package com.firefly.utils.json.io

Source Code of com.firefly.utils.json.io.JsonStringReader

package com.firefly.utils.json.io;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;

import com.firefly.utils.VerifyUtils;
import com.firefly.utils.json.JsonReader;
import com.firefly.utils.json.exception.JsonException;

public class JsonStringReader extends JsonReader {
  private char[] chars;
  private int pos = 0;
  private final int limit;
  private int mark = 0;

  public JsonStringReader(String str) {
    chars = str.toCharArray();
    limit = chars.length;
  }
 
  @Override
  public void mark(int readAheadLimit) {
    mark = pos;
  }
 
  @Override
  public void reset() {
    pos = mark;
  }
 
  @Override
  public boolean isEndFlag(char ch) {
    switch (ch) {
    case ',':
    case '}':
    case ']':
    case ' ':
    case ':':
      return true;
    }
    return false;
  }
 
  @Override
  public boolean isString() {
    char c = readAndSkipBlank();
    return c == '"';
  }

  @Override
  public boolean isArray() {
    char c = readAndSkipBlank();
    return c == '[';
  }
 
  @Override
  public boolean isEmptyArray() {
    mark(1024);
    char c = readAndSkipBlank();
   
    if(c == ']')
      return true;
   
    reset();
    return false;
  }

  @Override
  public boolean isObject() {
    char c = readAndSkipBlank();
    return c == '{';
  }
 
  @Override
  public boolean isEmptyObject() {
    mark(1024);
    char c = readAndSkipBlank();
   
    if(c == '}')
      return true;
   
    reset();
    return false;
  }
 
  @Override
  public boolean isColon() {
    char c = readAndSkipBlank();
    return c == ':';
  }
 
  @Override
  public boolean isComma() {
    char c = readAndSkipBlank();
    return c == ',';
  }
 
  @Override
  public boolean isNull() {
    mark(1024);
    char ch = readAndSkipBlank();
    if(pos + 3 > limit) {
      reset();
      return false;
    }
   
    if(ch == 'n' && 'u' == read() && 'l' == read() && 'l' == read()) {
      if(pos >= limit)
        return true;
     
      ch = readAndSkipBlank();
      if(isEndFlag(ch)) {
        pos--;
        return true;
      } else {
        reset();
        return false;
      }
    } else {
      reset();
      return false;
    }
  }

  @Override
  public int read() {
    return chars[pos++];
  }

  @Override
  public char readAndSkipBlank() {
    char c = (char)read();
    if (c > ' ')
      return c;
    for (;;) {
      c = (char)read();
      if (c > ' ')
        return c;
    }
  }
 
  @Override
  public boolean readBoolean() {
    boolean ret = false;
   
    if(isNull())
      return ret;
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
   
    if(ch == 't' && 'r' == read() && 'u' == read() && 'e' == read())
      ret = true;
    else if (ch == 'f' && 'a' == read() && 'l' == read() && 's' == read() && 'e' == read())
      ret = false;
   
    if(isString) {
      ch = readAndSkipBlank();
      if(ch != '"')
        throw new JsonException("read boolean error");
    }
   
    return ret;
  }
 
  @Override
  public int readInt() {
    int value = 0;

    if(isNull())
      return value;
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    boolean negative = (ch == '-');
   
    if(!negative) {
      if(VerifyUtils.isDigit(ch))
        value = (value << 3) + (value << 1) + (ch - '0');
      else
        throw new JsonException("read int error, charactor \"" + ch + "\" is not integer");
    }
   
    for(;;) {
      ch = (char)read();
      if(VerifyUtils.isDigit(ch))
        value = (value << 3) + (value << 1) + (ch - '0');
      else {
        if(isString) {
          if(ch == '"')
            break;
        } else {
          if (isEndFlag(ch)) {
            pos--;
            break;
          } else
            throw new JsonException("read int error, charactor \"" + ch + "\" is not integer");
        }
      }
     
      if(pos >= limit)
        break;
    }
    return negative ? -value : value;
  }
 
  @Override
  public long readLong() {
    long value = 0;

    if(isNull())
      return value;
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    boolean negative = (ch == '-');
   
    if(!negative) {
      if(VerifyUtils.isDigit(ch))
        value = (value << 3) + (value << 1) + (ch - '0');
      else
        throw new JsonException("read int error, charactor \"" + ch + "\" is not integer");
    }
   
    for(;;) {
      ch = (char)read();
      if(VerifyUtils.isDigit(ch))
        value = (value << 3) + (value << 1) + (ch - '0');
      else {
        if(isString) {
          if(ch == '"')
            break;
        } else {
          if (isEndFlag(ch)) {
            pos--;
            break;
          } else
            throw new JsonException("read int error, charactor \"" + ch + "\" is not integer");
        }
      }
     
      if(pos >= limit)
        break;
    }
    return negative ? -value : value;
  }
 
  @Override
  public BigInteger readBigInteger() {
    String value = "0";
   
    if(isNull())
      return new BigInteger(value);
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    pos--;
   
    int start = pos;
    for(;;) {
      ch = (char)read();
      if(isString) {
        if(ch == '"')
          break;
      } else {
        if (isEndFlag(ch)) {
          pos--;
          break;
        }
      }
    }
   
    int len = isString ? pos - start - 1 : pos - start;
    String temp = new String(chars, start, len);
    return new BigInteger(temp);
  }
 
  @Override
  public BigDecimal readBigDecimal() {
    String value = "0.0";
   
    if(isNull())
      return new BigDecimal(value);
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    pos--;
   
    int start = pos;
    for(;;) {
      ch = (char)read();
      if(isString) {
        if(ch == '"')
          break;
      } else {
        if (isEndFlag(ch)) {
          pos--;
          break;
        }
      }
    }
   
    int len = isString ? pos - start - 1 : pos - start;
    String temp = new String(chars, start, len);
    return new BigDecimal(temp);
  }
 
  @Override
  public double readDouble() {
    double value = 0.0;

    if(isNull())
      return value;
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    pos--;
   
    int start = pos;
    for(;;) {
      ch = (char)read();
      if(isString) {
        if(ch == '"')
          break;
      } else {
        if (isEndFlag(ch)) {
          pos--;
          break;
        }
      }
    }
   
    int len = isString ? pos - start - 1 : pos - start;
    String temp = new String(chars, start, len);
    return Double.parseDouble(temp);
  }
 
  @Override
  public float readFloat() {
    float value = 0.0F;

    if(isNull())
      return value;
   
    char ch = readAndSkipBlank();
    boolean isString = (ch == '"');
    if(isString)
      ch = readAndSkipBlank();
    pos--;
   
    int start = pos;
    for(;;) {
      ch = (char)read();
      if(isString) {
        if(ch == '"')
          break;
      } else {
        if (isEndFlag(ch)) {
          pos--;
          break;
        }
      }
    }
   
    int len = isString ? pos - start - 1 : pos - start;
    String temp = new String(chars, start, len);
    return Float.parseFloat(temp);
  }

  @Override
  public char[] readField(char[] chs) {
    if(!isString())
      throw new JsonException("read field error");
     
    int cur = pos;
    int len = chs.length;
    boolean skip = true;
   
    int next = pos + len;
    if(next < limit && chars[next] == '"') {
      for (int i = 0; i < len; i++) {
        if (chs[i] != chars[cur++]) {
          skip = false;
          break;
        }
      }
    } else {
      skip = false;
    }

    if (skip) {
      pos = cur + 1;
      return null;
    } else {
      char[] field = null;
      int start = pos;
      for(;;) {
        char c = (char)read();
        if(c == '"')
          break;
      }
      int fieldLen = pos - 1 - start;
      field = new char[fieldLen];
      System.arraycopy(chars, start, field, 0, fieldLen);
      return field;
    }
  }
 
  @Override
  public char[] readChars() {
    if(!isString())
      throw new JsonException("read field error");
   
    int start = pos;
    for(;;) {
      char c = (char)read();
      if(c == '"')
        break;
    }
    int fieldLen = pos - 1 - start;
    char[] c = new char[fieldLen];
    System.arraycopy(chars, start, c, 0, fieldLen);
    return c;
  }
 
  @Override
  public void skipValue() {
    char ch = readAndSkipBlank();
    switch (ch) {
    case '"': // 跳过字符串
      for(;;) {
        ch = (char)read();
        if(ch == '"')
          break;
        else if(ch == '\\')
          pos++;
      }
      break;
    case '[': // 跳过数组
      for(;;) {
        if(isEmptyArray())
          break;
       
        skipValue();
        ch = readAndSkipBlank();
        if(ch == ']')
          break;
       
        if(ch != ',')
          throw new JsonException("json string array format error");
      }
      break;
    case '{': // 跳过对象
      for(;;) {
        if(isEmptyObject())
          break;
       
        readChars();
        if(!isColon())
          throw new JsonException("json string object format error");
       
        skipValue();
        ch = readAndSkipBlank();
        if(ch == '}')
          break;
       
        if(ch != ',')
          throw new JsonException("json string object format error");
      }
      break;

    default: // 跳过数字或者null
      for(;;) {
        ch = (char)read();
        if(isEndFlag(ch)) {
          pos--;
          break;
        }
      }
      break;
    }
  }
 
  @Override
  public String readString() {
    if(isNull())
      return null;
   
    if(!isString())
      throw new JsonException("read string error");
   
    JsonStringWriter writer = new JsonStringWriter();
    String ret = null;
   
    int cur = pos;
    int len = 0;
    for(;;) {
      char ch = chars[cur++];
      if(ch == '"') {
        len = cur - pos - 1;
        writer.write(chars, pos, len);
        pos = cur;
        break;
      } else if(ch == '\\') {
        char c0 = chars[cur++];
        len = cur - 2 - pos;
        writer.write(chars, pos, len);
        switch (c0) {
        case 'b':
          writer.write('\b');
          break;
        case 'n':
          writer.write('\n');
          break;
        case 'r':
          writer.write('\r');
          break;
        case 'f':
          writer.write('\f');
          break;
        case '\\':
          writer.write('\\');
          break;
        case '/':
          writer.write('/');
          break;
        case '"':
          writer.write('"');
          break;
        case 't':
          writer.write('\t');
          break;
        case 'u': // unicode char parse
          char[] controlChars = new char[4];
          for (int i = 0; i < controlChars.length; i++) {
            controlChars[i] = chars[cur++];
          }
          char tmp = (char)Integer.parseInt(String.valueOf(controlChars), 16);
          writer.write(tmp);
          break;
        }
        pos = cur;
      }
     
    }
    try {
      ret = writer.toString();
    } finally {
      writer.close();
    }
    return ret;
  }

  @Override
  public int read(char[] cbuf, int off, int len) throws IOException {
    throw new JsonException("method not implements!");
  }
 
  @Override
  public void close() throws IOException {
   
  }

}
TOP

Related Classes of com.firefly.utils.json.io.JsonStringReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.