PageRenderTime 54ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 1746 lines | 1594 code | 111 blank | 41 comment | 241 complexity | 27f4323126a0085cb2ae0a4760157ee7 MD5 | raw file
  1. /*
  2. * Copyright 1999-2101 Alibaba Group.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.alibaba.fastjson.parser;
  17. import static com.alibaba.fastjson.parser.JSONToken.COLON;
  18. import static com.alibaba.fastjson.parser.JSONToken.COMMA;
  19. import static com.alibaba.fastjson.parser.JSONToken.EOF;
  20. import static com.alibaba.fastjson.parser.JSONToken.ERROR;
  21. import static com.alibaba.fastjson.parser.JSONToken.LBRACE;
  22. import static com.alibaba.fastjson.parser.JSONToken.LBRACKET;
  23. import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING;
  24. import static com.alibaba.fastjson.parser.JSONToken.LPAREN;
  25. import static com.alibaba.fastjson.parser.JSONToken.RBRACE;
  26. import static com.alibaba.fastjson.parser.JSONToken.RBRACKET;
  27. import static com.alibaba.fastjson.parser.JSONToken.RPAREN;
  28. import java.lang.ref.SoftReference;
  29. import java.math.BigDecimal;
  30. import java.math.BigInteger;
  31. import java.util.ArrayList;
  32. import java.util.Calendar;
  33. import java.util.Collection;
  34. import java.util.HashSet;
  35. import java.util.Locale;
  36. import java.util.TimeZone;
  37. import com.alibaba.fastjson.JSON;
  38. import com.alibaba.fastjson.JSONException;
  39. import com.alibaba.fastjson.util.Base64;
  40. //这个类,为了性能优化做了很多特别处理,一切都是为了性能!!!
  41. /**
  42. * @author wenshao<szujobs@hotmail.com>
  43. */
  44. public final class JSONScanner implements JSONLexer {
  45. public final static byte EOI = 0x1A;
  46. private final char[] buf;
  47. private int bp;
  48. private final int buflen;
  49. private int eofPos;
  50. /**
  51. * The current character.
  52. */
  53. private char ch;
  54. /**
  55. * The token's position, 0-based offset from beginning of text.
  56. */
  57. private int pos;
  58. /**
  59. * A character buffer for literals.
  60. */
  61. private char[] sbuf;
  62. private int sp;
  63. /**
  64. * number start position
  65. */
  66. private int np;
  67. /**
  68. * The token, set by nextToken().
  69. */
  70. private int token;
  71. private Keywords keywods = Keywords.DEFAULT_KEYWORDS;
  72. private final static ThreadLocal<SoftReference<char[]>> sbufRefLocal = new ThreadLocal<SoftReference<char[]>>();
  73. private int features = JSON.DEFAULT_PARSER_FEATURE;
  74. private Calendar calendar = null;
  75. private boolean resetFlag = false;
  76. public int resetCount = 0;
  77. public JSONScanner(String input){
  78. this(input, JSON.DEFAULT_PARSER_FEATURE);
  79. }
  80. public JSONScanner(String input, int features){
  81. this(input.toCharArray(), input.length(), features);
  82. }
  83. public JSONScanner(char[] input, int inputLength){
  84. this(input, inputLength, JSON.DEFAULT_PARSER_FEATURE);
  85. }
  86. public JSONScanner(char[] input, int inputLength, int features){
  87. this.features = features;
  88. SoftReference<char[]> sbufRef = sbufRefLocal.get();
  89. if (sbufRef != null) {
  90. sbuf = sbufRef.get();
  91. sbufRefLocal.set(null);
  92. }
  93. if (sbuf == null) {
  94. sbuf = new char[64];
  95. }
  96. eofPos = inputLength;
  97. if (inputLength == input.length) {
  98. if (input.length > 0 && isWhitespace(input[input.length - 1])) {
  99. inputLength--;
  100. } else {
  101. char[] newInput = new char[inputLength + 1];
  102. System.arraycopy(input, 0, newInput, 0, input.length);
  103. input = newInput;
  104. }
  105. }
  106. buf = input;
  107. buflen = inputLength;
  108. buf[buflen] = EOI;
  109. bp = -1;
  110. ch = buf[++bp];
  111. }
  112. public boolean isResetFlag() {
  113. return resetFlag;
  114. }
  115. public void setResetFlag(boolean resetFlag) {
  116. this.resetFlag = resetFlag;
  117. }
  118. public final int getBufferPosition() {
  119. return bp;
  120. }
  121. public void reset(int mark, char mark_ch, int token) {
  122. this.bp = mark;
  123. this.ch = mark_ch;
  124. this.token = token;
  125. resetFlag = true;
  126. resetCount++;
  127. }
  128. public boolean isBlankInput() {
  129. for (int i = 0; i < buflen; ++i) {
  130. if (!isWhitespace(buf[i])) {
  131. return false;
  132. }
  133. }
  134. return true;
  135. }
  136. public static final boolean isWhitespace(char ch) {
  137. // 专门调整了判断顺序
  138. return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b';
  139. }
  140. /**
  141. * Report an error at the current token position using the provided arguments.
  142. */
  143. private void lexError(String key, Object... args) {
  144. token = ERROR;
  145. }
  146. /**
  147. * Return the current token, set by nextToken().
  148. */
  149. public final int token() {
  150. return token;
  151. }
  152. public final String tokenName() {
  153. return JSONToken.name(token);
  154. }
  155. private static boolean[] whitespaceFlags = new boolean[256];
  156. static {
  157. whitespaceFlags[' '] = true;
  158. whitespaceFlags['\n'] = true;
  159. whitespaceFlags['\r'] = true;
  160. whitespaceFlags['\t'] = true;
  161. whitespaceFlags['\f'] = true;
  162. whitespaceFlags['\b'] = true;
  163. }
  164. public final void skipWhitespace() {
  165. for (;;) {
  166. if (whitespaceFlags[ch]) {
  167. ch = buf[++bp];
  168. continue;
  169. } else {
  170. break;
  171. }
  172. }
  173. }
  174. public final char getCurrent() {
  175. return ch;
  176. }
  177. public final void nextTokenWithColon() {
  178. for (;;) {
  179. if (ch == ':') {
  180. ch = buf[++bp];
  181. nextToken();
  182. return;
  183. }
  184. if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
  185. ch = buf[++bp];
  186. continue;
  187. }
  188. throw new JSONException("not match ':' - " + ch);
  189. }
  190. }
  191. public final void nextTokenWithColon(int expect) {
  192. for (;;) {
  193. if (ch == ':') {
  194. ch = buf[++bp];
  195. break;
  196. }
  197. if (isWhitespace(ch)) {
  198. ch = buf[++bp];
  199. continue;
  200. }
  201. throw new JSONException("not match ':', actual " + ch);
  202. }
  203. for (;;) {
  204. if (expect == JSONToken.LITERAL_INT) {
  205. if (ch >= '0' && ch <= '9') {
  206. sp = 0;
  207. pos = bp;
  208. scanNumber();
  209. return;
  210. }
  211. if (ch == '"') {
  212. sp = 0;
  213. pos = bp;
  214. scanString();
  215. return;
  216. }
  217. } else if (expect == JSONToken.LITERAL_STRING) {
  218. if (ch == '"') {
  219. sp = 0;
  220. pos = bp;
  221. scanString();
  222. return;
  223. }
  224. if (ch >= '0' && ch <= '9') {
  225. sp = 0;
  226. pos = bp;
  227. scanNumber();
  228. return;
  229. }
  230. } else if (expect == JSONToken.LBRACE) {
  231. if (ch == '{') {
  232. token = JSONToken.LBRACE;
  233. ch = buf[++bp];
  234. return;
  235. }
  236. if (ch == '[') {
  237. token = JSONToken.LBRACKET;
  238. ch = buf[++bp];
  239. return;
  240. }
  241. } else if (expect == JSONToken.LBRACKET) {
  242. if (ch == '[') {
  243. token = JSONToken.LBRACKET;
  244. ch = buf[++bp];
  245. return;
  246. }
  247. if (ch == '{') {
  248. token = JSONToken.LBRACE;
  249. ch = buf[++bp];
  250. return;
  251. }
  252. }
  253. if (isWhitespace(ch)) {
  254. ch = buf[++bp];
  255. continue;
  256. }
  257. nextToken();
  258. break;
  259. }
  260. }
  261. public final void incrementBufferPosition() {
  262. ch = buf[++bp];
  263. }
  264. public final void resetStringPosition() {
  265. this.sp = 0;
  266. }
  267. public void nextToken(int expect) {
  268. for (;;) {
  269. switch (expect) {
  270. case JSONToken.LBRACE:
  271. if (ch == '{') {
  272. token = JSONToken.LBRACE;
  273. ch = buf[++bp];
  274. return;
  275. }
  276. if (ch == '[') {
  277. token = JSONToken.LBRACKET;
  278. ch = buf[++bp];
  279. return;
  280. }
  281. break;
  282. case JSONToken.COMMA:
  283. if (ch == ',') {
  284. token = JSONToken.COMMA;
  285. ch = buf[++bp];
  286. return;
  287. }
  288. if (ch == '}') {
  289. token = JSONToken.RBRACE;
  290. ch = buf[++bp];
  291. return;
  292. }
  293. if (ch == ']') {
  294. token = JSONToken.RBRACKET;
  295. ch = buf[++bp];
  296. return;
  297. }
  298. if (ch == EOI) {
  299. token = JSONToken.EOF;
  300. return;
  301. }
  302. break;
  303. case JSONToken.LITERAL_INT:
  304. if (ch >= '0' && ch <= '9') {
  305. sp = 0;
  306. pos = bp;
  307. scanNumber();
  308. return;
  309. }
  310. if (ch == '"') {
  311. sp = 0;
  312. pos = bp;
  313. scanString();
  314. return;
  315. }
  316. if (ch == '[') {
  317. token = JSONToken.LBRACKET;
  318. ch = buf[++bp];
  319. return;
  320. }
  321. if (ch == '{') {
  322. token = JSONToken.LBRACE;
  323. ch = buf[++bp];
  324. return;
  325. }
  326. break;
  327. case JSONToken.LITERAL_STRING:
  328. if (ch == '"') {
  329. sp = 0;
  330. pos = bp;
  331. scanString();
  332. return;
  333. }
  334. if (ch >= '0' && ch <= '9') {
  335. sp = 0;
  336. pos = bp;
  337. scanNumber();
  338. return;
  339. }
  340. if (ch == '[') {
  341. token = JSONToken.LBRACKET;
  342. ch = buf[++bp];
  343. return;
  344. }
  345. if (ch == '{') {
  346. token = JSONToken.LBRACE;
  347. ch = buf[++bp];
  348. return;
  349. }
  350. break;
  351. case JSONToken.LBRACKET:
  352. if (ch == '[') {
  353. token = JSONToken.LBRACKET;
  354. ch = buf[++bp];
  355. return;
  356. }
  357. if (ch == '{') {
  358. token = JSONToken.LBRACE;
  359. ch = buf[++bp];
  360. return;
  361. }
  362. break;
  363. case JSONToken.RBRACKET:
  364. if (ch == ']') {
  365. token = JSONToken.RBRACKET;
  366. ch = buf[++bp];
  367. return;
  368. }
  369. case JSONToken.EOF:
  370. if (ch == EOI) {
  371. token = JSONToken.EOF;
  372. return;
  373. }
  374. break;
  375. default:
  376. break;
  377. }
  378. if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
  379. ch = buf[++bp];
  380. continue;
  381. }
  382. nextToken();
  383. break;
  384. }
  385. }
  386. public final void nextToken() {
  387. sp = 0;
  388. for (;;) {
  389. pos = bp;
  390. if (ch == '"') {
  391. scanString();
  392. return;
  393. }
  394. if (ch == ',') {
  395. ch = buf[++bp];
  396. token = COMMA;
  397. return;
  398. }
  399. if (ch >= '0' && ch <= '9') {
  400. scanNumber();
  401. return;
  402. }
  403. if (ch == '-') {
  404. scanNumber();
  405. return;
  406. }
  407. switch (ch) {
  408. case '\'':
  409. if (!isEnabled(Feature.AllowSingleQuotes)) {
  410. throw new JSONException("Feature.AllowSingleQuotes is false");
  411. }
  412. scanStringSingleQuote();
  413. return;
  414. case ' ':
  415. case '\t':
  416. case '\b':
  417. case '\f':
  418. case '\n':
  419. case '\r':
  420. ch = buf[++bp];
  421. break;
  422. case 't': // true
  423. scanTrue();
  424. return;
  425. case 'T': // true
  426. scanTreeSet();
  427. return;
  428. case 'S': // set
  429. scanSet();
  430. return;
  431. case 'f': // false
  432. scanFalse();
  433. return;
  434. case 'n': // new,null
  435. scanNullOrNew();
  436. return;
  437. case 'D': // Date
  438. scanIdent();
  439. return;
  440. case '(':
  441. ch = buf[++bp];
  442. token = LPAREN;
  443. return;
  444. case ')':
  445. ch = buf[++bp];
  446. token = RPAREN;
  447. return;
  448. case '[':
  449. ch = buf[++bp];
  450. token = LBRACKET;
  451. return;
  452. case ']':
  453. ch = buf[++bp];
  454. token = RBRACKET;
  455. return;
  456. case '{':
  457. ch = buf[++bp];
  458. token = LBRACE;
  459. return;
  460. case '}':
  461. ch = buf[++bp];
  462. token = RBRACE;
  463. return;
  464. case ':':
  465. ch = buf[++bp];
  466. token = COLON;
  467. return;
  468. default:
  469. if (bp == buflen || ch == EOI && bp + 1 == buflen) { // JLS
  470. if (token == EOF) {
  471. throw new JSONException("EOF error");
  472. }
  473. token = EOF;
  474. pos = bp = eofPos;
  475. } else {
  476. lexError("illegal.char", String.valueOf((int) ch));
  477. ch = buf[++bp];
  478. }
  479. return;
  480. }
  481. }
  482. }
  483. boolean hasSpecial;
  484. public final void scanStringSingleQuote() {
  485. np = bp;
  486. hasSpecial = false;
  487. char ch;
  488. for (;;) {
  489. ch = buf[++bp];
  490. if (ch == '\'') {
  491. break;
  492. }
  493. if (ch == EOI) {
  494. throw new JSONException("unclosed single-quote string");
  495. }
  496. if (ch == '\\') {
  497. if (!hasSpecial) {
  498. hasSpecial = true;
  499. if (sp > sbuf.length) {
  500. char[] newsbuf = new char[sp * 2];
  501. System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
  502. sbuf = newsbuf;
  503. }
  504. System.arraycopy(buf, np + 1, sbuf, 0, sp);
  505. }
  506. ch = buf[++bp];
  507. switch (ch) {
  508. case '"':
  509. putChar('"');
  510. break;
  511. case '\\':
  512. putChar('\\');
  513. break;
  514. case '/':
  515. putChar('/');
  516. break;
  517. case '\'':
  518. putChar('\'');
  519. break;
  520. case 'b':
  521. putChar('\b');
  522. break;
  523. case 'f':
  524. case 'F':
  525. putChar('\f');
  526. break;
  527. case 'n':
  528. putChar('\n');
  529. break;
  530. case 'r':
  531. putChar('\r');
  532. break;
  533. case 't':
  534. putChar('\t');
  535. break;
  536. case 'x':
  537. char x1 = ch = buf[++bp];
  538. char x2 = ch = buf[++bp];
  539. int x_val = digits[x1] * 16 + digits[x2];
  540. char x_char = (char) x_val;
  541. putChar(x_char);
  542. break;
  543. case 'u':
  544. char c1 = ch = buf[++bp];
  545. char c2 = ch = buf[++bp];
  546. char c3 = ch = buf[++bp];
  547. char c4 = ch = buf[++bp];
  548. int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16);
  549. putChar((char) val);
  550. break;
  551. default:
  552. this.ch = ch;
  553. throw new JSONException("unclosed single-quote string");
  554. }
  555. continue;
  556. }
  557. if (!hasSpecial) {
  558. sp++;
  559. continue;
  560. }
  561. if (sp == sbuf.length) {
  562. putChar(ch);
  563. } else {
  564. sbuf[sp++] = ch;
  565. }
  566. }
  567. token = LITERAL_STRING;
  568. this.ch = buf[++bp];
  569. }
  570. public final void scanString() {
  571. np = bp;
  572. hasSpecial = false;
  573. char ch;
  574. for (;;) {
  575. ch = buf[++bp];
  576. if (ch == '\"') {
  577. break;
  578. }
  579. if (ch == '\\') {
  580. if (!hasSpecial) {
  581. hasSpecial = true;
  582. if (sp >= sbuf.length) {
  583. int newCapcity = sbuf.length * 2;
  584. if (sp > newCapcity) {
  585. newCapcity = sp;
  586. }
  587. char[] newsbuf = new char[newCapcity];
  588. System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
  589. sbuf = newsbuf;
  590. }
  591. System.arraycopy(buf, np + 1, sbuf, 0, sp);
  592. }
  593. ch = buf[++bp];
  594. switch (ch) {
  595. case '"':
  596. putChar('"');
  597. break;
  598. case '\\':
  599. putChar('\\');
  600. break;
  601. case '/':
  602. putChar('/');
  603. break;
  604. case 'b':
  605. putChar('\b');
  606. break;
  607. case 'f':
  608. case 'F':
  609. putChar('\f');
  610. break;
  611. case 'n':
  612. putChar('\n');
  613. break;
  614. case 'r':
  615. putChar('\r');
  616. break;
  617. case 't':
  618. putChar('\t');
  619. break;
  620. case 'x':
  621. char x1 = ch = buf[++bp];
  622. char x2 = ch = buf[++bp];
  623. int x_val = digits[x1] * 16 + digits[x2];
  624. char x_char = (char) x_val;
  625. putChar(x_char);
  626. break;
  627. case 'u':
  628. char u1 = ch = buf[++bp];
  629. char u2 = ch = buf[++bp];
  630. char u3 = ch = buf[++bp];
  631. char u4 = ch = buf[++bp];
  632. int val = Integer.parseInt(new String(new char[] { u1, u2, u3, u4 }), 16);
  633. putChar((char) val);
  634. break;
  635. default:
  636. this.ch = ch;
  637. throw new JSONException("unclosed string : " + ch);
  638. }
  639. continue;
  640. }
  641. if (!hasSpecial) {
  642. sp++;
  643. continue;
  644. }
  645. if (sp == sbuf.length) {
  646. putChar(ch);
  647. } else {
  648. sbuf[sp++] = ch;
  649. }
  650. }
  651. token = LITERAL_STRING;
  652. this.ch = buf[++bp];
  653. }
  654. public final String scanSymbolUnQuoted(final SymbolTable symbolTable) {
  655. final boolean[] firstIdentifierFlags = CharTypes.firstIdentifierFlags;
  656. final char first = ch;
  657. final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first];
  658. if (!firstFlag) {
  659. throw new JSONException("illegal identifier : " + ch);
  660. }
  661. final boolean[] identifierFlags = CharTypes.identifierFlags;
  662. int hash = first;
  663. np = bp;
  664. sp = 1;
  665. char ch;
  666. for (;;) {
  667. ch = buf[++bp];
  668. if (ch < identifierFlags.length) {
  669. if (!identifierFlags[ch]) {
  670. break;
  671. }
  672. }
  673. hash = 31 * hash + ch;
  674. sp++;
  675. continue;
  676. }
  677. this.ch = buf[bp];
  678. token = JSONToken.IDENTIFIER;
  679. final int NULL_HASH = 3392903;
  680. if (sp == 4 && hash == NULL_HASH && buf[np] == 'n' && buf[np + 1] == 'u' && buf[np + 2] == 'l'
  681. && buf[np + 3] == 'l') {
  682. return null;
  683. }
  684. return symbolTable.addSymbol(buf, np, sp, hash);
  685. }
  686. public final static int NOT_MATCH = -1;
  687. public final static int NOT_MATCH_NAME = -2;
  688. public final static int UNKOWN = 0;
  689. public final static int OBJECT = 1;
  690. public final static int ARRAY = 2;
  691. public final static int VALUE = 3;
  692. public final static int END = 4;
  693. private final static char[] typeFieldName = "\"@type\":\"".toCharArray();
  694. public int scanType(String type) {
  695. matchStat = UNKOWN;
  696. final int fieldNameLength = typeFieldName.length;
  697. for (int i = 0; i < fieldNameLength; ++i) {
  698. if (typeFieldName[i] != buf[bp + i]) {
  699. return NOT_MATCH_NAME;
  700. }
  701. }
  702. int bp = this.bp + fieldNameLength;
  703. final int typeLength = type.length();
  704. for (int i = 0; i < typeLength; ++i) {
  705. if (type.charAt(i) != buf[bp + i]) {
  706. return NOT_MATCH;
  707. }
  708. }
  709. bp += typeLength;
  710. if (buf[bp] != '"') {
  711. return NOT_MATCH;
  712. }
  713. this.ch = buf[++bp];
  714. if (ch == ',') {
  715. this.ch = buf[++bp];
  716. this.bp = bp;
  717. token = JSONToken.COMMA;
  718. return VALUE;
  719. } else if (ch == '}') {
  720. ch = buf[++bp];
  721. if (ch == ',') {
  722. token = JSONToken.COMMA;
  723. this.ch = buf[++bp];
  724. } else if (ch == ']') {
  725. token = JSONToken.RBRACKET;
  726. this.ch = buf[++bp];
  727. } else if (ch == '}') {
  728. token = JSONToken.RBRACE;
  729. this.ch = buf[++bp];
  730. } else if (ch == EOI) {
  731. token = JSONToken.EOF;
  732. } else {
  733. return NOT_MATCH;
  734. }
  735. matchStat = END;
  736. }
  737. this.bp = bp;
  738. return matchStat;
  739. }
  740. public boolean matchField(char[] fieldName) {
  741. final int fieldNameLength = fieldName.length;
  742. for (int i = 0; i < fieldNameLength; ++i) {
  743. if (fieldName[i] != buf[bp + i]) {
  744. return false;
  745. }
  746. }
  747. bp = bp + fieldNameLength;
  748. ch = buf[bp];
  749. if (ch == '{') {
  750. ch = buf[++bp];
  751. token = JSONToken.LBRACE;
  752. } else if (ch == '[') {
  753. ch = buf[++bp];
  754. token = JSONToken.LBRACKET;
  755. } else {
  756. nextToken();
  757. }
  758. return true;
  759. }
  760. public int matchStat = UNKOWN;
  761. public String scanFieldString(char[] fieldName) {
  762. matchStat = UNKOWN;
  763. final int fieldNameLength = fieldName.length;
  764. for (int i = 0; i < fieldNameLength; ++i) {
  765. if (fieldName[i] != buf[bp + i]) {
  766. matchStat = NOT_MATCH_NAME;
  767. return stringDefaultValue();
  768. }
  769. }
  770. int index = bp + fieldNameLength;
  771. char ch = buf[index++];
  772. if (ch != '"') {
  773. matchStat = NOT_MATCH;
  774. return stringDefaultValue();
  775. }
  776. String strVal;
  777. int start = index;
  778. for (;;) {
  779. ch = buf[index++];
  780. if (ch == '\"') {
  781. bp = index;
  782. this.ch = ch = buf[bp];
  783. strVal = new String(buf, start, index - start - 1);
  784. break;
  785. }
  786. if (ch == '\\') {
  787. matchStat = NOT_MATCH;
  788. return stringDefaultValue();
  789. }
  790. }
  791. if (ch == ',') {
  792. this.ch = buf[++bp];
  793. matchStat = VALUE;
  794. return strVal;
  795. } else if (ch == '}') {
  796. ch = buf[++bp];
  797. if (ch == ',') {
  798. token = JSONToken.COMMA;
  799. this.ch = buf[++bp];
  800. } else if (ch == ']') {
  801. token = JSONToken.RBRACKET;
  802. this.ch = buf[++bp];
  803. } else if (ch == '}') {
  804. token = JSONToken.RBRACE;
  805. this.ch = buf[++bp];
  806. } else if (ch == EOI) {
  807. token = JSONToken.EOF;
  808. } else {
  809. matchStat = NOT_MATCH;
  810. return stringDefaultValue();
  811. }
  812. matchStat = END;
  813. } else {
  814. matchStat = NOT_MATCH;
  815. return stringDefaultValue();
  816. }
  817. return strVal;
  818. }
  819. public String stringDefaultValue() {
  820. if (this.isEnabled(Feature.InitStringFieldAsEmpty)) {
  821. return "";
  822. }
  823. return null;
  824. }
  825. public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) {
  826. matchStat = UNKOWN;
  827. final int fieldNameLength = fieldName.length;
  828. for (int i = 0; i < fieldNameLength; ++i) {
  829. if (fieldName[i] != buf[bp + i]) {
  830. matchStat = NOT_MATCH_NAME;
  831. return null;
  832. }
  833. }
  834. int index = bp + fieldNameLength;
  835. char ch = buf[index++];
  836. if (ch != '"') {
  837. matchStat = NOT_MATCH;
  838. return null;
  839. }
  840. String strVal;
  841. int start = index;
  842. int hash = 0;
  843. for (;;) {
  844. ch = buf[index++];
  845. if (ch == '\"') {
  846. bp = index;
  847. this.ch = ch = buf[bp];
  848. strVal = symbolTable.addSymbol(buf, start, index - start - 1, hash);
  849. break;
  850. }
  851. hash = 31 * hash + ch;
  852. if (ch == '\\') {
  853. matchStat = NOT_MATCH;
  854. return null;
  855. }
  856. }
  857. if (ch == ',') {
  858. this.ch = buf[++bp];
  859. matchStat = VALUE;
  860. return strVal;
  861. } else if (ch == '}') {
  862. ch = buf[++bp];
  863. if (ch == ',') {
  864. token = JSONToken.COMMA;
  865. this.ch = buf[++bp];
  866. } else if (ch == ']') {
  867. token = JSONToken.RBRACKET;
  868. this.ch = buf[++bp];
  869. } else if (ch == '}') {
  870. token = JSONToken.RBRACE;
  871. this.ch = buf[++bp];
  872. } else if (ch == EOI) {
  873. token = JSONToken.EOF;
  874. } else {
  875. matchStat = NOT_MATCH;
  876. return null;
  877. }
  878. matchStat = END;
  879. } else {
  880. matchStat = NOT_MATCH;
  881. return null;
  882. }
  883. return strVal;
  884. }
  885. public ArrayList<String> scanFieldStringArray(char[] fieldName) {
  886. return (ArrayList<String>) scanFieldStringArray(fieldName, null);
  887. }
  888. @SuppressWarnings("unchecked")
  889. public Collection<String> scanFieldStringArray(char[] fieldName, Class<?> type) {
  890. matchStat = UNKOWN;
  891. Collection<String> list;
  892. if (type.isAssignableFrom(HashSet.class)) {
  893. list = new HashSet<String>();
  894. } else if (type.isAssignableFrom(ArrayList.class)) {
  895. list = new ArrayList<String>();
  896. } else {
  897. try {
  898. list = (Collection<String>) type.newInstance();
  899. } catch (Exception e) {
  900. throw new JSONException(e.getMessage(), e);
  901. }
  902. }
  903. final int fieldNameLength = fieldName.length;
  904. for (int i = 0; i < fieldNameLength; ++i) {
  905. if (fieldName[i] != buf[bp + i]) {
  906. matchStat = NOT_MATCH_NAME;
  907. return null;
  908. }
  909. }
  910. int index = bp + fieldNameLength;
  911. char ch = buf[index++];
  912. if (ch != '[') {
  913. matchStat = NOT_MATCH;
  914. return null;
  915. }
  916. ch = buf[index++];
  917. for (;;) {
  918. if (ch != '"') {
  919. matchStat = NOT_MATCH;
  920. return null;
  921. }
  922. String strVal;
  923. int start = index;
  924. for (;;) {
  925. ch = buf[index++];
  926. if (ch == '\"') {
  927. strVal = new String(buf, start, index - start - 1);
  928. list.add(strVal);
  929. ch = buf[index++];
  930. break;
  931. }
  932. if (ch == '\\') {
  933. matchStat = NOT_MATCH;
  934. return null;
  935. }
  936. }
  937. if (ch == ',') {
  938. ch = buf[index++];
  939. continue;
  940. }
  941. if (ch == ']') {
  942. ch = buf[index++];
  943. break;
  944. }
  945. matchStat = NOT_MATCH;
  946. return null;
  947. }
  948. bp = index;
  949. if (ch == ',') {
  950. this.ch = buf[bp];
  951. matchStat = VALUE;
  952. return list;
  953. } else if (ch == '}') {
  954. ch = buf[bp];
  955. if (ch == ',') {
  956. token = JSONToken.COMMA;
  957. this.ch = buf[++bp];
  958. } else if (ch == ']') {
  959. token = JSONToken.RBRACKET;
  960. this.ch = buf[++bp];
  961. } else if (ch == '}') {
  962. token = JSONToken.RBRACE;
  963. this.ch = buf[++bp];
  964. } else if (ch == EOI) {
  965. token = JSONToken.EOF;
  966. this.ch = ch;
  967. } else {
  968. matchStat = NOT_MATCH;
  969. return null;
  970. }
  971. matchStat = END;
  972. } else {
  973. matchStat = NOT_MATCH;
  974. return null;
  975. }
  976. return list;
  977. }
  978. public int scanFieldInt(char[] fieldName) {
  979. matchStat = UNKOWN;
  980. final int fieldNameLength = fieldName.length;
  981. for (int i = 0; i < fieldNameLength; ++i) {
  982. if (fieldName[i] != buf[bp + i]) {
  983. matchStat = NOT_MATCH_NAME;
  984. return 0;
  985. }
  986. }
  987. int index = bp + fieldNameLength;
  988. char ch = buf[index++];
  989. int value;
  990. if (ch >= '0' && ch <= '9') {
  991. value = digits[ch];
  992. for (;;) {
  993. ch = buf[index++];
  994. if (ch >= '0' && ch <= '9') {
  995. value = value * 10 + digits[ch];
  996. } else if (ch == '.') {
  997. matchStat = NOT_MATCH;
  998. return 0;
  999. } else {
  1000. bp = index - 1;
  1001. break;
  1002. }
  1003. }
  1004. if (value < 0) {
  1005. matchStat = NOT_MATCH;
  1006. return 0;
  1007. }
  1008. } else {
  1009. matchStat = NOT_MATCH;
  1010. return 0;
  1011. }
  1012. if (ch == ',') {
  1013. ch = buf[++bp];
  1014. matchStat = VALUE;
  1015. token = JSONToken.COMMA;
  1016. return value;
  1017. }
  1018. if (ch == '}') {
  1019. ch = buf[++bp];
  1020. if (ch == ',') {
  1021. token = JSONToken.COMMA;
  1022. this.ch = buf[++bp];
  1023. } else if (ch == ']') {
  1024. token = JSONToken.RBRACKET;
  1025. this.ch = buf[++bp];
  1026. } else if (ch == '}') {
  1027. token = JSONToken.RBRACE;
  1028. this.ch = buf[++bp];
  1029. } else if (ch == EOI) {
  1030. token = JSONToken.EOF;
  1031. } else {
  1032. matchStat = NOT_MATCH;
  1033. return 0;
  1034. }
  1035. matchStat = END;
  1036. }
  1037. return value;
  1038. }
  1039. public boolean scanFieldBoolean(char[] fieldName) {
  1040. matchStat = UNKOWN;
  1041. final int fieldNameLength = fieldName.length;
  1042. for (int i = 0; i < fieldNameLength; ++i) {
  1043. if (fieldName[i] != buf[bp + i]) {
  1044. matchStat = NOT_MATCH_NAME;
  1045. return false;
  1046. }
  1047. }
  1048. int index = bp + fieldNameLength;
  1049. char ch = buf[index++];
  1050. boolean value;
  1051. if (ch == 't') {
  1052. if (buf[index++] != 'r') {
  1053. matchStat = NOT_MATCH;
  1054. return false;
  1055. }
  1056. if (buf[index++] != 'u') {
  1057. matchStat = NOT_MATCH;
  1058. return false;
  1059. }
  1060. if (buf[index++] != 'e') {
  1061. matchStat = NOT_MATCH;
  1062. return false;
  1063. }
  1064. bp = index;
  1065. ch = buf[bp];
  1066. value = true;
  1067. } else if (ch == 'f') {
  1068. if (buf[index++] != 'a') {
  1069. matchStat = NOT_MATCH;
  1070. return false;
  1071. }
  1072. if (buf[index++] != 'l') {
  1073. matchStat = NOT_MATCH;
  1074. return false;
  1075. }
  1076. if (buf[index++] != 's') {
  1077. matchStat = NOT_MATCH;
  1078. return false;
  1079. }
  1080. if (buf[index++] != 'e') {
  1081. matchStat = NOT_MATCH;
  1082. return false;
  1083. }
  1084. bp = index;
  1085. ch = buf[bp];
  1086. value = false;
  1087. } else {
  1088. matchStat = NOT_MATCH;
  1089. return false;
  1090. }
  1091. if (ch == ',') {
  1092. ch = buf[++bp];
  1093. matchStat = VALUE;
  1094. token = JSONToken.COMMA;
  1095. } else if (ch == '}') {
  1096. ch = buf[++bp];
  1097. if (ch == ',') {
  1098. token = JSONToken.COMMA;
  1099. this.ch = buf[++bp];
  1100. } else if (ch == ']') {
  1101. token = JSONToken.RBRACKET;
  1102. this.ch = buf[++bp];
  1103. } else if (ch == '}') {
  1104. token = JSONToken.RBRACE;
  1105. this.ch = buf[++bp];
  1106. } else if (ch == EOI) {
  1107. token = JSONToken.EOF;
  1108. } else {
  1109. matchStat = NOT_MATCH;
  1110. return false;
  1111. }
  1112. matchStat = END;
  1113. } else {
  1114. matchStat = NOT_MATCH;
  1115. return false;
  1116. }
  1117. return value;
  1118. }
  1119. public long scanFieldLong(char[] fieldName) {
  1120. matchStat = UNKOWN;
  1121. final int fieldNameLength = fieldName.length;
  1122. for (int i = 0; i < fieldNameLength; ++i) {
  1123. if (fieldName[i] != buf[bp + i]) {
  1124. matchStat = NOT_MATCH_NAME;
  1125. return 0;
  1126. }
  1127. }
  1128. int index = bp + fieldNameLength;
  1129. char ch = buf[index++];
  1130. long value;
  1131. if (ch >= '0' && ch <= '9') {
  1132. value = digits[ch];
  1133. for (;;) {
  1134. ch = buf[index++];
  1135. if (ch >= '0' && ch <= '9') {
  1136. value = value * 10 + digits[ch];
  1137. } else if (ch == '.') {
  1138. token = NOT_MATCH;
  1139. return 0;
  1140. } else {
  1141. bp = index - 1;
  1142. break;
  1143. }
  1144. }
  1145. if (value < 0) {
  1146. matchStat = NOT_MATCH;
  1147. return 0;
  1148. }
  1149. } else {
  1150. matchStat = NOT_MATCH;
  1151. return 0;
  1152. }
  1153. if (ch == ',') {
  1154. ch = buf[++bp];
  1155. matchStat = VALUE;
  1156. token = JSONToken.COMMA;
  1157. return value;
  1158. } else if (ch == '}') {
  1159. ch = buf[++bp];
  1160. if (ch == ',') {
  1161. token = JSONToken.COMMA;
  1162. this.ch = buf[++bp];
  1163. } else if (ch == ']') {
  1164. token = JSONToken.RBRACKET;
  1165. this.ch = buf[++bp];
  1166. } else if (ch == '}') {
  1167. token = JSONToken.RBRACE;
  1168. this.ch = buf[++bp];
  1169. } else if (ch == EOI) {
  1170. token = JSONToken.EOF;
  1171. } else {
  1172. matchStat = NOT_MATCH;
  1173. return 0;
  1174. }
  1175. matchStat = END;
  1176. } else {
  1177. matchStat = NOT_MATCH;
  1178. return 0;
  1179. }
  1180. return value;
  1181. }
  1182. public float scanFieldFloat(char[] fieldName) {
  1183. matchStat = UNKOWN;
  1184. final int fieldNameLength = fieldName.length;
  1185. for (int i = 0; i < fieldNameLength; ++i) {
  1186. if (fieldName[i] != buf[bp + i]) {
  1187. matchStat = NOT_MATCH_NAME;
  1188. return 0;
  1189. }
  1190. }
  1191. int index = bp + fieldNameLength;
  1192. char ch = buf[index++];
  1193. float value;
  1194. if (ch >= '0' && ch <= '9') {
  1195. int start = index - 1;
  1196. for (;;) {
  1197. ch = buf[index++];
  1198. if (ch >= '0' && ch <= '9') {
  1199. continue;
  1200. } else {
  1201. break;
  1202. }
  1203. }
  1204. if (ch == '.') {
  1205. ch = buf[index++];
  1206. if (ch >= '0' && ch <= '9') {
  1207. for (;;) {
  1208. ch = buf[index++];
  1209. if (ch >= '0' && ch <= '9') {
  1210. continue;
  1211. } else {
  1212. break;
  1213. }
  1214. }
  1215. } else {
  1216. matchStat = NOT_MATCH;
  1217. return 0;
  1218. }
  1219. }
  1220. bp = index - 1;
  1221. String text = new String(buf, start, index - start - 1);
  1222. value = Float.parseFloat(text);
  1223. } else {
  1224. matchStat = NOT_MATCH;
  1225. return 0;
  1226. }
  1227. if (ch == ',') {
  1228. ch = buf[++bp];
  1229. matchStat = VALUE;
  1230. token = JSONToken.COMMA;
  1231. return value;
  1232. } else if (ch == '}') {
  1233. ch = buf[++bp];
  1234. if (ch == ',') {
  1235. token = JSONToken.COMMA;
  1236. this.ch = buf[++bp];
  1237. } else if (ch == ']') {
  1238. token = JSONToken.RBRACKET;
  1239. this.ch = buf[++bp];
  1240. } else if (ch == '}') {
  1241. token = JSONToken.RBRACE;
  1242. this.ch = buf[++bp];
  1243. } else if (ch == EOI) {
  1244. token = JSONToken.EOF;
  1245. } else {
  1246. matchStat = NOT_MATCH;
  1247. return 0;
  1248. }
  1249. matchStat = END;
  1250. } else {
  1251. matchStat = NOT_MATCH;
  1252. return 0;
  1253. }
  1254. return value;
  1255. }
  1256. public byte[] bytesValue() {
  1257. return Base64.decodeFast(buf, np + 1, sp);
  1258. }
  1259. public double scanFieldDouble(char[] fieldName) {
  1260. matchStat = UNKOWN;
  1261. final int fieldNameLength = fieldName.length;
  1262. for (int i = 0; i < fieldNameLength; ++i) {
  1263. if (fieldName[i] != buf[bp + i]) {
  1264. matchStat = NOT_MATCH_NAME;
  1265. return 0;
  1266. }
  1267. }
  1268. int index = bp + fieldNameLength;
  1269. char ch = buf[index++];
  1270. double value;
  1271. if (ch >= '0' && ch <= '9') {
  1272. int start = index - 1;
  1273. for (;;) {
  1274. ch = buf[index++];
  1275. if (ch >= '0' && ch <= '9') {
  1276. continue;
  1277. } else {
  1278. break;
  1279. }
  1280. }
  1281. if (ch == '.') {
  1282. ch = buf[index++];
  1283. if (ch >= '0' && ch <= '9') {
  1284. for (;;) {
  1285. ch = buf[index++];
  1286. if (ch >= '0' && ch <= '9') {
  1287. continue;
  1288. } else {
  1289. break;
  1290. }
  1291. }
  1292. } else {
  1293. matchStat = NOT_MATCH;
  1294. return 0;
  1295. }
  1296. }
  1297. bp = index - 1;
  1298. String text = new String(buf, start, index - start - 1);
  1299. value = Double.parseDouble(text);
  1300. } else {
  1301. matchStat = NOT_MATCH;
  1302. return 0;
  1303. }
  1304. if (ch == ',') {
  1305. ch = buf[++bp];
  1306. matchStat = VALUE;
  1307. token = JSONToken.COMMA;
  1308. } else if (ch == '}') {
  1309. ch = buf[++bp];
  1310. if (ch == ',') {
  1311. token = JSONToken.COMMA;
  1312. this.ch = buf[++bp];
  1313. } else if (ch == ']') {
  1314. token = JSONToken.RBRACKET;
  1315. this.ch = buf[++bp];
  1316. } else if (ch == '}') {
  1317. token = JSONToken.RBRACE;
  1318. this.ch = buf[++bp];
  1319. } else if (ch == EOI) {
  1320. token = JSONToken.EOF;
  1321. } else {
  1322. matchStat = NOT_MATCH;
  1323. return 0;
  1324. }
  1325. matchStat = END;
  1326. } else {
  1327. matchStat = NOT_MATCH;
  1328. return 0;
  1329. }
  1330. return value;
  1331. }
  1332. // public int scanField2(char[] fieldName, Object object, FieldDeserializer fieldDeserializer) {
  1333. // return NOT_MATCH;
  1334. // }
  1335. public String scanSymbol(final SymbolTable symbolTable) {
  1336. skipWhitespace();
  1337. if (ch == '"') {
  1338. return scanSymbol(symbolTable, '"');
  1339. }
  1340. if (ch == '\'') {
  1341. if (!isEnabled(Feature.AllowSingleQuotes)) {
  1342. throw new JSONException("syntax error");
  1343. }
  1344. return scanSymbol(symbolTable, '\'');
  1345. }
  1346. if (ch == '}') {
  1347. ch = buf[++bp];
  1348. token = JSONToken.RBRACE;
  1349. return null;
  1350. }
  1351. if (ch == ',') {
  1352. ch = buf[++bp];
  1353. token = JSONToken.COMMA;
  1354. return null;
  1355. }
  1356. if (ch == EOI) {
  1357. token = JSONToken.EOF;
  1358. return null;
  1359. }
  1360. if (!isEnabled(Feature.AllowUnQuotedFieldNames)) {
  1361. throw new JSONException("syntax error");
  1362. }
  1363. return scanSymbolUnQuoted(symbolTable);
  1364. }
  1365. public final String scanSymbol(final SymbolTable symbolTable, final char quote) {
  1366. int hash = 0;
  1367. np = bp;
  1368. sp = 0;
  1369. boolean hasSpecial = false;
  1370. char ch;
  1371. for (;;) {
  1372. ch = buf[++bp];
  1373. if (ch == quote) {
  1374. break;
  1375. }
  1376. if (ch == EOI) {
  1377. throw new JSONException("unclosed.str");
  1378. }
  1379. if (ch == '\\') {
  1380. if (!hasSpecial) {
  1381. hasSpecial = true;
  1382. if (sp >= sbuf.length) {
  1383. int newCapcity = sbuf.length * 2;
  1384. if (sp > newCapcity) {
  1385. newCapcity = sp;
  1386. }
  1387. char[] newsbuf = new char[newCapcity];
  1388. System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
  1389. sbuf = newsbuf;
  1390. }
  1391. System.arraycopy(buf, np + 1, sbuf, 0, sp);
  1392. }
  1393. ch = buf[++bp];
  1394. switch (ch) {
  1395. case '"':
  1396. hash = 31 * hash + (int) '"';
  1397. putChar('"');
  1398. break;
  1399. case '\\':
  1400. hash = 31 * hash + (int) '\\';
  1401. putChar('\\');
  1402. break;
  1403. case '/':
  1404. hash = 31 * hash + (int) '/';
  1405. putChar('/');
  1406. break;
  1407. case 'b':
  1408. hash = 31 * hash + (int) '\b';
  1409. putChar('\b');
  1410. break;
  1411. case 'f':
  1412. case 'F':
  1413. hash = 31 * hash + (int) '\f';
  1414. putChar('\f');
  1415. break;
  1416. case 'n':
  1417. hash = 31 * hash + (int) '\n';
  1418. putChar('\n');
  1419. break;
  1420. case 'r':
  1421. hash = 31 * hash + (int) '\r';
  1422. putChar('\r');
  1423. break;
  1424. case 't':
  1425. hash = 31 * hash + (int) '\t';
  1426. putChar('\t');
  1427. break;
  1428. case 'u':
  1429. char c1 = ch = buf[++bp];
  1430. char c2 = ch = buf[++bp];
  1431. char c3 = ch = buf[++bp];
  1432. char c4 = ch = buf[++bp];
  1433. int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16);
  1434. hash = 31 * hash + val;
  1435. putChar((char) val);
  1436. break;
  1437. default:
  1438. this.ch = ch;
  1439. throw new JSONException("unclosed.str.lit");
  1440. }
  1441. continue;
  1442. }
  1443. hash = 31 * hash + ch;
  1444. if (!hasSpecial) {
  1445. sp++;
  1446. continue;
  1447. }
  1448. if (sp == sbuf.length) {
  1449. putChar(ch);
  1450. } else {
  1451. sbuf[sp++] = ch;
  1452. }
  1453. }
  1454. token = LITERAL_STRING;
  1455. this.ch = buf[++bp];
  1456. if (!hasSpecial) {
  1457. return symbolTable.addSymbol(buf, np + 1, sp, hash);
  1458. } else {
  1459. return symbolTable.addSymbol(sbuf, 0, sp, hash);
  1460. }
  1461. }
  1462. public void scanTrue() {
  1463. if (buf[bp++] != 't') {
  1464. throw new JSONException("error parse true");
  1465. }
  1466. if (buf[bp++] != 'r') {
  1467. throw new JSONException("error parse true");
  1468. }
  1469. if (buf[bp++] != 'u') {
  1470. throw new JSONException("error parse true");
  1471. }
  1472. if (buf[bp++] != 'e') {
  1473. throw new JSONException("error parse true");
  1474. }
  1475. ch = buf[bp];
  1476. if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI
  1477. || ch == '\f' || ch == '\b') {
  1478. token = JSONToken.TRUE;
  1479. } else {
  1480. throw new JSONException("scan true error");
  1481. }
  1482. }
  1483. public void scanSet() {
  1484. if (buf[bp++] != 'S') {
  1485. throw new JSONException("error parse true");
  1486. }
  1487. if (buf[bp++] != 'e') {
  1488. throw new JSONException("error parse true");
  1489. }
  1490. if (buf[bp++] != 't') {
  1491. throw new JSONException("error parse true");
  1492. }
  1493. ch = buf[bp];
  1494. if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b' || ch == '[' || ch == '(') {
  1495. token = JSONToken.SET;
  1496. } else {
  1497. throw new JSONException("scan set error");
  1498. }
  1499. }
  1500. public void scanTreeSet() {
  1501. if (buf[bp++] != 'T') {
  1502. throw new JSONException("error parse true"