Merge pull request #1 from square/jwilson_0809_hello_moshi

Set up the moshi project.
This commit is contained in:
Jake Wharton
2014-08-09 14:10:01 -07:00
16 changed files with 5236 additions and 4 deletions

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
.classpath
.project
.settings
eclipsebin
bin
gen
build
out
lib
target
pom.xml.*
release.properties
.idea
*.iml
*.ipr
*.iws
classes
obj
.DS_Store

10
CHANGELOG.md Normal file
View File

@@ -0,0 +1,10 @@
Change Log
==========
## Version 0.1.0
_2014-08-09_
* Initial code creation.
* Imported JsonReader and JsonWriter from Gson.

17
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,17 @@
Contributing
============
If you would like to contribute code to Moshi you can do so through GitHub by
forking the repository and sending a pull request.
When submitting code, please make every effort to follow existing conventions
and style in order to keep the code as readable as possible. Please also make
sure your code compiles by running `mvn clean verify`. Checkstyle failures
during compilation indicate errors in your style and can be viewed in the
`checkstyle-result.xml` file.
Before your code can be accepted into the project you must also sign the
[Individual Contributor License Agreement (CLA)][1].
[1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1

View File

@@ -1,4 +1,5 @@
Apache License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -178,7 +179,7 @@ Apache License
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
@@ -186,7 +187,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,2 +1,5 @@
moshi
Moshi
=====
A modern JSON library for Android and Java.

131
checkstyle.xml Normal file
View File

@@ -0,0 +1,131 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<module name="NewlineAtEndOfFile"/>
<module name="FileLength"/>
<module name="FileTabCharacter"/>
<!-- Trailing spaces -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<!-- Space after 'for' and 'if' -->
<module name="RegexpSingleline">
<property name="format" value="^\s*(for|if)\b[^ ]"/>
<property name="message" value="Space needed before opening parenthesis."/>
</module>
<!-- For each spacing -->
<module name="RegexpSingleline">
<property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
<property name="message" value="Space needed around ':' character."/>
</module>
<module name="TreeWalker">
<property name="cacheFile" value="${checkstyle.cache.file}"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<!--module name="JavadocMethod"/-->
<!--module name="JavadocType"/-->
<!--module name="JavadocVariable"/-->
<module name="JavadocStyle"/>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<!--<module name="ConstantName"/>-->
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="LineLength">
<property name="max" value="100"/>
</module>
<module name="MethodLength"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="GenericWhitespace"/>
<!--<module name="EmptyForIteratorPad"/>-->
<module name="MethodParamPad"/>
<!--<module name="NoWhitespaceAfter"/>-->
<!--<module name="NoWhitespaceBefore"/>-->
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<!--module name="EmptyBlock"/-->
<module name="LeftCurly"/>
<!--<module name="NeedBraces"/>-->
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<!--module name="AvoidInlineConditionals"/-->
<module name="CovariantEquals"/>
<module name="EmptyStatement"/>
<!--<module name="EqualsAvoidNull"/>-->
<module name="EqualsHashCode"/>
<!--module name="HiddenField"/-->
<module name="IllegalInstantiation"/>
<!--module name="InnerAssignment"/-->
<!--module name="MagicNumber"/-->
<!--module name="MissingSwitchDefault"/-->
<module name="RedundantThrows"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!--module name="DesignForExtension"/-->
<!--<module name="FinalClass"/>-->
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<!--module name="VisibilityModifier"/-->
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<!--module name="FinalParameters"/-->
<!--module name="TodoComment"/-->
<module name="UpperEll"/>
</module>
</module>

41
deploy_javadoc.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
set -ex
REPO="git@github.com:square/moshi.git"
GROUP_ID="com.squareup.moshi"
ARTIFACT_ID="moshi"
DIR=temp-clone
# Delete any existing temporary website clone
rm -rf $DIR
# Clone the current repo into temp folder
git clone $REPO $DIR
# Move working directory into temp folder
cd $DIR
# Checkout and track the gh-pages branch
git checkout -t origin/gh-pages
# Delete everything
rm -rf *
# Download the latest javadoc
curl -L "http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=$GROUP_ID&a=$ARTIFACT_ID&v=LATEST&c=javadoc" > javadoc.zip
unzip javadoc.zip
rm javadoc.zip
# Stage all files in git and create a commit
git add .
git add -u
git commit -m "Website at $(date)"
# Push the new files up to GitHub
git push origin gh-pages
# Delete our temp folder
cd ..
rm -rf $DIR

27
moshi/pom.xml Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi-parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>moshi</artifactId>
<name>Moshi</name>
<dependencies>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.moshi;
/**
* Lexical scoping elements within a JSON reader or writer.
*
* @author Jesse Wilson
* @since 1.6
*/
final class JsonScope {
/**
* An array with no elements requires no separators or newlines before
* it is closed.
*/
static final int EMPTY_ARRAY = 1;
/**
* A array with at least one value requires a comma and newline before
* the next element.
*/
static final int NONEMPTY_ARRAY = 2;
/**
* An object with no name/value pairs requires no separators or newlines
* before it is closed.
*/
static final int EMPTY_OBJECT = 3;
/**
* An object whose most recent element is a key. The next element must
* be a value.
*/
static final int DANGLING_NAME = 4;
/**
* An object with at least one name/value pair requires a comma and
* newline before the next element.
*/
static final int NONEMPTY_OBJECT = 5;
/**
* No object or array has been started.
*/
static final int EMPTY_DOCUMENT = 6;
/**
* A document with at an array or object.
*/
static final int NONEMPTY_DOCUMENT = 7;
/**
* A document that's been closed and cannot be accessed.
*/
static final int CLOSED = 8;
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.moshi;
/**
* A structure, name or value type in a JSON-encoded string.
*/
public enum JsonToken {
/**
* The opening of a JSON array. Written using {@link JsonWriter#beginArray}
* and read using {@link JsonReader#beginArray}.
*/
BEGIN_ARRAY,
/**
* The closing of a JSON array. Written using {@link JsonWriter#endArray}
* and read using {@link JsonReader#endArray}.
*/
END_ARRAY,
/**
* The opening of a JSON object. Written using {@link JsonWriter#beginObject}
* and read using {@link JsonReader#beginObject}.
*/
BEGIN_OBJECT,
/**
* The closing of a JSON object. Written using {@link JsonWriter#endObject}
* and read using {@link JsonReader#endObject}.
*/
END_OBJECT,
/**
* A JSON property name. Within objects, tokens alternate between names and
* their values. Written using {@link JsonWriter#name} and read using {@link
* JsonReader#nextName}
*/
NAME,
/**
* A JSON string.
*/
STRING,
/**
* A JSON number represented in this API by a Java {@code double}, {@code
* long}, or {@code int}.
*/
NUMBER,
/**
* A JSON {@code true} or {@code false}.
*/
BOOLEAN,
/**
* A JSON {@code null}.
*/
NULL,
/**
* The end of the JSON stream. This sentinel value is returned by {@link
* JsonReader#peek()} to signal that the JSON-encoded value has no more
* tokens.
*/
END_DOCUMENT
}

View File

@@ -0,0 +1,632 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.moshi;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;
import static com.squareup.moshi.JsonScope.DANGLING_NAME;
import static com.squareup.moshi.JsonScope.EMPTY_ARRAY;
import static com.squareup.moshi.JsonScope.EMPTY_DOCUMENT;
import static com.squareup.moshi.JsonScope.EMPTY_OBJECT;
import static com.squareup.moshi.JsonScope.NONEMPTY_ARRAY;
import static com.squareup.moshi.JsonScope.NONEMPTY_DOCUMENT;
import static com.squareup.moshi.JsonScope.NONEMPTY_OBJECT;
/**
* Writes a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
* encoded value to a stream, one token at a time. The stream includes both
* literal values (strings, numbers, booleans and nulls) as well as the begin
* and end delimiters of objects and arrays.
*
* <h3>Encoding JSON</h3>
* To encode your data as JSON, create a new {@code JsonWriter}. Each JSON
* document must contain one top-level array or object. Call methods on the
* writer as you walk the structure's contents, nesting arrays and objects as
* necessary:
* <ul>
* <li>To write <strong>arrays</strong>, first call {@link #beginArray()}.
* Write each of the array's elements with the appropriate {@link #value}
* methods or by nesting other arrays and objects. Finally close the array
* using {@link #endArray()}.
* <li>To write <strong>objects</strong>, first call {@link #beginObject()}.
* Write each of the object's properties by alternating calls to
* {@link #name} with the property's value. Write property values with the
* appropriate {@link #value} method or by nesting other objects or arrays.
* Finally close the object using {@link #endObject()}.
* </ul>
*
* <h3>Example</h3>
* Suppose we'd like to encode a stream of messages such as the following: <pre> {@code
* [
* {
* "id": 912345678901,
* "text": "How do I stream JSON in Java?",
* "geo": null,
* "user": {
* "name": "json_newb",
* "followers_count": 41
* }
* },
* {
* "id": 912345678902,
* "text": "@json_newb just use JsonWriter!",
* "geo": [50.454722, -104.606667],
* "user": {
* "name": "jesse",
* "followers_count": 2
* }
* }
* ]}</pre>
* This code encodes the above structure: <pre> {@code
* public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
* JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
* writer.setIndentSpaces(4);
* writeMessagesArray(writer, messages);
* writer.close();
* }
*
* public void writeMessagesArray(JsonWriter writer, List<Message> messages) throws IOException {
* writer.beginArray();
* for (Message message : messages) {
* writeMessage(writer, message);
* }
* writer.endArray();
* }
*
* public void writeMessage(JsonWriter writer, Message message) throws IOException {
* writer.beginObject();
* writer.name("id").value(message.getId());
* writer.name("text").value(message.getText());
* if (message.getGeo() != null) {
* writer.name("geo");
* writeDoublesArray(writer, message.getGeo());
* } else {
* writer.name("geo").nullValue();
* }
* writer.name("user");
* writeUser(writer, message.getUser());
* writer.endObject();
* }
*
* public void writeUser(JsonWriter writer, User user) throws IOException {
* writer.beginObject();
* writer.name("name").value(user.getName());
* writer.name("followers_count").value(user.getFollowersCount());
* writer.endObject();
* }
*
* public void writeDoublesArray(JsonWriter writer, List<Double> doubles) throws IOException {
* writer.beginArray();
* for (Double value : doubles) {
* writer.value(value);
* }
* writer.endArray();
* }}</pre>
*
* <p>Each {@code JsonWriter} may be used to write a single JSON stream.
* Instances of this class are not thread safe. Calls that would result in a
* malformed JSON string will fail with an {@link IllegalStateException}.
*
* @author Jesse Wilson
*/
public class JsonWriter implements Closeable, Flushable {
/*
* From RFC 4627, "All Unicode characters may be placed within the
* quotation marks except for the characters that must be escaped:
* quotation mark, reverse solidus, and the control characters
* (U+0000 through U+001F)."
*
* We also escape '\u2028' and '\u2029', which JavaScript interprets as
* newline characters. This prevents eval() from failing with a syntax
* error. http://code.google.com/p/google-gson/issues/detail?id=341
*/
private static final String[] REPLACEMENT_CHARS;
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
static {
REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 0x1f; i++) {
REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int) i);
}
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}
/** The output data, containing at most one top-level array or object. */
private final Writer out;
private int[] stack = new int[32];
private int stackSize = 0;
{
push(EMPTY_DOCUMENT);
}
/**
* A string containing a full set of spaces for a single level of
* indentation, or null for no pretty printing.
*/
private String indent;
/**
* The name/value separator; either ":" or ": ".
*/
private String separator = ":";
private boolean lenient;
private boolean htmlSafe;
private String deferredName;
private boolean serializeNulls = true;
/**
* Creates a new instance that writes a JSON-encoded stream to {@code out}.
* For best performance, ensure {@link Writer} is buffered; wrapping in
* {@link java.io.BufferedWriter BufferedWriter} if necessary.
*/
public JsonWriter(Writer out) {
if (out == null) {
throw new NullPointerException("out == null");
}
this.out = out;
}
/**
* Sets the indentation string to be repeated for each level of indentation
* in the encoded document. If {@code indent.isEmpty()} the encoded document
* will be compact. Otherwise the encoded document will be more
* human-readable.
*
* @param indent a string containing only whitespace.
*/
public final void setIndent(String indent) {
if (indent.length() == 0) {
this.indent = null;
this.separator = ":";
} else {
this.indent = indent;
this.separator = ": ";
}
}
/**
* Configure this writer to relax its syntax rules. By default, this writer
* only emits well-formed JSON as specified by <a
* href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the writer
* to lenient permits the following:
* <ul>
* <li>Top-level values of any type. With strict writing, the top-level
* value must be an object or an array.
* <li>Numbers may be {@link Double#isNaN() NaNs} or {@link
* Double#isInfinite() infinities}.
* </ul>
*/
public final void setLenient(boolean lenient) {
this.lenient = lenient;
}
/**
* Returns true if this writer has relaxed syntax rules.
*/
public boolean isLenient() {
return lenient;
}
/**
* Configure this writer to emit JSON that's safe for direct inclusion in HTML
* and XML documents. This escapes the HTML characters {@code <}, {@code >},
* {@code &} and {@code =} before writing them to the stream. Without this
* setting, your XML/HTML encoder should replace these characters with the
* corresponding escape sequences.
*/
public final void setHtmlSafe(boolean htmlSafe) {
this.htmlSafe = htmlSafe;
}
/**
* Returns true if this writer writes JSON that's safe for inclusion in HTML
* and XML documents.
*/
public final boolean isHtmlSafe() {
return htmlSafe;
}
/**
* Sets whether object members are serialized when their value is null.
* This has no impact on array elements. The default is true.
*/
public final void setSerializeNulls(boolean serializeNulls) {
this.serializeNulls = serializeNulls;
}
/**
* Returns true if object members are serialized when their value is null.
* This has no impact on array elements. The default is true.
*/
public final boolean getSerializeNulls() {
return serializeNulls;
}
/**
* Begins encoding a new array. Each call to this method must be paired with
* a call to {@link #endArray}.
*
* @return this writer.
*/
public JsonWriter beginArray() throws IOException {
writeDeferredName();
return open(EMPTY_ARRAY, "[");
}
/**
* Ends encoding the current array.
*
* @return this writer.
*/
public JsonWriter endArray() throws IOException {
return close(EMPTY_ARRAY, NONEMPTY_ARRAY, "]");
}
/**
* Begins encoding a new object. Each call to this method must be paired
* with a call to {@link #endObject}.
*
* @return this writer.
*/
public JsonWriter beginObject() throws IOException {
writeDeferredName();
return open(EMPTY_OBJECT, "{");
}
/**
* Ends encoding the current object.
*
* @return this writer.
*/
public JsonWriter endObject() throws IOException {
return close(EMPTY_OBJECT, NONEMPTY_OBJECT, "}");
}
/**
* Enters a new scope by appending any necessary whitespace and the given
* bracket.
*/
private JsonWriter open(int empty, String openBracket) throws IOException {
beforeValue(true);
push(empty);
out.write(openBracket);
return this;
}
/**
* Closes the current scope by appending any necessary whitespace and the
* given bracket.
*/
private JsonWriter close(int empty, int nonempty, String closeBracket)
throws IOException {
int context = peek();
if (context != nonempty && context != empty) {
throw new IllegalStateException("Nesting problem.");
}
if (deferredName != null) {
throw new IllegalStateException("Dangling name: " + deferredName);
}
stackSize--;
if (context == nonempty) {
newline();
}
out.write(closeBracket);
return this;
}
private void push(int newTop) {
if (stackSize == stack.length) {
int[] newStack = new int[stackSize * 2];
System.arraycopy(stack, 0, newStack, 0, stackSize);
stack = newStack;
}
stack[stackSize++] = newTop;
}
/**
* Returns the value on the top of the stack.
*/
private int peek() {
if (stackSize == 0) {
throw new IllegalStateException("JsonWriter is closed.");
}
return stack[stackSize - 1];
}
/**
* Replace the value on the top of the stack with the given value.
*/
private void replaceTop(int topOfStack) {
stack[stackSize - 1] = topOfStack;
}
/**
* Encodes the property name.
*
* @param name the name of the forthcoming value. May not be null.
* @return this writer.
*/
public JsonWriter name(String name) throws IOException {
if (name == null) {
throw new NullPointerException("name == null");
}
if (deferredName != null) {
throw new IllegalStateException();
}
if (stackSize == 0) {
throw new IllegalStateException("JsonWriter is closed.");
}
deferredName = name;
return this;
}
private void writeDeferredName() throws IOException {
if (deferredName != null) {
beforeName();
string(deferredName);
deferredName = null;
}
}
/**
* Encodes {@code value}.
*
* @param value the literal string value, or null to encode a null literal.
* @return this writer.
*/
public JsonWriter value(String value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
beforeValue(false);
string(value);
return this;
}
/**
* Encodes {@code null}.
*
* @return this writer.
*/
public JsonWriter nullValue() throws IOException {
if (deferredName != null) {
if (serializeNulls) {
writeDeferredName();
} else {
deferredName = null;
return this; // skip the name and the value
}
}
beforeValue(false);
out.write("null");
return this;
}
/**
* Encodes {@code value}.
*
* @return this writer.
*/
public JsonWriter value(boolean value) throws IOException {
writeDeferredName();
beforeValue(false);
out.write(value ? "true" : "false");
return this;
}
/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
* {@link Double#isInfinite() infinities}.
* @return this writer.
*/
public JsonWriter value(double value) throws IOException {
if (Double.isNaN(value) || Double.isInfinite(value)) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
writeDeferredName();
beforeValue(false);
out.append(Double.toString(value));
return this;
}
/**
* Encodes {@code value}.
*
* @return this writer.
*/
public JsonWriter value(long value) throws IOException {
writeDeferredName();
beforeValue(false);
out.write(Long.toString(value));
return this;
}
/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
* {@link Double#isInfinite() infinities}.
* @return this writer.
*/
public JsonWriter value(Number value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
String string = value.toString();
if (!lenient
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
beforeValue(false);
out.append(string);
return this;
}
/**
* Ensures all buffered data is written to the underlying {@link Writer}
* and flushes that writer.
*/
public void flush() throws IOException {
if (stackSize == 0) {
throw new IllegalStateException("JsonWriter is closed.");
}
out.flush();
}
/**
* Flushes and closes this writer and the underlying {@link Writer}.
*
* @throws IOException if the JSON document is incomplete.
*/
public void close() throws IOException {
out.close();
int size = stackSize;
if (size > 1 || size == 1 && stack[size - 1] != NONEMPTY_DOCUMENT) {
throw new IOException("Incomplete document");
}
stackSize = 0;
}
private void string(String value) throws IOException {
String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
out.write("\"");
int last = 0;
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
String replacement;
if (c < 128) {
replacement = replacements[c];
if (replacement == null) {
continue;
}
} else if (c == '\u2028') {
replacement = "\\u2028";
} else if (c == '\u2029') {
replacement = "\\u2029";
} else {
continue;
}
if (last < i) {
out.write(value, last, i - last);
}
out.write(replacement);
last = i + 1;
}
if (last < length) {
out.write(value, last, length - last);
}
out.write("\"");
}
private void newline() throws IOException {
if (indent == null) {
return;
}
out.write("\n");
for (int i = 1, size = stackSize; i < size; i++) {
out.write(indent);
}
}
/**
* Inserts any necessary separators and whitespace before a name. Also
* adjusts the stack to expect the name's value.
*/
private void beforeName() throws IOException {
int context = peek();
if (context == NONEMPTY_OBJECT) { // first in object
out.write(',');
} else if (context != EMPTY_OBJECT) { // not in an object!
throw new IllegalStateException("Nesting problem.");
}
newline();
replaceTop(DANGLING_NAME);
}
/**
* Inserts any necessary separators and whitespace before a literal value,
* inline array, or inline object. Also adjusts the stack to expect either a
* closing bracket or another element.
*
* @param root true if the value is a new array or object, the two values
* permitted as top-level elements.
*/
@SuppressWarnings("fallthrough")
private void beforeValue(boolean root) throws IOException {
switch (peek()) {
case NONEMPTY_DOCUMENT:
if (!lenient) {
throw new IllegalStateException(
"JSON must have only one top-level value.");
}
// fall-through
case EMPTY_DOCUMENT: // first in document
if (!lenient && !root) {
throw new IllegalStateException(
"JSON must start with an array or an object.");
}
replaceTop(NONEMPTY_DOCUMENT);
break;
case EMPTY_ARRAY: // first in array
replaceTop(NONEMPTY_ARRAY);
newline();
break;
case NONEMPTY_ARRAY: // another in array
out.append(',');
newline();
break;
case DANGLING_NAME: // value for name
out.append(separator);
replaceTop(NONEMPTY_OBJECT);
break;
default:
throw new IllegalStateException("Nesting problem.");
}
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.moshi;
import java.io.IOException;
import java.io.StringReader;
import junit.framework.TestCase;
public class JsonReaderPathTest extends TestCase {
public void testPath() throws IOException {
JsonReader reader = new JsonReader(
new StringReader("{\"a\":[2,true,false,null,\"b\",{\"c\":\"d\"},[3]]}"));
assertEquals("$", reader.getPath());
reader.beginObject();
assertEquals("$.", reader.getPath());
reader.nextName();
assertEquals("$.a", reader.getPath());
reader.beginArray();
assertEquals("$.a[0]", reader.getPath());
reader.nextInt();
assertEquals("$.a[1]", reader.getPath());
reader.nextBoolean();
assertEquals("$.a[2]", reader.getPath());
reader.nextBoolean();
assertEquals("$.a[3]", reader.getPath());
reader.nextNull();
assertEquals("$.a[4]", reader.getPath());
reader.nextString();
assertEquals("$.a[5]", reader.getPath());
reader.beginObject();
assertEquals("$.a[5].", reader.getPath());
reader.nextName();
assertEquals("$.a[5].c", reader.getPath());
reader.nextString();
assertEquals("$.a[5].c", reader.getPath());
reader.endObject();
assertEquals("$.a[5]", reader.getPath());
reader.beginArray();
assertEquals("$.a[5][0]", reader.getPath());
reader.nextInt();
assertEquals("$.a[5][1]", reader.getPath());
reader.endArray();
assertEquals("$.a[5]", reader.getPath());
reader.endArray();
assertEquals("$.a", reader.getPath());
reader.endObject();
assertEquals("$", reader.getPath());
}
public void testObjectPath() throws IOException {
JsonReader reader = new JsonReader(new StringReader("{\"a\":1,\"b\":2}"));
assertEquals("$", reader.getPath());
reader.peek();
assertEquals("$", reader.getPath());
reader.beginObject();
assertEquals("$.", reader.getPath());
reader.peek();
assertEquals("$.", reader.getPath());
reader.nextName();
assertEquals("$.a", reader.getPath());
reader.peek();
assertEquals("$.a", reader.getPath());
reader.nextInt();
assertEquals("$.a", reader.getPath());
reader.peek();
assertEquals("$.a", reader.getPath());
reader.nextName();
assertEquals("$.b", reader.getPath());
reader.peek();
assertEquals("$.b", reader.getPath());
reader.nextInt();
assertEquals("$.b", reader.getPath());
reader.peek();
assertEquals("$.b", reader.getPath());
reader.endObject();
assertEquals("$", reader.getPath());
reader.peek();
assertEquals("$", reader.getPath());
reader.close();
assertEquals("$", reader.getPath());
}
public void testArrayPath() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[1,2]"));
assertEquals("$", reader.getPath());
reader.peek();
assertEquals("$", reader.getPath());
reader.beginArray();
assertEquals("$[0]", reader.getPath());
reader.peek();
assertEquals("$[0]", reader.getPath());
reader.nextInt();
assertEquals("$[1]", reader.getPath());
reader.peek();
assertEquals("$[1]", reader.getPath());
reader.nextInt();
assertEquals("$[2]", reader.getPath());
reader.peek();
assertEquals("$[2]", reader.getPath());
reader.endArray();
assertEquals("$", reader.getPath());
reader.peek();
assertEquals("$", reader.getPath());
reader.close();
assertEquals("$", reader.getPath());
}
public void testMultipleTopLevelValuesInOneDocument() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[][]"));
reader.setLenient(true);
reader.beginArray();
reader.endArray();
assertEquals("$", reader.getPath());
reader.beginArray();
reader.endArray();
assertEquals("$", reader.getPath());
}
public void testSkipArrayElements() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[1,2,3]"));
reader.beginArray();
reader.skipValue();
reader.skipValue();
assertEquals("$[2]", reader.getPath());
}
public void testSkipObjectNames() throws IOException {
JsonReader reader = new JsonReader(new StringReader("{\"a\":1}"));
reader.beginObject();
reader.skipValue();
assertEquals("$.null", reader.getPath());
}
public void testSkipObjectValues() throws IOException {
JsonReader reader = new JsonReader(new StringReader("{\"a\":1,\"b\":2}"));
reader.beginObject();
reader.nextName();
reader.skipValue();
assertEquals("$.null", reader.getPath());
reader.nextName();
assertEquals("$.b", reader.getPath());
}
public void testSkipNestedStructures() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[[1,2,3],4]"));
reader.beginArray();
reader.skipValue();
assertEquals("$[1]", reader.getPath());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,566 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.moshi;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import junit.framework.TestCase;
@SuppressWarnings("resource")
public final class JsonWriterTest extends TestCase {
public void testWrongTopLevelType() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
try {
jsonWriter.value("a");
fail();
} catch (IllegalStateException expected) {
}
}
public void testTwoNames() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.name("a");
try {
jsonWriter.name("a");
fail();
} catch (IllegalStateException expected) {
}
}
public void testNameWithoutValue() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.name("a");
try {
jsonWriter.endObject();
fail();
} catch (IllegalStateException expected) {
}
}
public void testValueWithoutName() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
try {
jsonWriter.value(true);
fail();
} catch (IllegalStateException expected) {
}
}
public void testMultipleTopLevelValues() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray().endArray();
try {
jsonWriter.beginArray();
fail();
} catch (IllegalStateException expected) {
}
}
public void testBadNestingObject() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.beginObject();
try {
jsonWriter.endArray();
fail();
} catch (IllegalStateException expected) {
}
}
public void testBadNestingArray() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.beginArray();
try {
jsonWriter.endObject();
fail();
} catch (IllegalStateException expected) {
}
}
public void testNullName() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
try {
jsonWriter.name(null);
fail();
} catch (NullPointerException expected) {
}
}
public void testNullStringValue() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.name("a");
jsonWriter.value((String) null);
jsonWriter.endObject();
assertEquals("{\"a\":null}", stringWriter.toString());
}
public void testNonFiniteDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
try {
jsonWriter.value(Double.NaN);
fail();
} catch (IllegalArgumentException expected) {
}
try {
jsonWriter.value(Double.NEGATIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
}
try {
jsonWriter.value(Double.POSITIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testNonFiniteBoxedDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
try {
jsonWriter.value(new Double(Double.NaN));
fail();
} catch (IllegalArgumentException expected) {
}
try {
jsonWriter.value(new Double(Double.NEGATIVE_INFINITY));
fail();
} catch (IllegalArgumentException expected) {
}
try {
jsonWriter.value(new Double(Double.POSITIVE_INFINITY));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value(-0.0);
jsonWriter.value(1.0);
jsonWriter.value(Double.MAX_VALUE);
jsonWriter.value(Double.MIN_VALUE);
jsonWriter.value(0.0);
jsonWriter.value(-0.5);
jsonWriter.value(2.2250738585072014E-308);
jsonWriter.value(Math.PI);
jsonWriter.value(Math.E);
jsonWriter.endArray();
jsonWriter.close();
assertEquals("[-0.0,"
+ "1.0,"
+ "1.7976931348623157E308,"
+ "4.9E-324,"
+ "0.0,"
+ "-0.5,"
+ "2.2250738585072014E-308,"
+ "3.141592653589793,"
+ "2.718281828459045]", stringWriter.toString());
}
public void testLongs() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value(0);
jsonWriter.value(1);
jsonWriter.value(-1);
jsonWriter.value(Long.MIN_VALUE);
jsonWriter.value(Long.MAX_VALUE);
jsonWriter.endArray();
jsonWriter.close();
assertEquals("[0,"
+ "1,"
+ "-1,"
+ "-9223372036854775808,"
+ "9223372036854775807]", stringWriter.toString());
}
public void testNumbers() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value(new BigInteger("0"));
jsonWriter.value(new BigInteger("9223372036854775808"));
jsonWriter.value(new BigInteger("-9223372036854775809"));
jsonWriter.value(new BigDecimal("3.141592653589793238462643383"));
jsonWriter.endArray();
jsonWriter.close();
assertEquals("[0,"
+ "9223372036854775808,"
+ "-9223372036854775809,"
+ "3.141592653589793238462643383]", stringWriter.toString());
}
public void testBooleans() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value(true);
jsonWriter.value(false);
jsonWriter.endArray();
assertEquals("[true,false]", stringWriter.toString());
}
public void testNulls() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.nullValue();
jsonWriter.endArray();
assertEquals("[null]", stringWriter.toString());
}
public void testStrings() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value("a");
jsonWriter.value("a\"");
jsonWriter.value("\"");
jsonWriter.value(":");
jsonWriter.value(",");
jsonWriter.value("\b");
jsonWriter.value("\f");
jsonWriter.value("\n");
jsonWriter.value("\r");
jsonWriter.value("\t");
jsonWriter.value(" ");
jsonWriter.value("\\");
jsonWriter.value("{");
jsonWriter.value("}");
jsonWriter.value("[");
jsonWriter.value("]");
jsonWriter.value("\0");
jsonWriter.value("\u0019");
jsonWriter.endArray();
assertEquals("[\"a\","
+ "\"a\\\"\","
+ "\"\\\"\","
+ "\":\","
+ "\",\","
+ "\"\\b\","
+ "\"\\f\","
+ "\"\\n\","
+ "\"\\r\","
+ "\"\\t\","
+ "\" \","
+ "\"\\\\\","
+ "\"{\","
+ "\"}\","
+ "\"[\","
+ "\"]\","
+ "\"\\u0000\","
+ "\"\\u0019\"]", stringWriter.toString());
}
public void testUnicodeLineBreaksEscaped() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value("\u2028 \u2029");
jsonWriter.endArray();
assertEquals("[\"\\u2028 \\u2029\"]", stringWriter.toString());
}
public void testEmptyArray() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.endArray();
assertEquals("[]", stringWriter.toString());
}
public void testEmptyObject() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.endObject();
assertEquals("{}", stringWriter.toString());
}
public void testObjectsInArrays() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.beginObject();
jsonWriter.name("a").value(5);
jsonWriter.name("b").value(false);
jsonWriter.endObject();
jsonWriter.beginObject();
jsonWriter.name("c").value(6);
jsonWriter.name("d").value(true);
jsonWriter.endObject();
jsonWriter.endArray();
assertEquals("[{\"a\":5,\"b\":false},"
+ "{\"c\":6,\"d\":true}]", stringWriter.toString());
}
public void testArraysInObjects() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.name("a");
jsonWriter.beginArray();
jsonWriter.value(5);
jsonWriter.value(false);
jsonWriter.endArray();
jsonWriter.name("b");
jsonWriter.beginArray();
jsonWriter.value(6);
jsonWriter.value(true);
jsonWriter.endArray();
jsonWriter.endObject();
assertEquals("{\"a\":[5,false],"
+ "\"b\":[6,true]}", stringWriter.toString());
}
public void testDeepNestingArrays() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
for (int i = 0; i < 20; i++) {
jsonWriter.beginArray();
}
for (int i = 0; i < 20; i++) {
jsonWriter.endArray();
}
assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringWriter.toString());
}
public void testDeepNestingObjects() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
for (int i = 0; i < 20; i++) {
jsonWriter.name("a");
jsonWriter.beginObject();
}
for (int i = 0; i < 20; i++) {
jsonWriter.endObject();
}
jsonWriter.endObject();
assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":"
+ "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{"
+ "}}}}}}}}}}}}}}}}}}}}}", stringWriter.toString());
}
public void testRepeatedName() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginObject();
jsonWriter.name("a").value(true);
jsonWriter.name("a").value(false);
jsonWriter.endObject();
// JsonWriter doesn't attempt to detect duplicate names
assertEquals("{\"a\":true,\"a\":false}", stringWriter.toString());
}
public void testPrettyPrintObject() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setIndent(" ");
jsonWriter.beginObject();
jsonWriter.name("a").value(true);
jsonWriter.name("b").value(false);
jsonWriter.name("c").value(5.0);
jsonWriter.name("e").nullValue();
jsonWriter.name("f").beginArray();
jsonWriter.value(6.0);
jsonWriter.value(7.0);
jsonWriter.endArray();
jsonWriter.name("g").beginObject();
jsonWriter.name("h").value(8.0);
jsonWriter.name("i").value(9.0);
jsonWriter.endObject();
jsonWriter.endObject();
String expected = "{\n"
+ " \"a\": true,\n"
+ " \"b\": false,\n"
+ " \"c\": 5.0,\n"
+ " \"e\": null,\n"
+ " \"f\": [\n"
+ " 6.0,\n"
+ " 7.0\n"
+ " ],\n"
+ " \"g\": {\n"
+ " \"h\": 8.0,\n"
+ " \"i\": 9.0\n"
+ " }\n"
+ "}";
assertEquals(expected, stringWriter.toString());
}
public void testPrettyPrintArray() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setIndent(" ");
jsonWriter.beginArray();
jsonWriter.value(true);
jsonWriter.value(false);
jsonWriter.value(5.0);
jsonWriter.nullValue();
jsonWriter.beginObject();
jsonWriter.name("a").value(6.0);
jsonWriter.name("b").value(7.0);
jsonWriter.endObject();
jsonWriter.beginArray();
jsonWriter.value(8.0);
jsonWriter.value(9.0);
jsonWriter.endArray();
jsonWriter.endArray();
String expected = "[\n"
+ " true,\n"
+ " false,\n"
+ " 5.0,\n"
+ " null,\n"
+ " {\n"
+ " \"a\": 6.0,\n"
+ " \"b\": 7.0\n"
+ " },\n"
+ " [\n"
+ " 8.0,\n"
+ " 9.0\n"
+ " ]\n"
+ "]";
assertEquals(expected, stringWriter.toString());
}
public void testLenientWriterPermitsMultipleTopLevelValues() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.setLenient(true);
writer.beginArray();
writer.endArray();
writer.beginArray();
writer.endArray();
writer.close();
assertEquals("[][]", stringWriter.toString());
}
public void testStrictWriterDoesNotPermitMultipleTopLevelValues() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
try {
writer.beginArray();
fail();
} catch (IllegalStateException expected) {
}
}
public void testClosedWriterThrowsOnStructure() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
writer.close();
try {
writer.beginArray();
fail();
} catch (IllegalStateException expected) {
}
try {
writer.endArray();
fail();
} catch (IllegalStateException expected) {
}
try {
writer.beginObject();
fail();
} catch (IllegalStateException expected) {
}
try {
writer.endObject();
fail();
} catch (IllegalStateException expected) {
}
}
public void testClosedWriterThrowsOnName() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
writer.close();
try {
writer.name("a");
fail();
} catch (IllegalStateException expected) {
}
}
public void testClosedWriterThrowsOnValue() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
writer.close();
try {
writer.value("a");
fail();
} catch (IllegalStateException expected) {
}
}
public void testClosedWriterThrowsOnFlush() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
writer.close();
try {
writer.flush();
fail();
} catch (IllegalStateException expected) {
}
}
public void testWriterCloseIsIdempotent() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
writer.beginArray();
writer.endArray();
writer.close();
writer.close();
}
}

90
pom.xml Normal file
View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi-parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Moshi (Parent)</name>
<description>A modern JSON API for Android and Java</description>
<url>https://github.com/square/moshi</url>
<modules>
<module>moshi</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.6</java.version>
<!-- Dependencies -->
<okio.version>1.0.1</okio.version>
<!-- Test Dependencies -->
<junit.version>4.11</junit.version>
</properties>
<scm>
<url>https://github.com/square/moshi/</url>
<connection>scm:git:https://github.com/square/moshi.git</connection>
<developerConnection>scm:git:git@github.com:square/moshi.git</developerConnection>
<tag>HEAD</tag>
</scm>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/square/moshi/issues</url>
</issueManagement>
<licenses>
<license>
<name>Apache 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
</plugins>
</build>
</project>