JSONCkecker(Java语言版本)
// MIT License
//
// Copyright (c) 2016 Michel Kraemer
// Copyright (c) 2005 JSON.org
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. package de.undercouch.actson; /**
* This class is based on the file
* <a href="http://www.json.org/JSON_checker/">JSON_checker.c</a>
* from <a href="http://www.json.org/">JSON.org</a>
* @author Michel Kraemer
* @author JSON.org
*/
public class JsonChecker {
private static final int __ = -1; // the universal error code /**
* Characters are mapped into these 31 character classes. This allows for
* a significant reduction in the size of the state transition table.
*/
private static final int C_SPACE = 0; // space
private static final int C_WHITE = 1; // other whitespace
private static final int C_LCURB = 2; // {
private static final int C_RCURB = 3; // }
private static final int C_LSQRB = 4; // [
private static final int C_RSQRB = 5; // ]
private static final int C_COLON = 6; // :
private static final int C_COMMA = 7; // ,
private static final int C_QUOTE = 8; // "
private static final int C_BACKS = 9; // \
private static final int C_SLASH = 10; // /
private static final int C_PLUS = 11; // +
private static final int C_MINUS = 12; // -
private static final int C_POINT = 13; // .
private static final int C_ZERO = 14; //
private static final int C_DIGIT = 15; //
private static final int C_LOW_A = 16; // a
private static final int C_LOW_B = 17; // b
private static final int C_LOW_C = 18; // c
private static final int C_LOW_D = 19; // d
private static final int C_LOW_E = 20; // e
private static final int C_LOW_F = 21; // f
private static final int C_LOW_L = 22; // l
private static final int C_LOW_N = 23; // n
private static final int C_LOW_R = 24; // r
private static final int C_LOW_S = 25; // s
private static final int C_LOW_T = 26; // t
private static final int C_LOW_U = 27; // u
private static final int C_ABCDF = 28; // ABCDF
private static final int C_E = 29; // E
private static final int C_ETC = 30; // everything else /**
* This array maps the 128 ASCII characters into character classes.
* The remaining Unicode characters should be mapped to C_ETC.
* Non-whitespace control characters are errors.
*/
private final static int[] ascii_class = {
__, __, __, __, __, __, __, __,
__, C_WHITE, C_WHITE, __, __, C_WHITE, __, __,
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, C_SPACE, C_ETC, C_QUOTE, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_PLUS, C_COMMA, C_MINUS, C_POINT, C_SLASH,
C_ZERO, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
C_DIGIT, C_DIGIT, C_COLON, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E, C_ABCDF, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_LSQRB, C_BACKS, C_RSQRB, C_ETC, C_ETC, C_ETC, C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_LOW_L, C_ETC, C_LOW_N, C_ETC,
C_ETC, C_ETC, C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_LCURB, C_ETC, C_RCURB, C_ETC, C_ETC
}; /**
* The state codes.
*/
private static final int GO = 0; // start
private static final int OK = 1; // ok
private static final int OB = 2; // object
private static final int KE = 3; // key
private static final int CO = 4; // colon
private static final int VA = 5; // value
private static final int AR = 6; // array
private static final int ST = 7; // string
private static final int ES = 8; // escape
private static final int U1 = 9; // u1
private static final int U2 = 10; // u2
private static final int U3 = 11; // u3
private static final int U4 = 12; // u4
private static final int MI = 13; // minus
private static final int ZE = 14; // zero
private static final int IN = 15; // integer
private static final int FR = 16; // fraction
private static final int E1 = 17; // e
private static final int E2 = 18; // ex
private static final int E3 = 19; // exp
private static final int T1 = 20; // tr
private static final int T2 = 21; // tru
private static final int T3 = 22; // true
private static final int F1 = 23; // fa
private static final int F2 = 24; // fal
private static final int F3 = 25; // fals
private static final int F4 = 26; // false
private static final int N1 = 27; // nu
private static final int N2 = 28; // nul
private static final int N3 = 29; // null /**
* The state transition table takes the current state and the current symbol,
* and returns either a new state or an action. An action is represented as a
* negative number. A JSON text is accepted if at the end of the text the
* state is OK and if the mode is MODE_DONE.
*/
private static int[][] state_transition_table = {
/* white 1-9 ABCDF etc
space | { } [ ] : , " \ / + - . 0 | a b c d e f l n r s t u | E |*/
/*start GO*/ {GO,GO,-6,__,-5,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*ok OK*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*object OB*/ {OB,OB,__,-9,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*key KE*/ {KE,KE,__,__,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*colon CO*/ {CO,CO,__,__,__,__,-2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*value VA*/ {VA,VA,-6,__,-5,__,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
/*array AR*/ {AR,AR,-6,__,-5,-7,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
/*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-4,ES,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
/*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__},
/*u1 U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__},
/*u2 U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__},
/*u3 U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__},
/*u4 U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ST,ST,ST,ST,ST,ST,ST,ST,__,__,__,__,__,__,ST,ST,__},
/*minus MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IN,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*zero ZE*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,FR,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*int IN*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,FR,IN,IN,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
/*frac FR*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
/*e E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*ex E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*exp E3*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*tr T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__},
/*tru T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__},
/*true T3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
/*fa F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*fal F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__},
/*fals F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__},
/*false F4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
/*nu N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__},
/*nul N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__},
/*null N3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__},
}; /**
* These modes can be pushed on the stack.
*/
private static final int MODE_ARRAY = 0;
private static final int MODE_DONE = 1;
private static final int MODE_KEY = 2;
private static final int MODE_OBJECT = 3; /**
* The stack containing the current modes
*/
private int[] stack; /**
* The top of the stack (-1 if the stack is empty)
*/
private int top = -1; /**
* The current state
*/
private int state; /**
* Push a mode onto the stack
* @param mode the mode to push
* @return false if there is overflow
*/
private boolean push(int mode) {
++top;
if (top >= stack.length) {
return false;
}
stack[top] = mode;
return true;
} /**
* Pop the stack, assuring that the current mode matches the expectation
* @param mode the expected mode
* @return false if there is underflow or if the modes mismatch
*/
private boolean pop(int mode) {
if (top < 0 || stack[top] != mode) {
return false;
}
--top;
return true;
} /**
* Constructs the JsonChecker
*/
public JsonChecker() {
this(16);
} /**
* Constructs the JsonChecker
* @param depth the maximum number of nested states
*/
public JsonChecker(int depth) {
stack = new int[depth];
top = -1;
state = GO;
push(MODE_DONE);
} /**
* Call this function for each character (or partial character) in your JSON text.
* It can accept UTF-8, UTF-16, or UTF-32.
* @param nextChar the character to feed
* @return <code>true</code> if things are looking ok so far, <code>false</code>
* if it rejects the text.
*/
public boolean feed(char nextChar) {
// Determine the character's class.
int nextClass;
if (nextChar < 0) {
return false;
}
if (nextChar >= 128) {
nextClass = C_ETC;
} else {
nextClass = ascii_class[nextChar];
if (nextClass <= __) {
return false;
}
} // Get the next state from the state transition table.
int nextState = state_transition_table[state][nextClass];
if (nextState >= 0) {
// Change the state.
state = nextState;
} else {
// Or perform one of the actions.
switch (nextState) {
// empty }
case -9:
if (!pop(MODE_KEY)) {
return false;
}
state = OK;
break; // }
case -8:
if (!pop(MODE_OBJECT)) {
return false;
}
state = OK;
break; // ]
case -7:
if (!pop(MODE_ARRAY)) {
return false;
}
state = OK;
break; // {
case -6:
if (!push(MODE_KEY)) {
return false;
}
state = OB;
break; // [
case -5:
if (!push(MODE_ARRAY)) {
return false;
}
state = AR;
break; // "
case -4:
switch (stack[top]) {
case MODE_KEY:
state = CO;
break;
case MODE_ARRAY:
case MODE_OBJECT:
state = OK;
break;
default:
return false;
}
break; // ,
case -3:
switch (stack[top]) {
case MODE_OBJECT:
// A comma causes a flip from object mode to key mode.
if (!pop(MODE_OBJECT) || !push(MODE_KEY)) {
return false;
}
state = KE;
break;
case MODE_ARRAY:
state = VA;
break;
default:
return false;
}
break; // :
case -2:
// A colon causes a flip from key mode to object mode.
if (!pop(MODE_KEY) || !push(MODE_OBJECT)) {
return false;
}
state = VA;
break; // Bad action.
default:
return false;
}
}
return true;
} /**
* This method should be called after all of the characters have been
* processed, but only if every call to {@link #feed(char)} returned
* <code>true</code>.
* @return <code>true</code> if the JSON text was accepted.
*/
public boolean done() {
return state == OK && pop(MODE_DONE);
}
}
JSONCkecker(Java语言版本)的更多相关文章
- 微信公众平台应用开发:方法、技巧与案例--柳峰,Java语言版本
他本人的博客:http://blog.csdn.net/lyq8479 作者简介: 刘运强,网名“柳峰”,资深微信公众平台应用开发工程师,国内微信公众平台应用开发的先驱之一,项目经验丰富.他还是一位资 ...
- day01<计算机基础知识&Java语言基础>
计算机基础知识(计算机概述) 计算机基础知识(软件开发和计算机语言概述) 计算机基础知识(人机交互) 计算机基础知识(键盘功能键和快捷键) 计算机基础知识(如何打开DOS控制台) 计算机基础知识(常见 ...
- Java语言发展史
Java语言发展史 詹姆斯·高斯林(James Gosling)1977年获得了加拿大卡尔加里大学计算机科学学士学位,1983年获得了美国卡内基梅隆大学计算机科学博士学位,毕业后到IBM工作,设计IB ...
- 让这个Java语言的开源商城系统火起来
Java是一门非常优秀的面向对象编程语言,功能强大且简单易用,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,凭借其简单性.面向对象.分布式.健壮性.安全性.平台独立与可 ...
- JAVA语言搭建白盒静态代码、黑盒网站插件式自动化安全审计平台
近期打算做一个插件化的白盒静态代码安全审计自动化平台和黑盒网站安全审计自动化平台.现在开源或半开源做黑盒网站安全扫描的平台,大多是基于python脚本,安全人员贡献python脚本插件增强平台功能.对 ...
- 【百度文库课程】Java语言基础与OOP入门学习笔记一
一. Java的历史与由来 原名Oak,针对嵌入式系统开发设计,语法与C/C++基本一致 二. Java语言特点 Java由四方面组成:Java编程语言.Java类文件格式.Java虚拟机和Java应 ...
- 20145205 java语言实现数据结构实验一
数据结构实验要求 综合类实验设计3 已知有一组数据a1a2a3a4--anb1b2b3b4--bm,其中ai均大于bj,但是a1到an和b1到bm不是有序的,试设计两到三个算法完成数据排序,且把bj数 ...
- 瘋耔java语言笔记
一◐ java概述 1.1 ...
- Java语言的个人理解
Java语言的个人理解(比价深层次吧) 大四的生活确实十分的奢靡,不锻炼,不读书,几乎就是当一天和尚撞一天钟的生活,太颓废了,还好自己不是这个样子,不过身体确实差了很多,昨天跑了一圈内环(4KM),今 ...
随机推荐
- 第一册:lesson twenty seven。
原文 :Mrs.smith's living room. Mrs.smith's living room is large. There is a television in the room. Th ...
- fork/join 全面剖析
fork/join作为一个并发框架在jdk7的时候就加入到了我们的java并发包java.util.concurrent中,并且在java 8 的lambda并行流中充当着底层框架的角色.这样一个优秀 ...
- Flask 系列之 Pagination
说明 操作系统:Windows 10 Python 版本:3.7x 虚拟环境管理器:virtualenv 代码编辑器:VS Code 实验目标 实现当前登录用户的事务浏览.添加.删除 操作 实现 首先 ...
- windows生成当前目录树
tree /f > list.txt 需要以管理员运行cmd
- mac svn的使用
一.概述 在windows下,我们常常用TortoiseSVN管理svn代码.在mac下,自带svn客户端和服务器端功能. 二.服务端:创建代码仓库,用来存储客户端所上传的代码 (1)创建svn代码存 ...
- canvas-6shadow.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JS之innerHTML,innerText,outerHTML,textContent的用法与区别
示例html代码: <div id="test"> <span style="color:red">test1</span> ...
- 如何理解MVC?
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范. 那么MVC框架究竟干了些什么:用一种业务逻辑. ...
- window.print()小知识
window.print() 实际上,是浏览器打印功能菜单的一种程序调用.与点击打印功能菜单一样,不能精确分页,不能设置纸型,套打的问题更加无从谈起,只不过,可以让用户不用去点菜单,直接点击网页中的 ...
- CSS中默认被继承的属性
在CSS中,所有属性都可以被继承,只需要显式的设置属性值为inherit即可.如果不设置该属性,CSS大部分属性默认不会从父元素继承而是设置初始值(initial value),但是有一部分属性,默认 ...