diff options
author | Jesse Wilson <jessewilson@google.com> | 2010-03-16 10:21:21 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-16 10:21:21 -0700 |
commit | a10509b68308e2bff501ece4862434108900c249 (patch) | |
tree | 0ac875551adce751d2c226883480fcd8625c42d3 /json | |
parent | e1036932386981100439bc9a0aa57199011a7849 (diff) | |
parent | c78ca6700830460f671652ce3efd4cc2c0cf7a6a (diff) | |
download | libcore-a10509b68308e2bff501ece4862434108900c249.zip libcore-a10509b68308e2bff501ece4862434108900c249.tar.gz libcore-a10509b68308e2bff501ece4862434108900c249.tar.bz2 |
Merge "First half of JSON Javadocs."
Diffstat (limited to 'json')
-rw-r--r-- | json/src/main/java/org/json/JSONException.java | 4 | ||||
-rw-r--r-- | json/src/main/java/org/json/JSONStringer.java | 96 | ||||
-rw-r--r-- | json/src/main/java/org/json/JSONTokener.java | 133 |
3 files changed, 214 insertions, 19 deletions
diff --git a/json/src/main/java/org/json/JSONException.java b/json/src/main/java/org/json/JSONException.java index e1efd9f..ddd1016 100644 --- a/json/src/main/java/org/json/JSONException.java +++ b/json/src/main/java/org/json/JSONException.java @@ -23,8 +23,8 @@ package org.json; * <ul> * <li>Attempts to parse or construct malformed documents * <li>Use of null as a name - * <li>Use of numeric types not available to JSON, such as {@link Double#NaN - * NaN} or {@link Double#POSITIVE_INFINITY infinity}. + * <li>Use of numeric types not available to JSON, such as {@link + * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}. * <li>Lookups using an out of range index or nonexistant name * <li>Type mismatches on lookups * </ul> diff --git a/json/src/main/java/org/json/JSONStringer.java b/json/src/main/java/org/json/JSONStringer.java index fb60bd1..fa22397 100644 --- a/json/src/main/java/org/json/JSONStringer.java +++ b/json/src/main/java/org/json/JSONStringer.java @@ -23,7 +23,40 @@ import java.util.List; // Note: this class was written without inspecting the non-free org.json sourcecode. /** + * Implements {@link JSONObject#toString()} and {@link JSONArray#toString}. Most + * application developers should use those methods directly and disregard this + * API. For example:<pre> + * JSONObject object = ... + * String json = object.toString();</pre> * + * <p>Stringers only encode well-formed JSON strings. In particular: + * <ul> + * <li>The stringer must have exactly one top-level array or object. + * <li>Lexical scopes must be balanced: every call to {@link #array()} must + * have a matching call to {@link #endArray()} and every call to {@link + * #object()} must have a matching call to {@link #endObject()}. + * <li>Arrays may not contain keys (property names). + * <li>Objects must alternate keys (property names) and values. + * <li>Values are inserted with either literal {@link #value(Object) value} + * calls, or by nesting arrays or objects. + * </ul> + * Calls that would result in a malformed JSON string will fail with a + * {@link JSONException}. + * + * <p>This class provides no facility for pretty-printing (ie. indenting) + * output. To encode indented output, use {@link JSONObject#toString(int)} or + * {@link JSONArray#toString(int)}. + * + * <p>Some implementations of the API support at most 20 levels of nesting. + * Attempts to create more than 20 levels of nesting may fail with a {@link + * JSONException}. + * + * <p>Each stringer may be used to encode a single top level value. Instances of + * this class are not thread safe. Although this class is nonfinal, it was not + * designed for inheritance and should not be subclassed. In particular, + * self-use by overridable methods is not specified. See <i>Effective Java</i> + * Item 17, "Design and Document or inheritance or else prohibit it" for further + * information. */ public class JSONStringer { @@ -96,18 +129,40 @@ public class JSONStringer { indent = new String(indentChars); } + /** + * Begins encoding a new array. Each call to this method must be paired with + * a call to {@link #endArray()}. + * + * @return this stringer. + */ public JSONStringer array() throws JSONException { return open(Scope.EMPTY_ARRAY, "["); } + /** + * Ends encoding the current array. + * + * @return this stringer. + */ public JSONStringer endArray() throws JSONException { return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]"); } + /** + * Begins encoding a new object. Each call to this method must be paired + * with a call to {@link #endObject()}. + * + * @return this stringer. + */ public JSONStringer object() throws JSONException { return open(Scope.EMPTY_OBJECT, "{"); } + /** + * Ends encoding the current object. + * + * @return this stringer. + */ public JSONStringer endObject() throws JSONException { return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}"); } @@ -161,6 +216,14 @@ public class JSONStringer { stack.set(stack.size() - 1, topOfStack); } + /** + * Encodes {@code value}. + * + * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, + * Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs} + * or {@link Double#isInfinite() infinities}. + * @return this stringer. + */ public JSONStringer value(Object value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -192,6 +255,11 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @return this stringer. + */ public JSONStringer value(boolean value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -201,6 +269,13 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @param value a finite value. May not be {@link Double#isNaN() NaNs} or + * {@link Double#isInfinite() infinities}. + * @return this stringer. + */ public JSONStringer value(double value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -210,6 +285,11 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @return this stringer. + */ public JSONStringer value(long value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -281,6 +361,12 @@ public class JSONStringer { } } + /** + * Encodes the key (property name) to this stringer. + * + * @param name the name of the forthcoming value. May not be null. + * @return this stringer. + */ public JSONStringer key(String name) throws JSONException { if (name == null) { throw new JSONException("Names must be non-null"); @@ -331,8 +417,14 @@ public class JSONStringer { } /** - * Although it contradicts the general contract of {@link Object#toString}, - * this method returns null if the stringer contains no data. + * Returns the encoded JSON string. + * + * <p>If invoked with unterminated arrays or unclosed objects, this method's + * return value is undefined. + * + * <p><strong>Warning:</strong> although it contradicts the general contract + * of {@link Object#toString}, this method returns null if the stringer + * contains no data. */ @Override public String toString() { return out.length() == 0 ? null : out.toString(); diff --git a/json/src/main/java/org/json/JSONTokener.java b/json/src/main/java/org/json/JSONTokener.java index e249c74..d5d2dd2 100644 --- a/json/src/main/java/org/json/JSONTokener.java +++ b/json/src/main/java/org/json/JSONTokener.java @@ -19,7 +19,28 @@ package org.json; // Note: this class was written without inspecting the non-free org.json sourcecode. /** + * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>) + * encoded string into the corresponding object. Most clients of + * this class will use only need the {@link #JSONTokener(String) constructor} + * and {@link #nextValue} method. Example usage: <pre> + * String json = "{" + * + " \"query\": \"Pizza\", " + * + " \"locations\": [ 94043, 90210 ] " + * + "}"; * + * JSONObject object = (JSONObject) new JSONTokener(json).nextValue(); + * String query = object.getString("query"); + * JSONArray locations = object.getJSONArray("locations");</pre> + * + * <p>This parser is lenient. A successful parse does not necessarily indicate + * that the input string is valid JSON. + * + * <p>Each tokener may be used to parse a single JSON string. Instances of this + * class are not thread safe. Although this class is nonfinal, it was not + * designed for inheritance and should not be subclassed. In particular, + * self-use by overridable methods is not specified. See <i>Effective Java</i> + * Item 17, "Design and Document or inheritance or else prohibit it" for further + * information. */ public class JSONTokener { @@ -32,10 +53,22 @@ public class JSONTokener { */ private int pos; + /** + * @param in JSON encoded string. Null is not permitted and will yield a + * tokener that throws {@code NullPointerExceptions} when methods are + * called. + */ public JSONTokener(String in) { this.in = in; } + /** + * Returns the next value from the input. + * + * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean, + * Integer, Long, Double or {@link JSONObject#NULL}. + * @throws JSONException if the input is malformed. + */ public Object nextValue() throws JSONException { int c = nextCleanInternal(); switch (c) { @@ -121,8 +154,12 @@ public class JSONTokener { } /** + * Returns the string up to but not including {@code quote}, unescaping any + * character escape sequences encountered along the way. The opening quote + * should have already been read. This consumes the closing quote, but does + * not include it in the returned string. * - * + * @param quote either ' or ". * @throws NumberFormatException if any unicode escape sequences are * malformed. */ @@ -264,9 +301,8 @@ public class JSONTokener { } /** - * Returns text from the current position until the first of any of the - * given characters or a newline character, excluding that character. The - * position is advanced to the excluded character. + * Returns the string up to but not including any of the given characters or + * a newline character. This does not consume the excluded character. */ private String nextToInternal(String excluded) { int start = pos; @@ -378,10 +414,17 @@ public class JSONTokener { } } - public JSONException syntaxError(String text) { - return new JSONException(text + this); + /** + * Returns an exception containing the given message plus the current + * position and the entire input string. + */ + public JSONException syntaxError(String message) { + return new JSONException(message + this); } + /** + * Returns the current position and the entire input string. + */ @Override public String toString() { // consistent with the original implementation return " at character " + pos + " of " + in; @@ -395,14 +438,26 @@ public class JSONTokener { * implementation and may be used by some clients. */ + /** + * Returns true until the input has been exhausted. + */ public boolean more() { return pos < in.length(); } + /** + * Returns the next available character, or the null character '\0' if all + * input has been exhausted. The return value of this method is ambiguous + * for JSON strings that contain the character '\0'. + */ public char next() { return pos < in.length() ? in.charAt(pos++) : '\0'; } + /** + * Returns the next available character if it equals {@code c}. Otherwise an + * exception is thrown. + */ public char next(char c) throws JSONException { char result = next(); if (result != c) { @@ -411,13 +466,27 @@ public class JSONTokener { return result; } + /** + * Returns the next character that is not whitespace and does not belong to + * a comment. If the input is exhausted before such a character can be + * found, the null character '\0' is returned. The return value of this + * method is ambiguous for JSON strings that contain the character '\0'. + */ public char nextClean() throws JSONException { int nextCleanInt = nextCleanInternal(); return nextCleanInt == -1 ? '\0' : (char) nextCleanInt; } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Returns the next {@code length} characters of the input. + * + * <p>The returned string shares its backing character array with this + * tokener's input string. If a reference to the returned string may be held + * indefinitely, you should {@link String(String) copy} it first to avoid + * memory leaks. + * + * @throws JSONException if the remaining input is not long enough to + * satisfy this request. */ public String next(int length) throws JSONException { if (pos + length > in.length()) { @@ -429,7 +498,20 @@ public class JSONTokener { } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Returns the {@link String#trim trimmed} string holding the characters up + * to but not including the first of: + * <ul> + * <li>any character in {@code excluded} + * <li>a newline character '\n' + * <li>a carriage return '\r' + * </ul> + * + * <p>The returned string shares its backing character array with this + * tokener's input string. If a reference to the returned string may be held + * indefinitely, you should {@link String(String) copy} it first to avoid + * memory leaks. + * + * @return a possibly-empty string */ public String nextTo(String excluded) { if (excluded == null) { @@ -439,33 +521,54 @@ public class JSONTokener { } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Equivalent to {@code nextTo(String.valueOf(excluded))}. */ public String nextTo(char excluded) { return nextToInternal(String.valueOf(excluded)).trim(); } + /** + * Advances past all input up to and including the next occurrence of + * {@code thru}. If the remaining input doesn't contain {@code thru}, the + * input is exhausted. + */ public void skipPast(String thru) { int thruStart = in.indexOf(thru, pos); pos = thruStart == -1 ? in.length() : (thruStart + thru.length()); } + /** + * Advances past all input up to but not including the next occurrence of + * {@code to}. If the remaining input doesn't contain {@code to}, the input + * is unchanged. + */ public char skipTo(char to) { - for (int i = pos, length = in.length(); i < length; i++) { - if (in.charAt(i) == to) { - pos = i; - return to; - } + int index = in.indexOf(to, pos); + if (index != -1) { + pos = index; + return to; + } else { + return '\0'; } - return '\0'; } + /** + * Unreads the most recent character of input. If no input characters have + * been read, the input is unchanged. + */ public void back() { if (--pos == -1) { pos = 0; } } + /** + * Returns the integer [0..15] value for the given hex character, or -1 + * for non-hex input. + * + * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other + * character will yield a -1 result. + */ public static int dehexchar(char hex) { if (hex >= '0' && hex <= '9') { return hex - '0'; |