程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi的JSON庫 - DJSON- JSONTokener(上)(2)

Delphi的JSON庫 - DJSON- JSONTokener(上)(2)

編輯:Delphi

首先貼出Java源代碼:

 1package org.JSon;
 2
 3/**//*
 4Copyright (c) 2002 JSON.org
 5
 6Permission is hereby granted, free of charge, to any person obtaining a copy
 7of this software and associated documentation files (the "Software"), to deal
 8in the Software without restriction, including without limitation the rights
 9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copIEs of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copIEs or substantial portions of the Software.
15
16The Software shall be used for Good, not Evil.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25*/
26
27/** *//**
28 * A JSONTokener takes a source string and extracts characters and tokens from
29 * it. It is used by the JSONObject and JSONArray constructors to parse
30 * JSON source strings.
31 * @author JSON.org
32 * @version 2
33 */
34public class JSONTokener {
35
36  /** *//**
37   * The index of the next character.
38   */
39  private int myIndex;
40
41
42  /** *//**
43   * The source string being tokenized.
44   */
45  private String mySource;
46
47
48  /** *//**
49   * Construct a JSONTokener from a string.
50   *
51   * @param s   A source string.
52   */
53  public JSONTokener(String s) {
54    this.myIndex = 0;
55    this.mySource = s;
56  }
57
58
59  /** *//**
60   * Back up one character. This provides a sort of lookahead capability,
61   * so that you can test for a digit or letter before attempting to parse
62   * the next number or identifIEr.
63   */
64  public void back() {
65    if (this.myIndex > 0) {
66      this.myIndex -= 1;
67    }
68  }
69
70
71
72  /** *//**
73   * Get the hex value of a character (base16).
74   * @param c A character between '0' and '9' or between 'A' and 'F' or
75   * between 'a' and 'f'.
76   * @return An int between 0 and 15, or -1 if c was not a hex digit.
77   */
78  public static int dehexchar(char c) {
79    if (c >= '0' && c <= '9') {
80      return c - '0';
81    }
82    if (c >= 'A' && c <= 'F') {
83      return c - ('A' - 10);
84    }
85    if (c >= 'a' && c <= 'f') {
86      return c - ('a' - 10);
87    }
88    return -1;
89  }
90
91
92  /** *//**
93   * Determine if the source string still contains characters that next()
94   * can consume.
95   * @return true if not yet at the end of the source.
96   */
97  public boolean more() {
98    return this.myIndex < this.mySource.length();
99  }
100
101
102  /** *//**
103   * Get the next character in the source string.
104   *
105   * @return The next character, or 0 if past the end of the source string.
106   */
107  public char next() {
108    if (more()) {
109      char c = this.mySource.charAt(this.myIndex);
110      this.myIndex += 1;
111      return c;
112    }
113    return 0;
114  }
115
116
117  /** *//**
118   * Consume the next character, and check that it matches a specifIEd
119   * character.
120   * @param c The character to match.
121   * @return The character.
122   * @throws JSONException if the character does not match.
123   */
124  public char next(char c) throws JSONException {
125    char n = next();
126    if (n != c) {
127      throw syntaxError("Expected '" + c + "' and instead saw '" +
128          n + "'");
129    }
130    return n;
131  }
132
133
134  /** *//**
135   * Get the next n characters.
136   *
137   * @param n   The number of characters to take.
138   * @return   A string of n characters.
139   * @throws JSONException
140   *  Substring bounds error if there are not
141   *  n characters remaining in the source string.
142   */
143   public String next(int n) throws JSONException {
144     int i = this.myIndex;
145     int j = i + n;
146     if (j >= this.mySource.length()) {
147      throw syntaxError("Substring bounds error");
148     }
149     this.myIndex += n;
150     return this.mySource.substring(i, j);
151   }
152
153
154  /** *//**
155   * Get the next char in the string, skipping whitespace
156   * and comments (slashslash, slashstar, and hash).
157   * @throws JSONException
158   * @return A character, or 0 if there are no more characters.
159   */
160  public char nextClean() throws JSONException {
161    for (;;) {
162      char c = next();
163      if (c == '/') {
164        switch (next()) {
165        case '/':
166          do {
167            c = next();
168          } while (c != '\n' && c != '\r' && c != 0);
169          break;
170        case '*':
171          for (;;) {
172            c = next();
173            if (c == 0) {
174              throw syntaxError("Unclosed comment");
175            }
176            if (c == '*') {
177              if (next() == '/') {
178                break;
179              }
180              back();
181            }
182          }
183          break;
184        default:
185          back();
186          return '/';
187        }
188      } else if (c == '#') {
189        do {
190          c = next();
191        } while (c != '\n' && c != '\r' && c != 0);
192      } else if (c == 0 || c > ' ') {
193        return c;
194      }
195    }
196  }
197
198
199  /** *//**
200   * Return the characters up to the next close quote character.
201   * Backslash processing is done. The formal JSON format does not
202   * allow strings in single quotes, but an implementation is allowed to
203   * accept them.
204   * @param quote The quoting character, either
205   *   <code>"</code>&nbsp;<small>(double quote)</small> or
206   *   <code>'</code>&nbsp;<small>(single quote)</small>.
207   * @return   A String.
208   * @throws JSONException Unterminated string.
209   */
210  public String nextString(char quote) throws JSONException {
211    char c;
212    StringBuffer sb = new StringBuffer();
213    for (;;) {
214      c = next();
215      switch (c) {
216      case 0:
217      case '\n':
218      case '\r':
219        throw syntaxError("Unterminated string");
220      case '\\':
221        c = next();
222        switch (c) {
223        case 'b':
224          sb.append('\b');
225          break;
226        case 't':
227          sb.append('\t');
228          break;
229        case 'n':
230          sb.append('\n');
231          break;
232        case 'f':
233          sb.append('\f');
234          break;
235        case 'r':
236          sb.append('\r');
237          break;
238        case 'u':
239          sb.append((char)Integer.parseInt(next(4), 16));
240          break;
241        case 'x' :
242          sb.append((char) Integer.parseInt(next(2), 16));
243          break;
244        default:
245          sb.append(c);
246        }
247        break;
248      default:
249        if (c == quote) {
250          return sb.toString();
251        }
252        sb.append(c);
253      }
254    }
255  }
256
257
258  /** *//**
259   * Get the text up but not including the specifIEd character or the
260   * end of line, whichever comes first.
261   * @param d A delimiter character.
262   * @return  A string.
263   */
264  public String nextTo(char d) {
265    StringBuffer sb = new StringBuffer();
266    for (;;) {
267      char c = next();
268      if (c == d || c == 0 || c == '\n' || c == '\r') {
269        if (c != 0) {
270          back();
271        }
272        return sb.toString().trim();
273      }
274      sb.append(c);
275    }
276  }
277
278
279  /** *//**
280   * Get the text up but not including one of the specifIEd delimeter
281   * characters or the end of line, whichever comes first.
282   * @param delimiters A set of delimiter characters.
283   * @return A string, trimmed.
284   */
285  public String nextTo(String delimiters) {
286    char c;
287    StringBuffer sb = new StringBuffer();
288    for (;;) {
289      c = next();
290      if (delimiters.indexOf(c) >= 0 || c == 0 ||
291          c == '\n' || c == '\r') {
292        if (c != 0) {
293          back();
294        }
295        return sb.toString().trim();
296      }
297      sb.append(c);
298    }
299  }
300
301
302  /** *//**
303   * Get the next value. The value can be a Boolean, Double, Integer,
304   * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
305   * @throws JSONException If syntax error.
306   *
307   * @return An object.
308   */
309  public Object nextValue() throws JSONException {
310    char c = nextClean();
311    String s;
312
313    switch (c) {
314      case '"':
315      case '\'':
316        return nextString(c);
317      case '{':
318        back();
319        return new JSONObject(this);
320      case '[':
321      case '(':
322        back();
323        return new JSONArray(this);
324    }
325
326    /**//*
327     * Handle unquoted text. This could be the values true, false, or
328     * null, or it can be a number. An implementation (such as this one)
329     * is allowed to also accept non-standard forms.
330     *
331     * Accumulate characters until we reach the end of the text or a
332     * formatting character.
333     */
334
335    StringBuffer sb = new StringBuffer();
336    char b = c;
337    while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
338      sb.append(c);
339      c = next();
340    }
341    back();
342
343    /**//*
344     * If it is true, false, or null, return the proper value.
345     */
346
347    s = sb.toString().trim();
348    if (s.equals("")) {
349      throw syntaxError("Missing value");
350    }
351    if (s.equalsIgnoreCase("true")) {
352      return Boolean.TRUE;
353    }
354    if (s.equalsIgnoreCase("false")) {
355      return Boolean.FALSE;
356    }
357    if (s.equalsIgnoreCase("null")) {
358      return JSONObject.NULL;
359    }
360
361    /**//*
362     * If it might be a number, try converting it. We support the 0- and 0x-
363     * conventions. If a number cannot be produced, then the value will just
364     * be a string. Note that the 0-, 0x-, plus, and implIEd string
365     * conventions are non-standard. A JSON parser is free to accept
366     * non-JSON forms as long as it accepts all correct JSON forms.
367     */
368
369    if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
370      if (b == '0') {
371        if (s.length() > 2 &&
372            (s.charAt(1) == 'x' || s.charAt(1) == 'X')) {
373          try {
374            return new Integer(Integer.parseInt(s.substring(2),
375                16));
376          } catch (Exception e) {
377            /**//* Ignore the error */
378          }
379        } else {
380          try {
381            return new Integer(Integer.parseInt(s, 8));
382          } catch (Exception e) {
383            /**//* Ignore the error */
384          }
385        }
386      }
387      try {
388        return new Integer(s);
389      } catch (Exception e) {
390        try {
391          return new Long(s);
392        } catch (Exception f) {
393          try {
394            return new Double(s);
395          } catch (Exception g) {
396            return s;
397          }
398        }
399      }
400    }
401    return s;
402  }
403
404
405  /** *//**
406   * Skip characters until the next character is the requested character.
407   * If the requested character is not found, no characters are skipped.
408   * @param to A character to skip to.
409   * @return The requested character, or zero if the requested character
410   * is not found.
411   */
412  public char skipTo(char to) {
413    char c;
414    int index = this.myIndex;
415    do {
416      c = next();
417      if (c == 0) {
418        this.myIndex = index;
419        return c;
420      }
421    } while (c != to);
422    back();
423    return c;
424  }
425
426
427  /** *//**
428   * Skip characters until past the requested string.
429   * If it is not found, we are left at the end of the source.
430   * @param to A string to skip past.
431   */
432  public boolean skipPast(String to) {
433    this.myIndex = this.mySource.indexOf(to, this.myIndex);
434    if (this.myIndex < 0) {
435      this.myIndex = this.mySource.length();
436      return false;
437    }
438    this.myIndex += to.length();
439    return true;
440
441  }
442
443
444  /** *//**
445   * Make a JSONException to signal a syntax error.
446   *
447   * @param message The error message.
448   * @return A JSONException object, suitable for throwing
449   */
450  public JSONException syntaxError(String message) {
451    return new JSONException(message + toString());
452  }
453
454
455  /** *//**
456   * Make a printable string of this JSONTokener.
457   *
458   * @return " at character [this.myIndex] of [this.mySource]"
459   */
460  public String toString() {
461    return " at character " + this.myIndex + " of " + this.mySource;
462  }
463}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved