[jackson-dataformat-smile] 05/31: ...
Hilko Bengen
bengen at alioth.debian.org
Mon Sep 2 17:37:20 UTC 2013
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag jackson-dataformat-smile-2.0.0
in repository jackson-dataformat-smile.
commit eb2e0f5805a613949e3bf0fc33d8cb8afd69fec0
Author: Tatu Saloranta <tsaloranta at gmail.com>
Date: Mon Nov 7 22:56:42 2011 -0800
...
---
.../jackson/dataformat/smile/.svn/all-wcprops | 59 -
.../jackson/dataformat/smile/.svn/entries | 334 ---
.../text-base/SmileBufferRecycler.java.svn-base | 53 -
.../.svn/text-base/SmileConstants.java.svn-base | 363 ---
.../.svn/text-base/SmileFactory.java.svn-base | 381 ---
.../.svn/text-base/SmileGenerator.java.svn-base | 2132 -----------------
.../smile/.svn/text-base/SmileParser.java.svn-base | 2523 --------------------
.../SmileParserBootstrapper.java.svn-base | 274 ---
.../smile/.svn/text-base/SmileUtil.java.svn-base | 46 -
.../smile/.svn/text-base/Tool.java.svn-base | 161 --
.../.svn/text-base/package-info.java.svn-base | 10 -
.../jackson/dataformat/smile/.svn/all-wcprops | 107 -
.../jackson/dataformat/smile/.svn/entries | 606 -----
.../.svn/text-base/SmileTestBase.java.svn-base | 83 -
.../TestGeneratorWithRawUtf8.java.svn-base | 222 --
...TestGeneratorWithSerializedString.java.svn-base | 86 -
.../text-base/TestSmileDetection.java.svn-base | 148 --
.../text-base/TestSmileDocBoundary.java.svn-base | 105 -
.../.svn/text-base/TestSmileFeatures.java.svn-base | 36 -
.../text-base/TestSmileGenerator.java.svn-base | 196 --
.../TestSmileGeneratorBufferRecycle.java.svn-base | 76 -
.../TestSmileGeneratorLongStrings.java.svn-base | 91 -
.../TestSmileGeneratorNumbers.java.svn-base | 128 -
.../TestSmileGeneratorSymbols.java.svn-base | 129 -
.../.svn/text-base/TestSmileParser.java.svn-base | 404 ----
.../text-base/TestSmileParserBinary.java.svn-base | 170 --
.../TestSmileParserLocation.java.svn-base | 61 -
.../text-base/TestSmileParserNumbers.java.svn-base | 301 ---
.../TestSmileParserSymbolHandling.java.svn-base | 560 -----
.../.svn/text-base/TestSmileUtil.java.svn-base | 43 -
30 files changed, 9888 deletions(-)
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops
deleted file mode 100644
index ab54cf7..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops
+++ /dev/null
@@ -1,59 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 70
-/jackson/!svn/ver/2084/trunk/src/smile/java/org/codehaus/jackson/smile
-END
-SmileGenerator.java
-K 25
-svn:wc:ra_dav:version-url
-V 90
-/jackson/!svn/ver/1822/trunk/src/smile/java/org/codehaus/jackson/smile/SmileGenerator.java
-END
-SmileFactory.java
-K 25
-svn:wc:ra_dav:version-url
-V 88
-/jackson/!svn/ver/1961/trunk/src/smile/java/org/codehaus/jackson/smile/SmileFactory.java
-END
-package-info.java
-K 25
-svn:wc:ra_dav:version-url
-V 88
-/jackson/!svn/ver/1552/trunk/src/smile/java/org/codehaus/jackson/smile/package-info.java
-END
-SmileConstants.java
-K 25
-svn:wc:ra_dav:version-url
-V 90
-/jackson/!svn/ver/1440/trunk/src/smile/java/org/codehaus/jackson/smile/SmileConstants.java
-END
-SmileParser.java
-K 25
-svn:wc:ra_dav:version-url
-V 87
-/jackson/!svn/ver/2084/trunk/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
-END
-SmileUtil.java
-K 25
-svn:wc:ra_dav:version-url
-V 84
-/jackson/!svn/ver/883/trunk/src/smile/java/org/codehaus/jackson/smile/SmileUtil.java
-END
-SmileParserBootstrapper.java
-K 25
-svn:wc:ra_dav:version-url
-V 99
-/jackson/!svn/ver/1557/trunk/src/smile/java/org/codehaus/jackson/smile/SmileParserBootstrapper.java
-END
-SmileBufferRecycler.java
-K 25
-svn:wc:ra_dav:version-url
-V 95
-/jackson/!svn/ver/1820/trunk/src/smile/java/org/codehaus/jackson/smile/SmileBufferRecycler.java
-END
-Tool.java
-K 25
-svn:wc:ra_dav:version-url
-V 80
-/jackson/!svn/ver/1217/trunk/src/smile/java/org/codehaus/jackson/smile/Tool.java
-END
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/entries b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/entries
deleted file mode 100644
index a31f2ea..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/entries
+++ /dev/null
@@ -1,334 +0,0 @@
-10
-
-dir
-2123
-https://svn.codehaus.org/jackson/trunk/src/smile/java/org/codehaus/jackson/smile
-https://svn.codehaus.org/jackson
-
-
-
-2011-10-02T08:25:09.487872Z
-2084
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-cc757fca-8a48-0410-80b4-e22f7f27f4c6
-
-SmileGenerator.java
-file
-
-
-
-
-2011-06-30T06:51:34.000000Z
-45067fe5f03340621017c5e93d40ce00
-2011-06-30T06:55:46.785861Z
-1822
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-81747
-
-SmileFactory.java
-file
-
-
-
-
-2011-08-07T06:13:24.000000Z
-5be4f6edd6345ce928dc7bcfbf087bd3
-2011-08-07T07:08:55.481062Z
-1961
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-12535
-
-package-info.java
-file
-
-
-
-
-2011-02-16T01:51:27.000000Z
-df9aa2040683600cadad3c9b8583fabc
-2011-02-16T01:38:31.362386Z
-1552
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-347
-
-SmileConstants.java
-file
-
-
-
-
-2010-12-28T03:14:01.000000Z
-cda4e028b6d9f8dbc15f9c285fb2a612
-2010-12-28T04:47:09.157573Z
-1440
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-13167
-
-SmileParser.java
-file
-
-
-
-
-2011-10-02T08:22:27.000000Z
-7ddc0a873052ca01635e3d69f7622604
-2011-10-02T08:25:09.487872Z
-2084
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-89912
-
-SmileUtil.java
-file
-
-
-
-
-2010-12-11T02:05:40.000000Z
-c08a4428a4be5408883bb111da30ede7
-2010-05-03T06:12:38.603109Z
-883
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1191
-
-SmileParserBootstrapper.java
-file
-
-
-
-
-2011-02-17T06:23:55.000000Z
-f185853d13a5db04e6b7b4b8044452f1
-2011-02-17T06:25:52.717951Z
-1557
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-9564
-
-SmileBufferRecycler.java
-file
-
-
-
-
-2011-06-29T05:38:14.000000Z
-bcd07dbad04c3bdc905c74031a25e089
-2011-06-29T06:27:48.605077Z
-1820
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1535
-
-Tool.java
-file
-
-
-
-
-2010-12-11T02:05:40.000000Z
-8659b4ddd6c35fe139fba6a17f5c39c4
-2010-10-29T20:48:39.404849Z
-1217
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5609
-
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileBufferRecycler.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileBufferRecycler.java.svn-base
deleted file mode 100644
index 35e30f4..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileBufferRecycler.java.svn-base
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.codehaus.jackson.smile;
-
-/**
- * Simple helper class used for implementing simple reuse system for Smile-specific
- * buffers that are used.
- *
- * @param <T> Type of name entries stored in arrays to recycle
- *
- * @since 1.7
- */
-public class SmileBufferRecycler<T>
-{
- public final static int DEFAULT_NAME_BUFFER_LENGTH = 64;
-
- public final static int DEFAULT_STRING_VALUE_BUFFER_LENGTH = 64;
-
- protected T[] _seenNamesBuffer;
-
- protected T[] _seenStringValuesBuffer;
-
- public SmileBufferRecycler() { }
-
- public T[] allocSeenNamesBuffer()
- {
- // 11-Feb-2011, tatu: Used to alloc here; but due to generics, can't easily any more
- T[] result = _seenNamesBuffer;
- if (result != null) {
- // let's ensure we don't retain it here, unless returned
- _seenNamesBuffer = null;
- // note: caller must have cleaned it up before returning
- }
- return result;
- }
-
- public T[] allocSeenStringValuesBuffer()
- {
- // 11-Feb-2011, tatu: Used to alloc here; but due to generics, can't easily any more
- T[] result = _seenStringValuesBuffer;
- if (result != null) {
- _seenStringValuesBuffer = null;
- // note: caller must have cleaned it up before returning
- }
- return result;
- }
-
- public void releaseSeenNamesBuffer(T[] buffer) {
- _seenNamesBuffer = buffer;
- }
-
- public void releaseSeenStringValuesBuffer(T[] buffer) {
- _seenStringValuesBuffer = buffer;
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileConstants.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileConstants.java.svn-base
deleted file mode 100644
index 9e0da3b..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileConstants.java.svn-base
+++ /dev/null
@@ -1,363 +0,0 @@
-package org.codehaus.jackson.smile;
-
-/**
- * Constants used by {@link SmileGenerator} and {@link SmileParser}
- *
- * @author tatu
- */
-public final class SmileConstants
-{
- /*
- /**********************************************************
- /* Thresholds
- /**********************************************************
- */
-
- /**
- * Encoding has special "short" forms for value Strings that can
- * be represented by 64 bytes of UTF-8 or less.
- */
- public final static int MAX_SHORT_VALUE_STRING_BYTES = 64;
-
- /**
- * Encoding has special "short" forms for field names that can
- * be represented by 64 bytes of UTF-8 or less.
- */
- public final static int MAX_SHORT_NAME_ASCII_BYTES = 64;
-
- /**
- * Maximum byte length for short non-ASCII names is slightly
- * less due to having to reserve bytes 0xF8 and above (but
- * we get one more as values 0 and 1 are not valid)
- */
- public final static int MAX_SHORT_NAME_UNICODE_BYTES = 56;
-
- /**
- * Longest back reference we use for field names is 10 bits; no point
- * in keeping much more around
- */
- public final static int MAX_SHARED_NAMES = 1024;
-
- /**
- * Longest back reference we use for short shared String values is 10 bits,
- * so up to (1 << 10) values to keep track of.
- */
- public final static int MAX_SHARED_STRING_VALUES = 1024;
-
- /**
- * Also: whereas we can refer to names of any length, we will only consider
- * text values that are considered "tiny" or "short" (ones encoded with
- * length prefix); this value thereby has to be maximum length of Strings
- * that can be encoded as such.
- */
- public final static int MAX_SHARED_STRING_LENGTH_BYTES = 65;
-
- /**
- * And to make encoding logic tight and simple, we can always
- * require that output buffer has this amount of space
- * available before encoding possibly short String (3 bytes since
- * longest UTF-8 encoded Java char is 3 bytes).
- * Two extra bytes need to be reserved as well; first for token indicator,
- * and second for terminating null byte (in case it's not a short String after all)
- */
- public final static int MIN_BUFFER_FOR_POSSIBLE_SHORT_STRING = 1 + (3 * 65);
-
- /*
- /**********************************************************
- /* Byte markers
- /**********************************************************
- */
-
- /**
- * We need a byte marker to denote end of variable-length Strings. Although
- * null byte is commonly used, let's try to avoid using it since it can't
- * be embedded in Web Sockets content (similarly, 0xFF can't). There are
- * multiple candidates for bytes UTF-8 can not have; 0xFC is chosen to
- * allow reasonable ordering (highest values meaning most significant
- * framing function; 0xFF being end-of-content and so on)
- */
- public final static int INT_MARKER_END_OF_STRING = 0xFC;
-
- public final static byte BYTE_MARKER_END_OF_STRING = (byte) INT_MARKER_END_OF_STRING;
-
- /**
- * In addition we can use a marker to allow simple framing; splitting
- * of physical data (like file) into distinct logical sections like
- * JSON documents. 0xFF makes sense here since it is also used
- * as end marker for Web Sockets.
- */
- public final static byte BYTE_MARKER_END_OF_CONTENT = (byte) 0xFF;
-
- /*
- /**********************************************************
- /* Format header: put smile on your data...
- /**********************************************************
- */
-
- /**
- * First byte of data header
- */
- public final static byte HEADER_BYTE_1 = (byte) ':';
-
- /**
- * Second byte of data header
- */
- public final static byte HEADER_BYTE_2 = (byte) ')';
-
- /**
- * Third byte of data header
- */
- public final static byte HEADER_BYTE_3 = (byte) '\n';
-
- /**
- * Current version consists of four zero bits (nibble)
- */
- public final static int HEADER_VERSION_0 = 0x0;
-
- /**
- * Fourth byte of data header; contains version nibble, may
- * have flags
- */
- public final static byte HEADER_BYTE_4 = (HEADER_VERSION_0 << 4);
-
- /**
- * Indicator bit that indicates whether encoded content may
- * have Shared names (back references to recently encoded field
- * names). If no header available, must be
- * processed as if this was set to true.
- * If (and only if) header exists, and value is 0, can parser
- * omit storing of seen names, as it is guaranteed that no back
- * references exist.
- */
- public final static int HEADER_BIT_HAS_SHARED_NAMES = 0x01;
-
- /**
- * Indicator bit that indicates whether encoded content may
- * have shared String values (back references to recently encoded
- * 'short' String values, where short is defined as 64 bytes or less).
- * If no header available, can be assumed to be 0 (false).
- * If header exists, and bit value is 1, parsers has to store up
- * to 1024 most recently seen distinct short String values.
- */
- public final static int HEADER_BIT_HAS_SHARED_STRING_VALUES = 0x02;
-
- /**
- * Indicator bit that indicates whether encoded content may
- * contain raw (unquoted) binary values.
- * If no header available, can be assumed to be 0 (false).
- * If header exists, and bit value is 1, parser can not assume that
- * specific byte values always have default meaning (specifically,
- * content end marker 0xFF and header signature can be contained
- * in binary values)
- *<p>
- * Note that this bit being true does not automatically mean that
- * such raw binary content indeed exists; just that it may exist.
- * This because header is written before any binary data may be
- * written.
- */
- public final static int HEADER_BIT_HAS_RAW_BINARY = 0x04;
-
- /*
- /**********************************************************
- /* Type prefixes: 3 MSB of token byte
- /**********************************************************
- */
-
- // Shared strings are back references for last 63 short (< 64 byte) string values
- // NOTE: 0x00 is reserved, not used with current version (may be used in future)
- public final static int TOKEN_PREFIX_SHARED_STRING_SHORT = 0x00;
- // literals are put between 0x20 and 0x3F to reserve markers (smiley), along with ints/doubles
- //public final static int TOKEN_PREFIX_MISC_NUMBERS = 0x20;
-
- public final static int TOKEN_PREFIX_TINY_ASCII = 0x40;
- public final static int TOKEN_PREFIX_SMALL_ASCII = 0x60;
- public final static int TOKEN_PREFIX_TINY_UNICODE = 0x80;
- public final static int TOKEN_PREFIX_SHORT_UNICODE = 0xA0;
-
- // Small ints are 4-bit (-16 to +15) integer constants
- public final static int TOKEN_PREFIX_SMALL_INT = 0xC0;
-
- // And misc types have empty at the end too, to reserve 0xF8 - 0xFF
- public final static int TOKEN_PREFIX_MISC_OTHER = 0xE0;
-
- /*
- /**********************************************************
- /* Token literals, normal mode
- /**********************************************************
- */
-
- // First, non-structured literals
-
- public final static byte TOKEN_LITERAL_EMPTY_STRING = 0x20;
- public final static byte TOKEN_LITERAL_NULL = 0x21;
- public final static byte TOKEN_LITERAL_FALSE = 0x22;
- public final static byte TOKEN_LITERAL_TRUE = 0x23;
-
- // And then structured literals
-
- public final static byte TOKEN_LITERAL_START_ARRAY = (byte) 0xF8;
- public final static byte TOKEN_LITERAL_END_ARRAY = (byte) 0xF9;
- public final static byte TOKEN_LITERAL_START_OBJECT = (byte) 0xFA;
- public final static byte TOKEN_LITERAL_END_OBJECT = (byte) 0xFB;
-
- /*
- /**********************************************************
- /* Subtype constants for misc text/binary types
- /**********************************************************
- */
-
- /**
- * Type (for misc, other) used
- * for regular integral types (byte/short/int/long)
- */
- public final static int TOKEN_MISC_INTEGER = 0x24;
-
- /**
- * Type (for misc, other) used
- * for regular floating-point types (float, double)
- */
- public final static int TOKEN_MISC_FP = 0x28;
-
- /**
- * Type (for misc, other) used for
- * variable length UTF-8 encoded text, when it is known to only contain ASCII chars.
- * Note: 2 LSB are reserved for future use; must be zeroes for now
- */
- public final static int TOKEN_MISC_LONG_TEXT_ASCII = 0xE0;
-
- /**
- * Type (for misc, other) used
- * for variable length UTF-8 encoded text, when it is NOT known to only contain ASCII chars
- * (which means it MAY have multi-byte characters)
- * Note: 2 LSB are reserved for future use; must be zeroes for now
- */
- public final static int TOKEN_MISC_LONG_TEXT_UNICODE = 0xE4;
-
- /**
- * Type (for misc, other) used
- * for "safe" (encoded by only using 7 LSB, giving 8/7 expansion ratio).
- * This is usually done to ensure that certain bytes are never included
- * in encoded data (like 0xFF)
- * Note: 2 LSB are reserved for future use; must be zeroes for now
- */
- public final static int TOKEN_MISC_BINARY_7BIT = 0xE8;
-
- /**
- * Type (for misc, other) used for shared String values where index
- * does not fit in "short" reference range (which is 0 - 30). If so,
- * 2 LSB from here and full following byte are used to get 10-bit
- * index. Values
- */
- public final static int TOKEN_MISC_SHARED_STRING_LONG = 0xEC;
-
- /**
- * Raw binary data marker is specifically chosen as separate from
- * other types, since it can have significant impact on framing
- * (or rather fast scanning based on structure and framing markers).
- */
- public final static int TOKEN_MISC_BINARY_RAW = 0xFD;
-
- /*
- /**********************************************************
- /* Modifiers for numeric entries
- /**********************************************************
- */
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_INTEGER},
- * indicating 32-bit integer (int)
- */
- public final static int TOKEN_MISC_INTEGER_32 = 0x00;
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_INTEGER},
- * indicating 32-bit integer (long)
- */
- public final static int TOKEN_MISC_INTEGER_64 = 0x01;
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_INTEGER},
- * indicating {@link java.math.BigInteger} type.
- */
- public final static int TOKEN_MISC_INTEGER_BIG = 0x02;
-
- // Note: type 3 (0xF3) reserved for future use
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_FP},
- * indicating 32-bit IEEE single precision floating point number.
- */
- public final static int TOKEN_MISC_FLOAT_32 = 0x00;
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_FP},
- * indicating 64-bit IEEE double precision floating point number.
- */
- public final static int TOKEN_MISC_FLOAT_64 = 0x01;
-
- /**
- * Numeric subtype (2 LSB) for {@link #TOKEN_MISC_FP},
- * indicating {@link java.math.BigDecimal} type.
- */
- public final static int TOKEN_MISC_FLOAT_BIG = 0x02;
-
- // Note: type 3 (0xF7) reserved for future use
-
- /*
- /**********************************************************
- /* Token types for keys
- /**********************************************************
- */
-
- /**
- * Let's use same code for empty key as for empty String value
- */
- public final static byte TOKEN_KEY_EMPTY_STRING = 0x20;
-
- public final static int TOKEN_PREFIX_KEY_SHARED_LONG = 0x30;
-
- public final static byte TOKEN_KEY_LONG_STRING = 0x34;
-
- public final static int TOKEN_PREFIX_KEY_SHARED_SHORT = 0x40;
-
- public final static int TOKEN_PREFIX_KEY_ASCII = 0x80;
-
- public final static int TOKEN_PREFIX_KEY_UNICODE = 0xC0;
-
- /*
- /**********************************************************
- /* Basic UTF-8 decode/encode table
- /**********************************************************
- */
-
- /**
- * Additionally we can combine UTF-8 decoding info into similar
- * data table.
- * Values indicate "byte length - 1"; meaning -1 is used for
- * invalid bytes, 0 for single-byte codes, 1 for 2-byte codes
- * and 2 for 3-byte codes.
- */
- public final static int[] sUtf8UnitLengths;
- static {
- int[] table = new int[256];
- for (int c = 128; c < 256; ++c) {
- int code;
-
- // We'll add number of bytes needed for decoding
- if ((c & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF)
- code = 1;
- } else if ((c & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF)
- code = 2;
- } else if ((c & 0xF8) == 0xF0) {
- // 4 bytes; double-char with surrogates and all...
- code = 3;
- } else {
- // And -1 seems like a good "universal" error marker...
- code = -1;
- }
- table[c] = code;
- }
- sUtf8UnitLengths = table;
- }
-}
-
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileFactory.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileFactory.java.svn-base
deleted file mode 100644
index b48a62f..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileFactory.java.svn-base
+++ /dev/null
@@ -1,381 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.net.URL;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.format.InputAccessor;
-import org.codehaus.jackson.format.MatchStrength;
-import org.codehaus.jackson.io.IOContext;
-
-/**
- * Factory used for constructing {@link SmileParser} and {@link SmileGenerator}
- * instances; both of which handle
- * <a href="http://wiki.fasterxml.com/SmileFormat">Smile</a> encoded data.
- *<p>
- * Extends {@link JsonFactory} mostly so that users can actually use it in place
- * of regular non-Smile factory instances.
- *<p>
- * Note on using non-byte-based sources/targets (char based, like
- * {@link java.io.Reader} and {@link java.io.Writer}): these can not be
- * used for Smile-format documents, and thus will either downgrade to
- * textual JSON (when parsing), or throw exception (when trying to create
- * generator).
- *
- * @author tatu
- *
- * @since 1.6
- */
-public class SmileFactory extends JsonFactory
-{
- /**
- * Name used to identify Smile format.
- * (and returned by {@link #getFormatName()}
- */
- public final static String FORMAT_NAME_SMILE = "Smile";
-
- /**
- * Bitfield (set of flags) of all parser features that are enabled
- * by default.
- */
- final static int DEFAULT_SMILE_PARSER_FEATURE_FLAGS = SmileParser.Feature.collectDefaults();
-
- /**
- * Bitfield (set of flags) of all generator features that are enabled
- * by default.
- */
- final static int DEFAULT_SMILE_GENERATOR_FEATURE_FLAGS = SmileGenerator.Feature.collectDefaults();
-
- /*
- /**********************************************************
- /* Configuration
- /**********************************************************
- */
-
- /**
- * Whether non-supported methods (ones trying to output using
- * char-based targets like {@link java.io.Writer}, for example)
- * should be delegated to regular Jackson JSON processing
- * (if set to true); or throw {@link UnsupportedOperationException}
- * (if set to false)
- */
- protected boolean _cfgDelegateToTextual;
-
- protected int _smileParserFeatures = DEFAULT_SMILE_PARSER_FEATURE_FLAGS;
-
- protected int _smileGeneratorFeatures = DEFAULT_SMILE_GENERATOR_FEATURE_FLAGS;
-
- /*
- /**********************************************************
- /* Factory construction, configuration
- /**********************************************************
- */
-
- /**
- * Default constructor used to create factory instances.
- * Creation of a factory instance is a light-weight operation,
- * but it is still a good idea to reuse limited number of
- * factory instances (and quite often just a single instance):
- * factories are used as context for storing some reused
- * processing objects (such as symbol tables parsers use)
- * and this reuse only works within context of a single
- * factory instance.
- */
- public SmileFactory() { this(null); }
-
- public SmileFactory(ObjectCodec oc) { super(oc); }
-
- public void delegateToTextual(boolean state) {
- _cfgDelegateToTextual = state;
- }
-
- /*
- /**********************************************************
- /* Format detection functionality (since 1.8)
- /**********************************************************
- */
-
- @Override
- public String getFormatName()
- {
- return FORMAT_NAME_SMILE;
- }
-
- /**
- * Sub-classes need to override this method (as of 1.8)
- */
- @Override
- public MatchStrength hasFormat(InputAccessor acc) throws IOException
- {
- return SmileParserBootstrapper.hasSmileFormat(acc);
- }
-
- /*
- /**********************************************************
- /* Configuration, parser settings
- /**********************************************************
- */
-
- /**
- * Method for enabling or disabling specified parser feature
- * (check {@link SmileParser.Feature} for list of features)
- */
- public final SmileFactory configure(SmileParser.Feature f, boolean state)
- {
- if (state) {
- enable(f);
- } else {
- disable(f);
- }
- return this;
- }
-
- /**
- * Method for enabling specified parser feature
- * (check {@link SmileParser.Feature} for list of features)
- */
- public SmileFactory enable(SmileParser.Feature f) {
- _smileParserFeatures |= f.getMask();
- return this;
- }
-
- /**
- * Method for disabling specified parser features
- * (check {@link SmileParser.Feature} for list of features)
- */
- public SmileFactory disable(SmileParser.Feature f) {
- _smileParserFeatures &= ~f.getMask();
- return this;
- }
-
- /**
- * Checked whether specified parser feature is enabled.
- */
- public final boolean isEnabled(SmileParser.Feature f) {
- return (_smileParserFeatures & f.getMask()) != 0;
- }
-
- /*
- /**********************************************************
- /* Configuration, generator settings
- /**********************************************************
- */
-
- /**
- * Method for enabling or disabling specified generator feature
- * (check {@link org.codehaus.jackson.JsonGenerator.Feature} for list of features)
- *
- * @since 1.2
- */
- public final SmileFactory configure(SmileGenerator.Feature f, boolean state) {
- if (state) {
- enable(f);
- } else {
- disable(f);
- }
- return this;
- }
-
-
- /**
- * Method for enabling specified generator features
- * (check {@link org.codehaus.jackson.JsonGenerator.Feature} for list of features)
- */
- public SmileFactory enable(SmileGenerator.Feature f) {
- _smileGeneratorFeatures |= f.getMask();
- return this;
- }
-
- /**
- * Method for disabling specified generator feature
- * (check {@link org.codehaus.jackson.JsonGenerator.Feature} for list of features)
- */
- public SmileFactory disable(SmileGenerator.Feature f) {
- _smileGeneratorFeatures &= ~f.getMask();
- return this;
- }
-
- /**
- * Check whether specified generator feature is enabled.
- */
- public final boolean isEnabled(SmileGenerator.Feature f) {
- return (_smileGeneratorFeatures & f.getMask()) != 0;
- }
-
- /*
- /**********************************************************
- /* Overridden parser factory methods
- /**********************************************************
- */
-
- @Override
- public SmileParser createJsonParser(File f)
- throws IOException, JsonParseException
- {
- return _createJsonParser(new FileInputStream(f), _createContext(f, true));
- }
-
- @Override
- public SmileParser createJsonParser(URL url)
- throws IOException, JsonParseException
- {
- return _createJsonParser(_optimizedStreamFromURL(url), _createContext(url, true));
- }
-
- @Override
- public SmileParser createJsonParser(InputStream in)
- throws IOException, JsonParseException
- {
- return _createJsonParser(in, _createContext(in, false));
- }
-
- //public JsonParser createJsonParser(Reader r)
-
- @Override
- public SmileParser createJsonParser(byte[] data)
- throws IOException, JsonParseException
- {
- IOContext ctxt = _createContext(data, true);
- return _createJsonParser(data, 0, data.length, ctxt);
- }
-
- @Override
- public SmileParser createJsonParser(byte[] data, int offset, int len)
- throws IOException, JsonParseException
- {
- return _createJsonParser(data, offset, len, _createContext(data, true));
- }
-
- /*
- /**********************************************************
- /* Overridden generator factory methods
- /**********************************************************
- */
-
- /**
- *<p>
- * note: co-variant return type
- */
- @Override
- public SmileGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
- throws IOException
- {
- return createJsonGenerator(out);
- }
-
- /**
- * Since Smile format always uses UTF-8 internally, no encoding need
- * to be passed to this method.
- */
- @Override
- public SmileGenerator createJsonGenerator(OutputStream out) throws IOException
- {
- // false -> we won't manage the stream unless explicitly directed to
- IOContext ctxt = _createContext(out, false);
- return _createJsonGenerator(out, ctxt);
- }
-
- /*
- /******************************************************
- /* Overridden internal factory methods
- /******************************************************
- */
-
- //protected IOContext _createContext(Object srcRef, boolean resourceManaged)
-
- /**
- * Overridable factory method that actually instantiates desired
- * parser.
- */
- @Override
- protected SmileParser _createJsonParser(InputStream in, IOContext ctxt)
- throws IOException, JsonParseException
- {
- return new SmileParserBootstrapper(ctxt, in).constructParser(_parserFeatures,
- _smileParserFeatures, _objectCodec, _rootByteSymbols);
- }
-
- /**
- * Overridable factory method that actually instantiates desired
- * parser.
- */
- @Override
- protected JsonParser _createJsonParser(Reader r, IOContext ctxt)
- throws IOException, JsonParseException
- {
- if (_cfgDelegateToTextual) {
- return super._createJsonParser(r, ctxt);
- }
- throw new UnsupportedOperationException("Can not create generator for non-byte-based target");
- }
-
- /**
- * Overridable factory method that actually instantiates desired
- * parser.
- */
- @Override
- protected SmileParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt)
- throws IOException, JsonParseException
- {
- return new SmileParserBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
- _smileParserFeatures, _objectCodec, _rootByteSymbols);
- }
-
- /**
- * Overridable factory method that actually instantiates desired
- * generator.
- */
- @Override
- protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
- throws IOException
- {
- if (_cfgDelegateToTextual) {
- return super._createJsonGenerator(out, ctxt);
- }
- throw new UnsupportedOperationException("Can not create generator for non-byte-based target");
- }
-
- //public BufferRecycler _getBufferRecycler()
-
- @Override
- protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
- {
- if (_cfgDelegateToTextual) {
- return super._createWriter(out, enc, ctxt);
- }
- throw new UnsupportedOperationException("Can not create generator for non-byte-based target");
- }
-
- /*
- /**********************************************************
- /* Internal methods
- /**********************************************************
- */
-
- protected SmileGenerator _createJsonGenerator(OutputStream out, IOContext ctxt)
- throws IOException
- {
- int feats = _smileGeneratorFeatures;
- /* One sanity check: MUST write header if shared string values setting is enabled,
- * or quoting of binary data disabled.
- * But should we force writing, or throw exception, if settings are in conflict?
- * For now, let's error out...
- */
- SmileGenerator gen = new SmileGenerator(ctxt, _generatorFeatures, feats, _objectCodec, out);
- if ((feats & SmileGenerator.Feature.WRITE_HEADER.getMask()) != 0) {
- gen.writeHeader();
- } else {
- if ((feats & SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES.getMask()) != 0) {
- throw new JsonGenerationException(
- "Inconsistent settings: WRITE_HEADER disabled, but CHECK_SHARED_STRING_VALUES enabled; can not construct generator"
- +" due to possible data loss (either enable WRITE_HEADER, or disable CHECK_SHARED_STRING_VALUES to resolve)");
- }
- if ((feats & SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT.getMask()) == 0) {
- throw new JsonGenerationException(
- "Inconsistent settings: WRITE_HEADER disabled, but ENCODE_BINARY_AS_7BIT disabled; can not construct generator"
- +" due to possible data loss (either enable WRITE_HEADER, or ENCODE_BINARY_AS_7BIT to resolve)");
- }
- }
- return gen;
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileGenerator.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileGenerator.java.svn-base
deleted file mode 100644
index d1c8cdd..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileGenerator.java.svn-base
+++ /dev/null
@@ -1,2132 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.lang.ref.SoftReference;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.io.IOContext;
-import org.codehaus.jackson.io.SerializedString;
-import org.codehaus.jackson.impl.JsonGeneratorBase;
-import org.codehaus.jackson.impl.JsonWriteContext;
-
-import static org.codehaus.jackson.smile.SmileConstants.*;
-
-/**
- * {@link JsonGenerator} implementation for the experimental "Binary JSON Infoset".
- *
- * @author tatu
- */
-public class SmileGenerator
- extends JsonGeneratorBase
-{
- /**
- * Enumeration that defines all togglable features for Smile generators.
- */
- public enum Feature {
- /**
- * Whether to write 4-byte header sequence when starting output or not.
- * If disabled, no header is written; this may be useful in embedded cases
- * where context is enough to know that content is encoded using this format.
- * Note, however, that omitting header means that default settings for
- * shared names/string values can not be changed.
- *<p>
- * Default setting is true, meaning that header will be written.
- */
- WRITE_HEADER(true),
-
- /**
- * Whether write byte marker that signifies end of logical content segment
- * ({@link SmileConstants#BYTE_MARKER_END_OF_CONTENT}) when
- * {@link #close} is called or not. This can be useful when outputting
- * multiple adjacent logical content segments (documents) into single
- * physical output unit (file).
- *<p>
- * Default setting is false meaning that such marker is not written.
- */
- WRITE_END_MARKER(false),
-
- /**
- * Whether to use simple 7-bit per byte encoding for binary content when output.
- * This is necessary ensure that byte 0xFF will never be included in content output.
- * For other data types this limitation is handled automatically; but since overhead
- * for binary data (14% size expansion, processing overhead) is non-negligible,
- * it is not enabled by default. If no binary data is output, feature has no effect.
- *<p>
- * Default setting is true, indicating that binary data is quoted as 7-bit bytes
- * instead of written raw.
- */
- ENCODE_BINARY_AS_7BIT(true),
-
- /**
- * Whether generator should check if it can "share" field names during generating
- * content or not. If enabled, can replace repeating field names with back references,
- * which are more compact and should faster to decode. Downside is that there is some
- * overhead for writing (need to track existing values, check), as well as decoding.
- *<p>
- * Since field names tend to repeat quite often, this setting is enabled by default.
- */
- CHECK_SHARED_NAMES(true),
-
- /**
- * Whether generator should check if it can "share" short (at most 64 bytes encoded)
- * String value during generating
- * content or not. If enabled, can replace repeating Short String values with back references,
- * which are more compact and should faster to decode. Downside is that there is some
- * overhead for writing (need to track existing values, check), as well as decoding.
- *<p>
- * Since efficiency of this option depends a lot on type of content being produced,
- * this option is disabled by default, and should only be enabled if it is likely that
- * same values repeat relatively often.
- */
- CHECK_SHARED_STRING_VALUES(false)
- ;
-
- protected final boolean _defaultState;
- protected final int _mask;
-
- /**
- * Method that calculates bit set (flags) of all features that
- * are enabled by default.
- */
- public static int collectDefaults()
- {
- int flags = 0;
- for (Feature f : values()) {
- if (f.enabledByDefault()) {
- flags |= f.getMask();
- }
- }
- return flags;
- }
-
- private Feature(boolean defaultState) {
- _defaultState = defaultState;
- _mask = (1 << ordinal());
- }
-
- public boolean enabledByDefault() { return _defaultState; }
- public int getMask() { return _mask; }
- }
-
- /**
- * Helper class used for keeping track of possibly shareable String
- * references (for field names and/or short String values)
- */
- protected final static class SharedStringNode
- {
- public final String value;
- public final int index;
- public SharedStringNode next;
-
- public SharedStringNode(String value, int index, SharedStringNode next)
- {
- this.value = value;
- this.index = index;
- this.next = next;
- }
- }
-
- /**
- * To simplify certain operations, we require output buffer length
- * to allow outputting of contiguous 256 character UTF-8 encoded String
- * value. Length of the longest UTF-8 code point (from Java char) is 3 bytes,
- * and we need both initial token byte and single-byte end marker
- * so we get following value.
- *<p>
- * Note: actually we could live with shorter one; absolute minimum would
- * be for encoding 64-character Strings.
- */
- private final static int MIN_BUFFER_LENGTH = (3 * 256) + 2;
-
- protected final static byte TOKEN_BYTE_LONG_STRING_ASCII = (byte) TOKEN_MISC_LONG_TEXT_ASCII;
- protected final static byte TOKEN_BYTE_LONG_STRING_UNICODE = (byte) TOKEN_MISC_LONG_TEXT_UNICODE;
-
- protected final static byte TOKEN_BYTE_INT_32 = (byte) (TOKEN_MISC_INTEGER | TOKEN_MISC_INTEGER_32);
- protected final static byte TOKEN_BYTE_INT_64 = (byte) (TOKEN_MISC_INTEGER | TOKEN_MISC_INTEGER_64);
- protected final static byte TOKEN_BYTE_BIG_INTEGER = (byte) (TOKEN_MISC_INTEGER | TOKEN_MISC_INTEGER_BIG);
-
- protected final static byte TOKEN_BYTE_FLOAT_32 = (byte) (TOKEN_MISC_FP | TOKEN_MISC_FLOAT_32);
- protected final static byte TOKEN_BYTE_FLOAT_64 = (byte) (TOKEN_MISC_FP | TOKEN_MISC_FLOAT_64);
- protected final static byte TOKEN_BYTE_BIG_DECIMAL = (byte) (TOKEN_MISC_FP | TOKEN_MISC_FLOAT_BIG);
-
- protected final static int SURR1_FIRST = 0xD800;
- protected final static int SURR1_LAST = 0xDBFF;
- protected final static int SURR2_FIRST = 0xDC00;
- protected final static int SURR2_LAST = 0xDFFF;
-
- protected final static long MIN_INT_AS_LONG = (long) Integer.MIN_VALUE;
- protected final static long MAX_INT_AS_LONG = (long) Integer.MAX_VALUE;
-
- /*
- /**********************************************************
- /* Configuration
- /**********************************************************
- */
-
- final protected IOContext _ioContext;
-
- final protected OutputStream _out;
-
- /**
- * Bit flag composed of bits that indicate which
- * {@link org.codehaus.jackson.smile.SmileGenerator.Feature}s
- * are enabled.
- */
- protected int _smileFeatures;
-
- /**
- * Helper object used for low-level recycling of Smile-generator
- * specific buffers.
- *
- * @since 1.7
- */
- final protected SmileBufferRecycler<SharedStringNode> _smileBufferRecycler;
-
- /*
- /**********************************************************
- /* Output buffering
- /**********************************************************
- */
-
- /**
- * Intermediate buffer in which contents are buffered before
- * being written using {@link #_out}.
- */
- protected byte[] _outputBuffer;
-
- /**
- * Pointer to the next available byte in {@link #_outputBuffer}
- */
- protected int _outputTail = 0;
-
- /**
- * Offset to index after the last valid index in {@link #_outputBuffer}.
- * Typically same as length of the buffer.
- */
- protected final int _outputEnd;
-
- /**
- * Intermediate buffer in which characters of a String are copied
- * before being encoded.
- */
- protected char[] _charBuffer;
-
- protected final int _charBufferLength;
-
- /**
- * Let's keep track of how many bytes have been output, may prove useful
- * when debugging. This does <b>not</b> include bytes buffered in
- * the output buffer, just bytes that have been written using underlying
- * stream writer.
- */
- protected int _bytesWritten;
-
- /*
- /**********************************************************
- /* Shared String detection
- /**********************************************************
- */
-
- /**
- * Raw data structure used for checking whether field name to
- * write can be output using back reference or not.
- */
- protected SharedStringNode[] _seenNames;
-
- /**
- * Number of entries in {@link #_seenNames}; -1 if no shared name
- * detection is enabled
- */
- protected int _seenNameCount;
-
- /**
- * Raw data structure used for checking whether String value to
- * write can be output using back reference or not.
- */
- protected SharedStringNode[] _seenStringValues;
-
- /**
- * Number of entries in {@link #_seenStringValues}; -1 if no shared text value
- * detection is enabled
- */
- protected int _seenStringValueCount;
-
- /**
- * Flag that indicates whether the output buffer is recycable (and
- * needs to be returned to recycler once we are done) or not.
- */
- protected boolean _bufferRecyclable;
-
- /*
- /**********************************************************
- /* Thread-local recycling
- /**********************************************************
- */
-
- /**
- * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftRerefence}
- * to a buffer recycler used to provide a low-cost
- * buffer recycling for Smile-specific buffers.
- */
- final protected static ThreadLocal<SoftReference<SmileBufferRecycler<SharedStringNode>>> _smileRecyclerRef
- = new ThreadLocal<SoftReference<SmileBufferRecycler<SharedStringNode>>>();
-
- /*
- /**********************************************************
- /* Life-cycle
- /**********************************************************
- */
-
- public SmileGenerator(IOContext ctxt, int jsonFeatures, int smileFeatures,
- ObjectCodec codec, OutputStream out)
- {
- super(jsonFeatures, codec);
- _smileFeatures = smileFeatures;
- _ioContext = ctxt;
- _smileBufferRecycler = _smileBufferRecycler();
- _out = out;
- _bufferRecyclable = true;
- _outputBuffer = ctxt.allocWriteEncodingBuffer();
- _outputEnd = _outputBuffer.length;
- _charBuffer = ctxt.allocConcatBuffer();
- _charBufferLength = _charBuffer.length;
- // let's just sanity check to prevent nasty odd errors
- if (_outputEnd < MIN_BUFFER_LENGTH) {
- throw new IllegalStateException("Internal encoding buffer length ("+_outputEnd
- +") too short, must be at least "+MIN_BUFFER_LENGTH);
- }
- if ((smileFeatures & Feature.CHECK_SHARED_NAMES.getMask()) == 0) {
- _seenNames = null;
- _seenNameCount = -1;
- } else {
- _seenNames = _smileBufferRecycler.allocSeenNamesBuffer();
- if (_seenNames == null) {
- _seenNames = new SharedStringNode[SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH];
- }
- _seenNameCount = 0;
- }
-
- if ((smileFeatures & Feature.CHECK_SHARED_STRING_VALUES.getMask()) == 0) {
- _seenStringValues = null;
- _seenStringValueCount = -1;
- } else {
- _seenStringValues = _smileBufferRecycler.allocSeenStringValuesBuffer();
- if (_seenStringValues == null) {
- _seenStringValues = new SharedStringNode[SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH];
- }
- _seenStringValueCount = 0;
- }
-}
-
- public SmileGenerator(IOContext ctxt, int jsonFeatures, int smileFeatures,
- ObjectCodec codec, OutputStream out, byte[] outputBuffer, int offset, boolean bufferRecyclable)
- {
- super(jsonFeatures, codec);
- _smileFeatures = smileFeatures;
- _ioContext = ctxt;
- _smileBufferRecycler = _smileBufferRecycler();
- _out = out;
- _bufferRecyclable = bufferRecyclable;
- _outputTail = offset;
- _outputBuffer = outputBuffer;
- _outputEnd = _outputBuffer.length;
- _charBuffer = ctxt.allocConcatBuffer();
- _charBufferLength = _charBuffer.length;
- // let's just sanity check to prevent nasty odd errors
- if (_outputEnd < MIN_BUFFER_LENGTH) {
- throw new IllegalStateException("Internal encoding buffer length ("+_outputEnd
- +") too short, must be at least "+MIN_BUFFER_LENGTH);
- }
- if ((smileFeatures & Feature.CHECK_SHARED_NAMES.getMask()) == 0) {
- _seenNames = null;
- _seenNameCount = -1;
- } else {
- _seenNames = _smileBufferRecycler.allocSeenNamesBuffer();
- if (_seenNames == null) {
- _seenNames = new SharedStringNode[SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH];
- }
- _seenNameCount = 0;
- }
-
- if ((smileFeatures & Feature.CHECK_SHARED_STRING_VALUES.getMask()) == 0) {
- _seenStringValues = null;
- _seenStringValueCount = -1;
- } else {
- _seenStringValues = _smileBufferRecycler.allocSeenStringValuesBuffer();
- if (_seenStringValues == null) {
- _seenStringValues = new SharedStringNode[SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH];
- }
- _seenStringValueCount = 0;
- }
- }
-
- /**
- * Method that can be called to explicitly write Smile document header.
- * Note that usually you do not need to call this for first document to output,
- * but rather only if you intend to write multiple root-level documents
- * with same generator (and even in that case this is optional thing to do).
- * As a result usually only {@link SmileFactory} calls this method.
- */
- public void writeHeader() throws IOException
- {
- int last = HEADER_BYTE_4;
- if ((_smileFeatures & Feature.CHECK_SHARED_NAMES.getMask()) != 0) {
- last |= SmileConstants.HEADER_BIT_HAS_SHARED_NAMES;
- }
- if ((_smileFeatures & Feature.CHECK_SHARED_STRING_VALUES.getMask()) != 0) {
- last |= SmileConstants.HEADER_BIT_HAS_SHARED_STRING_VALUES;
- }
- if ((_smileFeatures & Feature.ENCODE_BINARY_AS_7BIT.getMask()) == 0) {
- last |= SmileConstants.HEADER_BIT_HAS_RAW_BINARY;
- }
- _writeBytes(HEADER_BYTE_1, HEADER_BYTE_2, HEADER_BYTE_3, (byte) last);
- }
-
- protected final static SmileBufferRecycler<SharedStringNode> _smileBufferRecycler()
- {
- SoftReference<SmileBufferRecycler<SharedStringNode>> ref = _smileRecyclerRef.get();
- SmileBufferRecycler<SharedStringNode> br = (ref == null) ? null : ref.get();
-
- if (br == null) {
- br = new SmileBufferRecycler<SharedStringNode>();
- _smileRecyclerRef.set(new SoftReference<SmileBufferRecycler<SharedStringNode>>(br));
- }
- return br;
- }
-
- /*
- /**********************************************************
- /* Overridden methods, configuration
- /**********************************************************
- */
-
- /**
- * No way (or need) to indent anything, so let's block any attempts.
- * (should we throw an exception instead?)
- */
- @Override
- public JsonGenerator useDefaultPrettyPrinter()
- {
- return this;
- }
-
- /**
- * No way (or need) to indent anything, so let's block any attempts.
- * (should we throw an exception instead?)
- */
- @Override
- public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
- return this;
- }
-
- @Override
- public Object getOutputTarget() {
- return _out;
- }
-
- /*
- /**********************************************************
- /* Overridden methods, write methods
- /**********************************************************
- */
-
- /* And then methods overridden to make final, streamline some
- * aspects...
- */
-
- @Override
- public final void writeFieldName(String name) throws IOException, JsonGenerationException
- {
- if (_writeContext.writeFieldName(name) == JsonWriteContext.STATUS_EXPECT_VALUE) {
- _reportError("Can not write a field name, expecting a value");
- }
- _writeFieldName(name);
- }
-
- @Override
- public final void writeFieldName(SerializedString name)
- throws IOException, JsonGenerationException
- {
- // Object is a value, need to verify it's allowed
- if (_writeContext.writeFieldName(name.getValue()) == JsonWriteContext.STATUS_EXPECT_VALUE) {
- _reportError("Can not write a field name, expecting a value");
- }
- _writeFieldName(name);
- }
-
- @Override
- public final void writeFieldName(SerializableString name)
- throws IOException, JsonGenerationException
- {
- // Object is a value, need to verify it's allowed
- if (_writeContext.writeFieldName(name.getValue()) == JsonWriteContext.STATUS_EXPECT_VALUE) {
- _reportError("Can not write a field name, expecting a value");
- }
- _writeFieldName(name);
- }
-
- @Override
- public final void writeStringField(String fieldName, String value)
- throws IOException, JsonGenerationException
- {
- if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) {
- _reportError("Can not write a field name, expecting a value");
- }
- _writeFieldName(fieldName);
- writeString(value);
- }
-
- /*
- /**********************************************************
- /* Extended API, configuration
- /**********************************************************
- */
-
- public SmileGenerator enable(Feature f) {
- _smileFeatures |= f.getMask();
- return this;
- }
-
- public SmileGenerator disable(Feature f) {
- _smileFeatures &= ~f.getMask();
- return this;
- }
-
- public final boolean isEnabled(Feature f) {
- return (_smileFeatures & f.getMask()) != 0;
- }
-
- public SmileGenerator configure(Feature f, boolean state) {
- if (state) {
- enable(f);
- } else {
- disable(f);
- }
- return this;
- }
-
- /*
- /**********************************************************
- /* Extended API, other
- /**********************************************************
- */
-
- /**
- * Method for directly inserting specified byte in output at
- * current position.
- *<p>
- * NOTE: only use this method if you really know what you are doing.
- */
- public void writeRaw(byte b) throws IOException, JsonGenerationException
- {
- _writeByte(TOKEN_LITERAL_START_ARRAY);
- }
-
- /**
- * Method for directly inserting specified bytes in output at
- * current position.
- *<p>
- * NOTE: only use this method if you really know what you are doing.
- */
- public void writeBytes(byte[] data, int offset, int len) throws IOException
- {
- _writeBytes(data, offset, len);
- }
-
- /*
- /**********************************************************
- /* Output method implementations, structural
- /**********************************************************
- */
-
- @Override
- public final void writeStartArray() throws IOException, JsonGenerationException
- {
- _verifyValueWrite("start an array");
- _writeContext = _writeContext.createChildArrayContext();
- _writeByte(TOKEN_LITERAL_START_ARRAY);
- }
-
- @Override
- public final void writeEndArray() throws IOException, JsonGenerationException
- {
- if (!_writeContext.inArray()) {
- _reportError("Current context not an ARRAY but "+_writeContext.getTypeDesc());
- }
- _writeByte(TOKEN_LITERAL_END_ARRAY);
- _writeContext = _writeContext.getParent();
- }
-
- @Override
- public final void writeStartObject() throws IOException, JsonGenerationException
- {
- _verifyValueWrite("start an object");
- _writeContext = _writeContext.createChildObjectContext();
- _writeByte(TOKEN_LITERAL_START_OBJECT);
- }
-
- @Override
- public final void writeEndObject() throws IOException, JsonGenerationException
- {
- if (!_writeContext.inObject()) {
- _reportError("Current context not an object but "+_writeContext.getTypeDesc());
- }
- _writeContext = _writeContext.getParent();
- _writeByte(TOKEN_LITERAL_END_OBJECT);
- }
-
- private final void _writeFieldName(String name)
- throws IOException, JsonGenerationException
- {
- int len = name.length();
- if (len == 0) {
- _writeByte(TOKEN_KEY_EMPTY_STRING);
- return;
- }
- // First: is it something we can share?
- if (_seenNameCount >= 0) {
- int ix = _findSeenName(name);
- if (ix >= 0) {
- _writeSharedNameReference(ix);
- return;
- }
- }
- if (len > MAX_SHORT_NAME_UNICODE_BYTES) { // can not be a 'short' String; off-line (rare case)
- _writeNonShortFieldName(name, len);
- return;
- }
-
- // first: ensure we have enough space
- if ((_outputTail + MIN_BUFFER_FOR_POSSIBLE_SHORT_STRING) >= _outputEnd) {
- _flushBuffer();
- }
- // then let's copy String chars to char buffer, faster than using getChar (measured, profiled)
- name.getChars(0, len, _charBuffer, 0);
- int origOffset = _outputTail;
- ++_outputTail; // to reserve space for type token
- int byteLen = _shortUTF8Encode(_charBuffer, 0, len);
- byte typeToken;
-
- // ASCII?
- if (byteLen == len) {
- if (byteLen <= MAX_SHORT_NAME_ASCII_BYTES) { // yes, is short indeed
- typeToken = (byte) ((TOKEN_PREFIX_KEY_ASCII - 1) + byteLen);
- } else { // longer albeit ASCII
- typeToken = TOKEN_KEY_LONG_STRING;
- // and we will need String end marker byte
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
- } else { // not all ASCII
- if (byteLen <= MAX_SHORT_NAME_UNICODE_BYTES) { // yes, is short indeed
- // note: since 2 is smaller allowed length, offset differs from one used for
- typeToken = (byte) ((TOKEN_PREFIX_KEY_UNICODE - 2) + byteLen);
- } else { // nope, longer non-ASCII Strings
- typeToken = TOKEN_KEY_LONG_STRING;
- // and we will need String end marker byte
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
- }
- // and then sneak in type token now that know the details
- _outputBuffer[origOffset] = typeToken;
- // Also, keep track if we can use back-references (shared names)
- if (_seenNameCount >= 0) {
- _addSeenName(name);
- }
- }
-
- private final void _writeNonShortFieldName(final String name, final int len)
- throws IOException, JsonGenerationException
- {
- _writeByte(TOKEN_KEY_LONG_STRING);
- // can we still make a temp copy?
- if (len > _charBufferLength) { // nah, not even that
- _slowUTF8Encode(name);
- } else { // yep.
- name.getChars(0, len, _charBuffer, 0);
- // but will encoded version fit in buffer?
- int maxLen = len + len + len;
- if (maxLen <= _outputBuffer.length) { // yes indeed
- if ((_outputTail + maxLen) >= _outputEnd) {
- _flushBuffer();
- }
- _shortUTF8Encode(_charBuffer, 0, len);
- } else { // nope, need bit slower variant
- _mediumUTF8Encode(_charBuffer, 0, len);
- }
- }
- if (_seenNameCount >= 0) {
- _addSeenName(name);
- }
- if (_outputTail >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
-
- protected final void _writeFieldName(SerializableString name)
- throws IOException, JsonGenerationException
- {
- final int charLen = name.charLength();
- if (charLen == 0) {
- _writeByte(TOKEN_KEY_EMPTY_STRING);
- return;
- }
- final byte[] bytes = name.asUnquotedUTF8();
- final int byteLen = bytes.length;
- if (byteLen != charLen) {
- _writeFieldNameUnicode(name, bytes);
- return;
- }
- // Then: is it something we can share?
- if (_seenNameCount >= 0) {
- int ix = _findSeenName(name.getValue());
- if (ix >= 0) {
- _writeSharedNameReference(ix);
- return;
- }
- }
-
- // Common case: short ASCII name that fits in buffer as is
- if (byteLen <= MAX_SHORT_NAME_ASCII_BYTES) {
- // output buffer is bigger than what we need, always, so
- if ((_outputTail + byteLen) >= _outputEnd) { // need marker byte and actual bytes
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = (byte) ((TOKEN_PREFIX_KEY_ASCII - 1) + byteLen);
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- } else {
- _writeLongAsciiFieldName(bytes);
- }
- // Also, keep track if we can use back-references (shared names)
- if (_seenNameCount >= 0) {
- _addSeenName(name.getValue());
- }
- }
-
- private final void _writeLongAsciiFieldName(byte[] bytes)
- throws IOException, JsonGenerationException
- {
- final int byteLen = bytes.length;
- if (_outputTail >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = TOKEN_KEY_LONG_STRING;
- // Ok. Enough room?
- if ((_outputTail + byteLen + 1) < _outputEnd) {
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- } else {
- _flushBuffer();
- // either way, do intermediate copy if name is relatively short
- // Need to copy?
- if (byteLen < MIN_BUFFER_LENGTH) {
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- } else {
- // otherwise, just write as is
- if (_outputTail > 0) {
- _flushBuffer();
- }
- _out.write(bytes, 0, byteLen);
- }
- }
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
-
- protected final void _writeFieldNameUnicode(SerializableString name, byte[] bytes)
- throws IOException, JsonGenerationException
- {
- // Then: is it something we can share?
- if (_seenNameCount >= 0) {
- int ix = _findSeenName(name.getValue());
- if (ix >= 0) {
- _writeSharedNameReference(ix);
- return;
- }
- }
-
- final int byteLen = bytes.length;
-
- // Common case: short Unicode name that fits in output buffer
- if (byteLen <= MAX_SHORT_NAME_UNICODE_BYTES) {
- if ((_outputTail + byteLen) >= _outputEnd) { // need marker byte and actual bytes
- _flushBuffer();
- }
- // note: since 2 is smaller allowed length, offset differs from one used for
- _outputBuffer[_outputTail++] = (byte) ((TOKEN_PREFIX_KEY_UNICODE - 2) + byteLen);
-
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- // Also, keep track if we can use back-references (shared names)
- if (_seenNameCount >= 0) {
- _addSeenName(name.getValue());
- }
- return;
- }
- if (_outputTail >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = TOKEN_KEY_LONG_STRING;
- // Ok. Enough room?
- if ((_outputTail + byteLen + 1) < _outputEnd) {
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- } else {
- _flushBuffer();
- // either way, do intermediate copy if name is relatively short
- // Need to copy?
- if (byteLen < MIN_BUFFER_LENGTH) {
- System.arraycopy(bytes, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- } else {
- // otherwise, just write as is
- if (_outputTail > 0) {
- _flushBuffer();
- }
- _out.write(bytes, 0, byteLen);
- }
- }
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- // Also, keep track if we can use back-references (shared names)
- if (_seenNameCount >= 0) {
- _addSeenName(name.getValue());
- }
- }
-
- private final void _writeSharedNameReference(int ix)
- throws IOException,JsonGenerationException
- {
- // 03-Mar-2011, tatu: Related to [JACKSON-525], let's add a sanity check here
- if (ix >= _seenNameCount) {
- throw new IllegalArgumentException("Internal error: trying to write shared name with index "+ix
- +"; but have only seen "+_seenNameCount+" so far!");
- }
- if (ix < 64) {
- _writeByte((byte) (TOKEN_PREFIX_KEY_SHARED_SHORT + ix));
- } else {
- _writeBytes(((byte) (TOKEN_PREFIX_KEY_SHARED_LONG + (ix >> 8))), (byte) ix);
- }
- }
-
- /*
- /**********************************************************
- /* Output method implementations, textual
- /**********************************************************
- */
-
- @Override
- public void writeString(String text) throws IOException,JsonGenerationException
- {
- if (text == null) {
- writeNull();
- return;
- }
- _verifyValueWrite("write String value");
- int len = text.length();
- if (len == 0) {
- _writeByte(TOKEN_LITERAL_EMPTY_STRING);
- return;
- }
- // Longer string handling off-lined
- if (len > MAX_SHARED_STRING_LENGTH_BYTES) {
- _writeNonSharedString(text, len);
- return;
- }
- // Then: is it something we can share?
- if (_seenStringValueCount >= 0) {
- int ix = _findSeenStringValue(text);
- if (ix >= 0) {
- _writeSharedStringValueReference(ix);
- return;
- }
- }
-
- // possibly short string (but not necessarily)
- // first: ensure we have enough space
- if ((_outputTail + MIN_BUFFER_FOR_POSSIBLE_SHORT_STRING) >= _outputEnd) {
- _flushBuffer();
- }
- // then let's copy String chars to char buffer, faster than using getChar (measured, profiled)
- text.getChars(0, len, _charBuffer, 0);
- int origOffset = _outputTail;
- ++_outputTail; // to leave room for type token
- int byteLen = _shortUTF8Encode(_charBuffer, 0, len);
- if (byteLen <= MAX_SHORT_VALUE_STRING_BYTES) { // yes, is short indeed
- // plus keep reference, if it could be shared:
- if (_seenStringValueCount >= 0) {
- _addSeenStringValue(text);
- }
- if (byteLen == len) { // and all ASCII
- _outputBuffer[origOffset] = (byte) ((TOKEN_PREFIX_TINY_ASCII - 1) + byteLen);
- } else { // not just ASCII
- // note: since length 1 can not be used here, value range is offset by 2, not 1
- _outputBuffer[origOffset] = (byte) ((TOKEN_PREFIX_TINY_UNICODE - 2) + byteLen);
- }
- } else { // nope, longer String
- _outputBuffer[origOffset] = (byteLen == len) ? TOKEN_BYTE_LONG_STRING_ASCII : TOKEN_BYTE_LONG_STRING_UNICODE;
- // and we will need String end marker byte
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
- }
-
- private final void _writeSharedStringValueReference(int ix)
- throws IOException,JsonGenerationException
- {
- // 03-Mar-2011, tatu: Related to [JACKSON-525], let's add a sanity check here
- if (ix >= _seenStringValueCount) {
- throw new IllegalArgumentException("Internal error: trying to write shared String value with index "+ix
- +"; but have only seen "+_seenStringValueCount+" so far!");
- }
- if (ix < 31) { // add 1, as byte 0 is omitted
- _writeByte((byte) (TOKEN_PREFIX_SHARED_STRING_SHORT + 1 + ix));
- } else {
- _writeBytes(((byte) (TOKEN_MISC_SHARED_STRING_LONG + (ix >> 8))), (byte) ix);
- }
- }
-
- /**
- * Helper method called to handle cases where String value to write is known
- * to be long enough not to be shareable.
- */
- private final void _writeNonSharedString(final String text, final int len)
- throws IOException,JsonGenerationException
- {
- // First: can we at least make a copy to char[]?
- if (len > _charBufferLength) { // nope; need to skip copy step (alas; this is slower)
- _writeByte(TOKEN_BYTE_LONG_STRING_UNICODE);
- _slowUTF8Encode(text);
- _writeByte(BYTE_MARKER_END_OF_STRING);
- return;
- }
- text.getChars(0, len, _charBuffer, 0);
- // Expansion can be 3x for Unicode; and then there's type byte and end marker, so:
- int maxLen = len + len + len + 2;
- // Next: does it always fit within output buffer?
- if (maxLen > _outputBuffer.length) { // nope
- // can't rewrite type buffer, so can't speculate it might be all-ASCII
- _writeByte(TOKEN_BYTE_LONG_STRING_UNICODE);
- _mediumUTF8Encode(_charBuffer, 0, len);
- _writeByte(BYTE_MARKER_END_OF_STRING);
- return;
- }
-
- if ((_outputTail + maxLen) >= _outputEnd) {
- _flushBuffer();
- }
- int origOffset = _outputTail;
- // can't say for sure if it's ASCII or Unicode, so:
- _writeByte(TOKEN_BYTE_LONG_STRING_ASCII);
- int byteLen = _shortUTF8Encode(_charBuffer, 0, len);
- // If not ASCII, fix type:
- if (byteLen > len) {
- _outputBuffer[origOffset] = TOKEN_BYTE_LONG_STRING_UNICODE;
- }
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
-
- @Override
- public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException
- {
- // Shared strings are tricky; easiest to just construct String, call the other method
- if (len <= MAX_SHARED_STRING_LENGTH_BYTES && _seenStringValueCount >= 0 && len > 0) {
- writeString(new String(text, offset, len));
- return;
- }
- _verifyValueWrite("write String value");
- if (len == 0) {
- _writeByte(TOKEN_LITERAL_EMPTY_STRING);
- return;
- }
- if (len <= MAX_SHORT_VALUE_STRING_BYTES) { // possibly short strings (not necessarily)
- // first: ensure we have enough space
- if ((_outputTail + MIN_BUFFER_FOR_POSSIBLE_SHORT_STRING) >= _outputEnd) {
- _flushBuffer();
- }
- int origOffset = _outputTail;
- ++_outputTail; // to leave room for type token
- int byteLen = _shortUTF8Encode(text, offset, offset+len);
- byte typeToken;
- if (byteLen <= MAX_SHORT_VALUE_STRING_BYTES) { // yes, is short indeed
- if (byteLen == len) { // and all ASCII
- typeToken = (byte) ((TOKEN_PREFIX_TINY_ASCII - 1) + byteLen);
- } else { // not just ASCII
- typeToken = (byte) ((TOKEN_PREFIX_TINY_UNICODE - 2) + byteLen);
- }
- } else { // nope, longer non-ASCII Strings
- typeToken = TOKEN_BYTE_LONG_STRING_UNICODE;
- // and we will need String end marker byte
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- }
- // and then sneak in type token now that know the details
- _outputBuffer[origOffset] = typeToken;
- } else { // "long" String, never shared
- // but might still fit within buffer?
- int maxLen = len + len + len + 2;
- if (maxLen <= _outputBuffer.length) { // yes indeed
- if ((_outputTail + maxLen) >= _outputEnd) {
- _flushBuffer();
- }
- int origOffset = _outputTail;
- _writeByte(TOKEN_BYTE_LONG_STRING_UNICODE);
- int byteLen = _shortUTF8Encode(text, offset, offset+len);
- // if it's ASCII, let's revise our type determination (to help decoder optimize)
- if (byteLen == len) {
- _outputBuffer[origOffset] = TOKEN_BYTE_LONG_STRING_ASCII;
- }
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- } else {
- _writeByte(TOKEN_BYTE_LONG_STRING_UNICODE);
- _mediumUTF8Encode(text, offset, offset+len);
- _writeByte(BYTE_MARKER_END_OF_STRING);
- }
- }
- }
-
- @Override
- public final void writeString(SerializableString sstr)
- throws IOException, JsonGenerationException
- {
- _verifyValueWrite("write String value");
- // First: is it empty?
- String str = sstr.getValue();
- int len = str.length();
- if (len == 0) {
- _writeByte(TOKEN_LITERAL_EMPTY_STRING);
- return;
- }
- // Second: something we can share?
- if (len <= MAX_SHARED_STRING_LENGTH_BYTES && _seenStringValueCount >= 0) {
- int ix = _findSeenStringValue(str);
- if (ix >= 0) {
- _writeSharedStringValueReference(ix);
- return;
- }
- }
- // If not, use pre-encoded version
- byte[] raw = sstr.asUnquotedUTF8();
- final int byteLen = raw.length;
-
- if (byteLen <= MAX_SHORT_VALUE_STRING_BYTES) { // short string
- // first: ensure we have enough space
- if ((_outputTail + byteLen + 1) >= _outputEnd) {
- _flushBuffer();
- }
- // ASCII or Unicode?
- int typeToken = (byteLen == len)
- ? ((TOKEN_PREFIX_TINY_ASCII - 1) + byteLen)
- : ((TOKEN_PREFIX_TINY_UNICODE - 2) + byteLen)
- ;
- _outputBuffer[_outputTail++] = (byte) typeToken;
- System.arraycopy(raw, 0, _outputBuffer, _outputTail, byteLen);
- _outputTail += byteLen;
- // plus keep reference, if it could be shared:
- if (_seenStringValueCount >= 0) {
- _addSeenStringValue(sstr.getValue());
- }
- } else { // "long" String, never shared
- // but might still fit within buffer?
- byte typeToken = (byteLen == len) ? TOKEN_BYTE_LONG_STRING_ASCII : TOKEN_BYTE_LONG_STRING_UNICODE;
- _writeByte(typeToken);
- _writeBytes(raw, 0, raw.length);
- _writeByte(BYTE_MARKER_END_OF_STRING);
- }
- }
-
- @Override
- public void writeRawUTF8String(byte[] text, int offset, int len)
- throws IOException, JsonGenerationException
- {
- _verifyValueWrite("write String value");
- // first: is it empty String?
- if (len == 0) {
- _writeByte(TOKEN_LITERAL_EMPTY_STRING);
- return;
- }
- // Sanity check: shared-strings incompatible with raw String writing
- if (_seenStringValueCount >= 0) {
- throw new UnsupportedOperationException("Can not use direct UTF-8 write methods when 'Feature.CHECK_SHARED_STRING_VALUES' enabled");
- }
- /* Other practical limitation is that we do not really know if it might be
- * ASCII or not; and figuring it out is rather slow. So, best we can do is
- * to declare we do not know it is ASCII (i.e. "is Unicode").
- */
- if (len <= MAX_SHARED_STRING_LENGTH_BYTES) { // up to 65 Unicode bytes
- // first: ensure we have enough space
- if ((_outputTail + len) >= _outputEnd) { // bytes, plus one for type indicator
- _flushBuffer();
- }
- /* 11-Feb-2011, tatu: As per [JACKSON-492], mininum length for "Unicode"
- * String is 2; 1 byte length must be ASCII.
- */
- if (len == 1) {
- _outputBuffer[_outputTail++] = TOKEN_PREFIX_TINY_ASCII; // length of 1 cancels out (len-1)
- _outputBuffer[_outputTail++] = text[offset];
- } else {
- _outputBuffer[_outputTail++] = (byte) ((TOKEN_PREFIX_TINY_UNICODE - 2) + len);
- System.arraycopy(text, offset, _outputBuffer, _outputTail, len);
- _outputTail += len;
- }
- } else { // "long" String
- // but might still fit within buffer?
- int maxLen = len + len + len + 2;
- if (maxLen <= _outputBuffer.length) { // yes indeed
- if ((_outputTail + maxLen) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = TOKEN_BYTE_LONG_STRING_UNICODE;
- System.arraycopy(text, offset, _outputBuffer, _outputTail, len);
- _outputTail += len;
- _outputBuffer[_outputTail++] = BYTE_MARKER_END_OF_STRING;
- } else {
- _writeByte(TOKEN_BYTE_LONG_STRING_UNICODE);
- _writeBytes(text, offset, len);
- _writeByte(BYTE_MARKER_END_OF_STRING);
- }
- }
- }
-
- @Override
- public final void writeUTF8String(byte[] text, int offset, int len)
- throws IOException, JsonGenerationException
- {
- // Since no escaping is needed, same as 'writeRawUTF8String'
- writeRawUTF8String(text, offset, len);
- }
-
- /*
- /**********************************************************
- /* Output method implementations, unprocessed ("raw")
- /**********************************************************
- */
-
- @Override
- public void writeRaw(String text) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRaw(char c) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRawValue(String text) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRawValue(String text, int offset, int len) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- @Override
- public void writeRawValue(char[] text, int offset, int len) throws IOException, JsonGenerationException {
- throw _notSupported();
- }
-
- /*
- /**********************************************************
- /* Output method implementations, base64-encoded binary
- /**********************************************************
- */
-
- @Override
- public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) throws IOException, JsonGenerationException
- {
- if (data == null) {
- writeNull();
- return;
- }
- _verifyValueWrite("write Binary value");
- if (this.isEnabled(Feature.ENCODE_BINARY_AS_7BIT)) {
- _writeByte((byte) TOKEN_MISC_BINARY_7BIT);
- _write7BitBinaryWithLength(data, offset, len);
- } else {
- _writeByte((byte) TOKEN_MISC_BINARY_RAW );
- _writePositiveVInt(len);
- // raw is dead simple of course:
- _writeBytes(data, offset, len);
- }
- }
-
- /*
- /**********************************************************
- /* Output method implementations, primitive
- /**********************************************************
- */
-
- @Override
- public void writeBoolean(boolean state) throws IOException, JsonGenerationException
- {
- _verifyValueWrite("write boolean value");
- if (state) {
- _writeByte(TOKEN_LITERAL_TRUE);
- } else {
- _writeByte(TOKEN_LITERAL_FALSE);
- }
- }
-
- @Override
- public void writeNull() throws IOException, JsonGenerationException
- {
- _verifyValueWrite("write null value");
- _writeByte(TOKEN_LITERAL_NULL);
- }
-
- @Override
- public void writeNumber(int i) throws IOException, JsonGenerationException
- {
- _verifyValueWrite("write number");
- // First things first: let's zigzag encode number
- i = SmileUtil.zigzagEncode(i);
- // tiny (single byte) or small (type + 6-bit value) number?
- if (i <= 0x3F && i >= 0) {
- if (i <= 0x1F) { // tiny
- _writeByte((byte) (TOKEN_PREFIX_SMALL_INT + i));
- return;
- }
- // nope, just small, 2 bytes (type, 1-byte zigzag value) for 6 bit value
- _writeBytes(TOKEN_BYTE_INT_32, (byte) (0x80 + i));
- return;
- }
- // Ok: let's find minimal representation then
- byte b0 = (byte) (0x80 + (i & 0x3F));
- i >>>= 6;
- if (i <= 0x7F) { // 13 bits is enough (== 3 byte total encoding)
- _writeBytes(TOKEN_BYTE_INT_32, (byte) i, b0);
- return;
- }
- byte b1 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_32, (byte) i, b1, b0);
- return;
- }
- byte b2 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_32, (byte) i, b2, b1, b0);
- return;
- }
- // no, need all 5 bytes
- byte b3 = (byte) (i & 0x7F);
- _writeBytes(TOKEN_BYTE_INT_32, (byte) (i >> 7), b3, b2, b1, b0);
- }
-
- @Override
- public void writeNumber(long l) throws IOException, JsonGenerationException
- {
- // First: maybe 32 bits is enough?
- if (l <= MAX_INT_AS_LONG && l >= MIN_INT_AS_LONG) {
- writeNumber((int) l);
- return;
- }
- _verifyValueWrite("write number");
- // Then let's zigzag encode it
-
- l = SmileUtil.zigzagEncode(l);
- // Ok, well, we do know that 5 lowest-significant bytes are needed
- int i = (int) l;
- // 4 can be extracted from lower int
- byte b0 = (byte) (0x80 + (i & 0x3F)); // sign bit set in the last byte
- byte b1 = (byte) ((i >> 6) & 0x7F);
- byte b2 = (byte) ((i >> 13) & 0x7F);
- byte b3 = (byte) ((i >> 20) & 0x7F);
- // fifth one is split between ints:
- l >>>= 27;
- byte b4 = (byte) (((int) l) & 0x7F);
-
- // which may be enough?
- i = (int) (l >> 7);
- if (i == 0) {
- _writeBytes(TOKEN_BYTE_INT_64, b4, b3, b2, b1, b0);
- return;
- }
-
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_64, (byte) i);
- _writeBytes(b4, b3, b2, b1, b0);
- return;
- }
- byte b5 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_64, (byte) i);
- _writeBytes(b5, b4, b3, b2, b1, b0);
- return;
- }
- byte b6 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_64, (byte) i, b6);
- _writeBytes(b5, b4, b3, b2, b1, b0);
- return;
- }
- byte b7 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _writeBytes(TOKEN_BYTE_INT_64, (byte) i, b7, b6);
- _writeBytes(b5, b4, b3, b2, b1, b0);
- return;
- }
- byte b8 = (byte) (i & 0x7F);
- i >>= 7;
- // must be done, with 10 bytes! (9 * 7 + 6 == 69 bits; only need 63)
- _writeBytes(TOKEN_BYTE_INT_64, (byte) i, b8, b7, b6);
- _writeBytes(b5, b4, b3, b2, b1, b0);
- }
-
- @Override
- public void writeNumber(BigInteger v) throws IOException, JsonGenerationException
- {
- if (v == null) {
- writeNull();
- return;
- }
- _verifyValueWrite("write number");
- // quite simple: type, and then VInt-len prefixed 7-bit encoded binary data:
- _writeByte(TOKEN_BYTE_BIG_INTEGER);
- byte[] data = v.toByteArray();
- _write7BitBinaryWithLength(data, 0, data.length);
- }
-
- @Override
- public void writeNumber(double d) throws IOException, JsonGenerationException
- {
- // Ok, now, we needed token type byte plus 10 data bytes (7 bits each)
- _ensureRoomForOutput(11);
- _verifyValueWrite("write number");
- /* 17-Apr-2010, tatu: could also use 'doubleToIntBits', but it seems more accurate to use
- * exact representation; and possibly faster. However, if there are cases
- * where collapsing of NaN was needed (for non-Java clients), this can
- * be changed
- */
- long l = Double.doubleToRawLongBits(d);
- _outputBuffer[_outputTail++] = TOKEN_BYTE_FLOAT_64;
- // Handle first 29 bits (single bit first, then 4 x 7 bits)
- int hi5 = (int) (l >>> 35);
- _outputBuffer[_outputTail+4] = (byte) (hi5 & 0x7F);
- hi5 >>= 7;
- _outputBuffer[_outputTail+3] = (byte) (hi5 & 0x7F);
- hi5 >>= 7;
- _outputBuffer[_outputTail+2] = (byte) (hi5 & 0x7F);
- hi5 >>= 7;
- _outputBuffer[_outputTail+1] = (byte) (hi5 & 0x7F);
- hi5 >>= 7;
- _outputBuffer[_outputTail] = (byte) hi5;
- _outputTail += 5;
- // Then split byte (one that crosses lo/hi int boundary), 7 bits
- {
- int mid = (int) (l >> 28);
- _outputBuffer[_outputTail++] = (byte) (mid & 0x7F);
- }
- // and then last 4 bytes (28 bits)
- int lo4 = (int) l;
- _outputBuffer[_outputTail+3] = (byte) (lo4 & 0x7F);
- lo4 >>= 7;
- _outputBuffer[_outputTail+2] = (byte) (lo4 & 0x7F);
- lo4 >>= 7;
- _outputBuffer[_outputTail+1] = (byte) (lo4 & 0x7F);
- lo4 >>= 7;
- _outputBuffer[_outputTail] = (byte) (lo4 & 0x7F);
- _outputTail += 4;
- }
-
- @Override
- public void writeNumber(float f) throws IOException, JsonGenerationException
- {
- // Ok, now, we needed token type byte plus 5 data bytes (7 bits each)
- _ensureRoomForOutput(6);
- _verifyValueWrite("write number");
-
- /* 17-Apr-2010, tatu: could also use 'floatToIntBits', but it seems more accurate to use
- * exact representation; and possibly faster. However, if there are cases
- * where collapsing of NaN was needed (for non-Java clients), this can
- * be changed
- */
- int i = Float.floatToRawIntBits(f);
- _outputBuffer[_outputTail++] = TOKEN_BYTE_FLOAT_32;
- _outputBuffer[_outputTail+4] = (byte) (i & 0x7F);
- i >>= 7;
- _outputBuffer[_outputTail+3] = (byte) (i & 0x7F);
- i >>= 7;
- _outputBuffer[_outputTail+2] = (byte) (i & 0x7F);
- i >>= 7;
- _outputBuffer[_outputTail+1] = (byte) (i & 0x7F);
- i >>= 7;
- _outputBuffer[_outputTail] = (byte) (i & 0x7F);
- _outputTail += 5;
- }
-
- @Override
- public void writeNumber(BigDecimal dec) throws IOException, JsonGenerationException
- {
- if (dec == null) {
- writeNull();
- return;
- }
- _verifyValueWrite("write number");
- _writeByte(TOKEN_BYTE_BIG_DECIMAL);
- int scale = dec.scale();
- // Ok, first output scale as VInt
- _writeSignedVInt(scale);
- BigInteger unscaled = dec.unscaledValue();
- byte[] data = unscaled.toByteArray();
- // And then binary data in "safe" mode (7-bit values)
- _write7BitBinaryWithLength(data, 0, data.length);
- }
-
- @Override
- public void writeNumber(String encodedValue) throws IOException,JsonGenerationException, UnsupportedOperationException
- {
- /* 17-Apr-2010, tatu: Could try parsing etc; but for now let's not bother, it could
- * just be some non-standard representation that caller wants to pass
- */
- throw _notSupported();
- }
-
- /*
- /**********************************************************
- /* Implementations for other methods
- /**********************************************************
- */
-
- @Override
- protected final void _verifyValueWrite(String typeMsg)
- throws IOException, JsonGenerationException
- {
- int status = _writeContext.writeValue();
- if (status == JsonWriteContext.STATUS_EXPECT_NAME) {
- _reportError("Can not "+typeMsg+", expecting field name");
- }
- }
-
- /*
- /**********************************************************
- /* Low-level output handling
- /**********************************************************
- */
-
- @Override
- public final void flush() throws IOException
- {
- _flushBuffer();
- if (isEnabled(JsonGenerator.Feature.FLUSH_PASSED_TO_STREAM)) {
- _out.flush();
- }
- }
-
- @Override
- public void close() throws IOException
- {
- /* 05-Dec-2008, tatu: To add [JACKSON-27], need to close open
- * scopes.
- */
- // First: let's see that we still have buffers...
- if (_outputBuffer != null
- && isEnabled(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT)) {
- while (true) {
- JsonStreamContext ctxt = getOutputContext();
- if (ctxt.inArray()) {
- writeEndArray();
- } else if (ctxt.inObject()) {
- writeEndObject();
- } else {
- break;
- }
- }
- }
- boolean wasClosed = _closed;
- super.close();
-
- if (!wasClosed && isEnabled(Feature.WRITE_END_MARKER)) {
- _writeByte(BYTE_MARKER_END_OF_CONTENT);
- }
- _flushBuffer();
-
- if (_ioContext.isResourceManaged() || isEnabled(JsonGenerator.Feature.AUTO_CLOSE_TARGET)) {
- _out.close();
- } else {
- // If we can't close it, we should at least flush
- _out.flush();
- }
- // Internal buffer(s) generator has can now be released as well
- _releaseBuffers();
- }
-
- /*
- /**********************************************************
- /* Internal methods, UTF-8 encoding
- /**********************************************************
- */
-
- /**
- * Helper method called when the whole character sequence is known to
- * fit in the output buffer regardless of UTF-8 expansion.
- */
- private final int _shortUTF8Encode(char[] str, int i, int end)
- {
- // First: let's see if it's all ASCII: that's rather fast
- int ptr = _outputTail;
- final byte[] outBuf = _outputBuffer;
- do {
- int c = str[i];
- if (c > 0x7F) {
- return _shortUTF8Encode2(str, i, end, ptr);
- }
- outBuf[ptr++] = (byte) c;
- } while (++i < end);
- int codedLen = ptr - _outputTail;
- _outputTail = ptr;
- return codedLen;
- }
-
- /**
- * Helper method called when the whole character sequence is known to
- * fit in the output buffer, but not all characters are single-byte (ASCII)
- * characters.
- */
- private final int _shortUTF8Encode2(char[] str, int i, int end, int outputPtr)
- {
- final byte[] outBuf = _outputBuffer;
- while (i < end) {
- int c = str[i++];
- if (c <= 0x7F) {
- outBuf[outputPtr++] = (byte) c;
- continue;
- }
- // Nope, multi-byte:
- if (c < 0x800) { // 2-byte
- outBuf[outputPtr++] = (byte) (0xc0 | (c >> 6));
- outBuf[outputPtr++] = (byte) (0x80 | (c & 0x3f));
- continue;
- }
- // 3 or 4 bytes (surrogate)
- // Surrogates?
- if (c < SURR1_FIRST || c > SURR2_LAST) { // nope, regular 3-byte character
- outBuf[outputPtr++] = (byte) (0xe0 | (c >> 12));
- outBuf[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- outBuf[outputPtr++] = (byte) (0x80 | (c & 0x3f));
- continue;
- }
- // Yup, a surrogate pair
- if (c > SURR1_LAST) { // must be from first range; second won't do
- _throwIllegalSurrogate(c);
- }
- // ... meaning it must have a pair
- if (i >= end) {
- _throwIllegalSurrogate(c);
- }
- c = _convertSurrogate(c, str[i++]);
- if (c > 0x10FFFF) { // illegal in JSON as well as in XML
- _throwIllegalSurrogate(c);
- }
- outBuf[outputPtr++] = (byte) (0xf0 | (c >> 18));
- outBuf[outputPtr++] = (byte) (0x80 | ((c >> 12) & 0x3f));
- outBuf[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- outBuf[outputPtr++] = (byte) (0x80 | (c & 0x3f));
- }
- int codedLen = outputPtr - _outputTail;
- _outputTail = outputPtr;
- return codedLen;
- }
-
- private void _slowUTF8Encode(String str) throws IOException
- {
- final int len = str.length();
- int inputPtr = 0;
- final int bufferEnd = _outputEnd - 4;
-
- output_loop:
- for (; inputPtr < len; ) {
- /* First, let's ensure we can output at least 4 bytes
- * (longest UTF-8 encoded codepoint):
- */
- if (_outputTail >= bufferEnd) {
- _flushBuffer();
- }
- int c = str.charAt(inputPtr++);
- // And then see if we have an ASCII char:
- if (c <= 0x7F) { // If so, can do a tight inner loop:
- _outputBuffer[_outputTail++] = (byte)c;
- // Let's calc how many ASCII chars we can copy at most:
- int maxInCount = (len - inputPtr);
- int maxOutCount = (bufferEnd - _outputTail);
-
- if (maxInCount > maxOutCount) {
- maxInCount = maxOutCount;
- }
- maxInCount += inputPtr;
- ascii_loop:
- while (true) {
- if (inputPtr >= maxInCount) { // done with max. ascii seq
- continue output_loop;
- }
- c = str.charAt(inputPtr++);
- if (c > 0x7F) {
- break ascii_loop;
- }
- _outputBuffer[_outputTail++] = (byte) c;
- }
- }
-
- // Nope, multi-byte:
- if (c < 0x800) { // 2-byte
- _outputBuffer[_outputTail++] = (byte) (0xc0 | (c >> 6));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- } else { // 3 or 4 bytes
- // Surrogates?
- if (c < SURR1_FIRST || c > SURR2_LAST) {
- _outputBuffer[_outputTail++] = (byte) (0xe0 | (c >> 12));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- continue;
- }
- // Yup, a surrogate:
- if (c > SURR1_LAST) { // must be from first range
- _throwIllegalSurrogate(c);
- }
- // and if so, followed by another from next range
- if (inputPtr >= len) {
- _throwIllegalSurrogate(c);
- }
- c = _convertSurrogate(c, str.charAt(inputPtr++));
- if (c > 0x10FFFF) { // illegal, as per RFC 4627
- _throwIllegalSurrogate(c);
- }
- _outputBuffer[_outputTail++] = (byte) (0xf0 | (c >> 18));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 12) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- }
- }
- }
-
- private void _mediumUTF8Encode(char[] str, int inputPtr, int inputEnd) throws IOException
- {
- final int bufferEnd = _outputEnd - 4;
-
- output_loop:
- while (inputPtr < inputEnd) {
- /* First, let's ensure we can output at least 4 bytes
- * (longest UTF-8 encoded codepoint):
- */
- if (_outputTail >= bufferEnd) {
- _flushBuffer();
- }
- int c = str[inputPtr++];
- // And then see if we have an ASCII char:
- if (c <= 0x7F) { // If so, can do a tight inner loop:
- _outputBuffer[_outputTail++] = (byte)c;
- // Let's calc how many ASCII chars we can copy at most:
- int maxInCount = (inputEnd - inputPtr);
- int maxOutCount = (bufferEnd - _outputTail);
-
- if (maxInCount > maxOutCount) {
- maxInCount = maxOutCount;
- }
- maxInCount += inputPtr;
- ascii_loop:
- while (true) {
- if (inputPtr >= maxInCount) { // done with max. ascii seq
- continue output_loop;
- }
- c = str[inputPtr++];
- if (c > 0x7F) {
- break ascii_loop;
- }
- _outputBuffer[_outputTail++] = (byte) c;
- }
- }
-
- // Nope, multi-byte:
- if (c < 0x800) { // 2-byte
- _outputBuffer[_outputTail++] = (byte) (0xc0 | (c >> 6));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- } else { // 3 or 4 bytes
- // Surrogates?
- if (c < SURR1_FIRST || c > SURR2_LAST) {
- _outputBuffer[_outputTail++] = (byte) (0xe0 | (c >> 12));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- continue;
- }
- // Yup, a surrogate:
- if (c > SURR1_LAST) { // must be from first range
- _throwIllegalSurrogate(c);
- }
- // and if so, followed by another from next range
- if (inputPtr >= inputEnd) {
- _throwIllegalSurrogate(c);
- }
- c = _convertSurrogate(c, str[inputPtr++]);
- if (c > 0x10FFFF) { // illegal, as per RFC 4627
- _throwIllegalSurrogate(c);
- }
- _outputBuffer[_outputTail++] = (byte) (0xf0 | (c >> 18));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 12) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | ((c >> 6) & 0x3f));
- _outputBuffer[_outputTail++] = (byte) (0x80 | (c & 0x3f));
- }
- }
- }
-
- /**
- * Method called to calculate UTF codepoint, from a surrogate pair.
- */
- private int _convertSurrogate(int firstPart, int secondPart)
- {
- // Ok, then, is the second part valid?
- if (secondPart < SURR2_FIRST || secondPart > SURR2_LAST) {
- throw new IllegalArgumentException("Broken surrogate pair: first char 0x"+Integer.toHexString(firstPart)+", second 0x"+Integer.toHexString(secondPart)+"; illegal combination");
- }
- return 0x10000 + ((firstPart - SURR1_FIRST) << 10) + (secondPart - SURR2_FIRST);
- }
-
- private void _throwIllegalSurrogate(int code)
- {
- if (code > 0x10FFFF) { // over max?
- throw new IllegalArgumentException("Illegal character point (0x"+Integer.toHexString(code)+") to output; max is 0x10FFFF as per RFC 4627");
- }
- if (code >= SURR1_FIRST) {
- if (code <= SURR1_LAST) { // Unmatched first part (closing without second part?)
- throw new IllegalArgumentException("Unmatched first part of surrogate pair (0x"+Integer.toHexString(code)+")");
- }
- throw new IllegalArgumentException("Unmatched second part of surrogate pair (0x"+Integer.toHexString(code)+")");
- }
- // should we ever get this?
- throw new IllegalArgumentException("Illegal character point (0x"+Integer.toHexString(code)+") to output");
- }
-
- /*
- /**********************************************************
- /* Internal methods, writing bytes
- /**********************************************************
- */
-
- private final void _ensureRoomForOutput(int needed) throws IOException
- {
- if ((_outputTail + needed) >= _outputEnd) {
- _flushBuffer();
- }
- }
-
- private final void _writeByte(byte b) throws IOException
- {
- if (_outputTail >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b;
- }
-
- private final void _writeBytes(byte b1, byte b2) throws IOException
- {
- if ((_outputTail + 1) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b2;
- }
-
- private final void _writeBytes(byte b1, byte b2, byte b3) throws IOException
- {
- if ((_outputTail + 2) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b3;
- }
-
- private final void _writeBytes(byte b1, byte b2, byte b3, byte b4) throws IOException
- {
- if ((_outputTail + 3) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b3;
- _outputBuffer[_outputTail++] = b4;
- }
-
- private final void _writeBytes(byte b1, byte b2, byte b3, byte b4, byte b5) throws IOException
- {
- if ((_outputTail + 4) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b3;
- _outputBuffer[_outputTail++] = b4;
- _outputBuffer[_outputTail++] = b5;
- }
-
- private final void _writeBytes(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6) throws IOException
- {
- if ((_outputTail + 5) >= _outputEnd) {
- _flushBuffer();
- }
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b3;
- _outputBuffer[_outputTail++] = b4;
- _outputBuffer[_outputTail++] = b5;
- _outputBuffer[_outputTail++] = b6;
- }
-
- private final void _writeBytes(byte[] data, int offset, int len) throws IOException
- {
- if (len == 0) {
- return;
- }
- if ((_outputTail + len) >= _outputEnd) {
- _writeBytesLong(data, offset, len);
- return;
- }
- // common case, non-empty, fits in just fine:
- System.arraycopy(data, offset, _outputBuffer, _outputTail, len);
- _outputTail += len;
- }
-
- private final void _writeBytesLong(byte[] data, int offset, int len) throws IOException
- {
- if (_outputTail >= _outputEnd) {
- _flushBuffer();
- }
- while (true) {
- int currLen = Math.min(len, (_outputEnd - _outputTail));
- System.arraycopy(data, offset, _outputBuffer, _outputTail, currLen);
- _outputTail += currLen;
- if ((len -= currLen) == 0) {
- break;
- }
- offset += currLen;
- _flushBuffer();
- }
- }
-
- /**
- * Helper method for writing a 32-bit positive (really 31-bit then) value.
- * Value is NOT zigzag encoded (since there is no sign bit to worry about)
- */
- private void _writePositiveVInt(int i) throws IOException
- {
- // At most 5 bytes (4 * 7 + 6 bits == 34 bits)
- _ensureRoomForOutput(5);
- byte b0 = (byte) (0x80 + (i & 0x3F));
- i >>= 6;
- if (i <= 0x7F) { // 6 or 13 bits is enough (== 2 or 3 byte total encoding)
- if (i > 0) {
- _outputBuffer[_outputTail++] = (byte) i;
- }
- _outputBuffer[_outputTail++] = b0;
- return;
- }
- byte b1 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _outputBuffer[_outputTail++] = (byte) i;
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b0;
- } else {
- byte b2 = (byte) (i & 0x7F);
- i >>= 7;
- if (i <= 0x7F) {
- _outputBuffer[_outputTail++] = (byte) i;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b0;
- } else {
- byte b3 = (byte) (i & 0x7F);
- _outputBuffer[_outputTail++] = (byte) (i >> 7);
- _outputBuffer[_outputTail++] = b3;
- _outputBuffer[_outputTail++] = b2;
- _outputBuffer[_outputTail++] = b1;
- _outputBuffer[_outputTail++] = b0;
- }
- }
- }
-
- /**
- * Helper method for writing 32-bit signed value, using
- * "zig zag encoding" (see protocol buffers for explanation -- basically,
- * sign bit is moved as LSB, rest of value shifted left by one)
- * coupled with basic variable length encoding
- */
- private void _writeSignedVInt(int input) throws IOException
- {
- _writePositiveVInt(SmileUtil.zigzagEncode(input));
- }
-
- protected void _write7BitBinaryWithLength(byte[] data, int offset, int len) throws IOException
- {
- _writePositiveVInt(len);
- // first, let's handle full 7-byte chunks
- while (len >= 7) {
- if ((_outputTail + 8) >= _outputEnd) {
- _flushBuffer();
- }
- int i = data[offset++]; // 1st byte
- _outputBuffer[_outputTail++] = (byte) ((i >> 1) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 2nd
- _outputBuffer[_outputTail++] = (byte) ((i >> 2) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 3rd
- _outputBuffer[_outputTail++] = (byte) ((i >> 3) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 4th
- _outputBuffer[_outputTail++] = (byte) ((i >> 4) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 5th
- _outputBuffer[_outputTail++] = (byte) ((i >> 5) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 6th
- _outputBuffer[_outputTail++] = (byte) ((i >> 6) & 0x7F);
- i = (i << 8) | (data[offset++] & 0xFF); // 7th
- _outputBuffer[_outputTail++] = (byte) ((i >> 7) & 0x7F);
- _outputBuffer[_outputTail++] = (byte) (i & 0x7F);
- len -= 7;
- }
- // and then partial piece, if any
- if (len > 0) {
- // up to 6 bytes to output, resulting in at most 7 bytes (which can encode 49 bits)
- if ((_outputTail + 7) >= _outputEnd) {
- _flushBuffer();
- }
- int i = data[offset++];
- _outputBuffer[_outputTail++] = (byte) ((i >> 1) & 0x7F);
- if (len > 1) {
- i = ((i & 0x01) << 8) | (data[offset++] & 0xFF); // 2nd
- _outputBuffer[_outputTail++] = (byte) ((i >> 2) & 0x7F);
- if (len > 2) {
- i = ((i & 0x03) << 8) | (data[offset++] & 0xFF); // 3rd
- _outputBuffer[_outputTail++] = (byte) ((i >> 3) & 0x7F);
- if (len > 3) {
- i = ((i & 0x07) << 8) | (data[offset++] & 0xFF); // 4th
- _outputBuffer[_outputTail++] = (byte) ((i >> 4) & 0x7F);
- if (len > 4) {
- i = ((i & 0x0F) << 8) | (data[offset++] & 0xFF); // 5th
- _outputBuffer[_outputTail++] = (byte) ((i >> 5) & 0x7F);
- if (len > 5) {
- i = ((i & 0x1F) << 8) | (data[offset++] & 0xFF); // 6th
- _outputBuffer[_outputTail++] = (byte) ((i >> 6) & 0x7F);
- _outputBuffer[_outputTail++] = (byte) (i & 0x3F); // last 6 bits
- } else {
- _outputBuffer[_outputTail++] = (byte) (i & 0x1F); // last 5 bits
- }
- } else {
- _outputBuffer[_outputTail++] = (byte) (i & 0x0F); // last 4 bits
- }
- } else {
- _outputBuffer[_outputTail++] = (byte) (i & 0x07); // last 3 bits
- }
- } else {
- _outputBuffer[_outputTail++] = (byte) (i & 0x03); // last 2 bits
- }
- } else {
- _outputBuffer[_outputTail++] = (byte) (i & 0x01); // last bit
- }
- }
- }
-
- /*
- /**********************************************************
- /* Internal methods, buffer handling
- /**********************************************************
- */
-
- @Override
- protected void _releaseBuffers()
- {
- byte[] buf = _outputBuffer;
- if (buf != null && _bufferRecyclable) {
- _outputBuffer = null;
- _ioContext.releaseWriteEncodingBuffer(buf);
- }
- char[] cbuf = _charBuffer;
- if (cbuf != null) {
- _charBuffer = null;
- _ioContext.releaseConcatBuffer(cbuf);
- }
- /* Ok: since clearing up of larger arrays is much slower,
- * let's only recycle default-sized buffers...
- */
- {
- SharedStringNode[] nameBuf = _seenNames;
- if (nameBuf != null && nameBuf.length == SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH) {
- _seenNames = null;
- /* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer; and note
- * that since it's a hash area, must clear all
- */
- if (_seenNameCount > 0) {
- Arrays.fill(nameBuf, null);
- }
- _smileBufferRecycler.releaseSeenNamesBuffer(nameBuf);
- }
- }
- {
- SharedStringNode[] valueBuf = _seenStringValues;
- if (valueBuf != null && valueBuf.length == SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH) {
- _seenStringValues = null;
- /* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer; and note
- * that since it's a hash area, must clear all
- */
- if (_seenStringValueCount > 0) {
- Arrays.fill(valueBuf, null);
- }
- _smileBufferRecycler.releaseSeenStringValuesBuffer(valueBuf);
- }
- }
- }
-
- protected final void _flushBuffer() throws IOException
- {
- if (_outputTail > 0) {
- _bytesWritten += _outputTail;
- _out.write(_outputBuffer, 0, _outputTail);
- _outputTail = 0;
- }
- }
-
- /*
- /**********************************************************
- /* Internal methods, handling shared string "maps"
- /**********************************************************
- */
-
- private final int _findSeenName(String name)
- {
- int hash = name.hashCode();
- SharedStringNode head = _seenNames[hash & (_seenNames.length-1)];
- if (head == null) {
- return -1;
- }
- SharedStringNode node = head;
- // first, identity match; assuming most of the time we get intern()ed String
- // And do unrolled initial check; 90+% likelihood head node has all info we need:
- if (node.value == name) {
- return node.index;
- }
- while ((node = node.next) != null) {
- if (node.value == name) {
- return node.index;
- }
- }
- // If not, equality check; we already know head is not null
- node = head;
- do {
- String value = node.value;
- if (value.hashCode() == hash && value.equals(name)) {
- return node.index;
- }
- node = node.next;
- } while (node != null);
- return -1;
- }
-
- private final void _addSeenName(String name)
- {
- // first: do we need to expand?
- if (_seenNameCount == _seenNames.length) {
- if (_seenNameCount == MAX_SHARED_NAMES) { // we are too full, restart from empty
- Arrays.fill(_seenNames, null);
- _seenNameCount = 0;
- } else { // we always start with modest default size (like 64), so expand to full
- SharedStringNode[] old = _seenNames;
- _seenNames = new SharedStringNode[MAX_SHARED_NAMES];
- final int mask = MAX_SHARED_NAMES-1;
- for (SharedStringNode node : old) {
- for (; node != null; node = node.next) {
- int ix = node.value.hashCode() & mask;
- node.next = _seenNames[ix];
- _seenNames[ix] = node;
- }
- }
- }
- }
- // other than that, just slap it there
- int ix = name.hashCode() & (_seenNames.length-1);
- _seenNames[ix] = new SharedStringNode(name, _seenNameCount, _seenNames[ix]);
- ++_seenNameCount;
- }
-
- private final int _findSeenStringValue(String text)
- {
- int hash = text.hashCode();
- SharedStringNode head = _seenStringValues[hash & (_seenStringValues.length-1)];
- if (head != null) {
- SharedStringNode node = head;
- // first, identity match; assuming most of the time we get intern()ed String
- do {
- if (node.value == text) {
- return node.index;
- }
- node = node.next;
- } while (node != null);
- // and then comparison, if no match yet
- node = head;
- do {
- String value = node.value;
- if (value.hashCode() == hash && value.equals(text)) {
- return node.index;
- }
- node = node.next;
- } while (node != null);
- }
- return -1;
- }
-
- private final void _addSeenStringValue(String text)
- {
- // first: do we need to expand?
- if (_seenStringValueCount == _seenStringValues.length) {
- if (_seenStringValueCount == MAX_SHARED_STRING_VALUES) { // we are too full, restart from empty
- Arrays.fill(_seenStringValues, null);
- _seenStringValueCount = 0;
- } else { // we always start with modest default size (like 64), so expand to full
- SharedStringNode[] old = _seenStringValues;
- _seenStringValues = new SharedStringNode[MAX_SHARED_STRING_VALUES];
- final int mask = MAX_SHARED_STRING_VALUES-1;
- for (SharedStringNode node : old) {
- for (; node != null; node = node.next) {
- int ix = node.value.hashCode() & mask;
- node.next = _seenStringValues[ix];
- _seenStringValues[ix] = node;
- }
- }
- }
- }
- // other than that, just slap it there
- int ix = text.hashCode() & (_seenStringValues.length-1);
- _seenStringValues[ix] = new SharedStringNode(text, _seenStringValueCount, _seenStringValues[ix]);
- ++_seenStringValueCount;
- }
-
- /*
- /**********************************************************
- /* Internal methods, error reporting
- /**********************************************************
- */
-
- /**
- * Method for accessing offset of the next byte within the whole output
- * stream that this generator has produced.
- */
- protected long outputOffset() {
- return _bytesWritten + _outputTail;
- }
-
- protected UnsupportedOperationException _notSupported() {
- return new UnsupportedOperationException();
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParser.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParser.java.svn-base
deleted file mode 100644
index bbb55d2..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParser.java.svn-base
+++ /dev/null
@@ -1,2523 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import static org.codehaus.jackson.smile.SmileConstants.BYTE_MARKER_END_OF_STRING;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.ref.SoftReference;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.impl.JsonParserBase;
-import org.codehaus.jackson.io.IOContext;
-import org.codehaus.jackson.sym.BytesToNameCanonicalizer;
-import org.codehaus.jackson.sym.Name;
-
-public class SmileParser
- extends JsonParserBase
-{
- /**
- * Enumeration that defines all togglable features for Smile generators.
- */
- public enum Feature {
- /**
- * Feature that determines whether 4-byte Smile header is mandatory in input,
- * or optional. If enabled, it means that only input that starts with the header
- * is accepted as valid; if disabled, header is optional. In latter case,r
- * settings for content are assumed to be defaults.
- */
- REQUIRE_HEADER(true)
- ;
-
- final boolean _defaultState;
- final int _mask;
-
- /**
- * Method that calculates bit set (flags) of all features that
- * are enabled by default.
- */
- public static int collectDefaults()
- {
- int flags = 0;
- for (Feature f : values()) {
- if (f.enabledByDefault()) {
- flags |= f.getMask();
- }
- }
- return flags;
- }
-
- private Feature(boolean defaultState) {
- _defaultState = defaultState;
- _mask = (1 << ordinal());
- }
-
- public boolean enabledByDefault() { return _defaultState; }
- public int getMask() { return _mask; }
- }
-
- private final static int[] NO_INTS = new int[0];
-
- private final static String[] NO_STRINGS = new String[0];
-
- /*
- /**********************************************************
- /* Configuration
- /**********************************************************
- */
-
- /**
- * Codec used for data binding when (if) requested.
- */
- protected ObjectCodec _objectCodec;
-
- /**
- * Flag that indicates whether content can legally have raw (unquoted)
- * binary data. Since this information is included both in header and
- * in actual binary data blocks there is redundancy, and we want to
- * ensure settings are compliant. Using application may also want to
- * know this setting in case it does some direct (random) access.
- */
- protected boolean _mayContainRawBinary;
-
- /**
- * Helper object used for low-level recycling of Smile-generator
- * specific buffers.
- *
- * @since 1.7
- */
- final protected SmileBufferRecycler<String> _smileBufferRecycler;
-
- /*
- /**********************************************************
- /* Input source config, state (from ex StreamBasedParserBase)
- /**********************************************************
- */
-
- /**
- * Input stream that can be used for reading more content, if one
- * in use. May be null, if input comes just as a full buffer,
- * or if the stream has been closed.
- */
- protected InputStream _inputStream;
-
- /**
- * Current buffer from which data is read; generally data is read into
- * buffer from input source, but in some cases pre-loaded buffer
- * is handed to the parser.
- */
- protected byte[] _inputBuffer;
-
- /**
- * Flag that indicates whether the input buffer is recycable (and
- * needs to be returned to recycler once we are done) or not.
- *<p>
- * If it is not, it also means that parser can NOT modify underlying
- * buffer.
- */
- protected boolean _bufferRecyclable;
-
- /*
- /**********************************************************
- /* Additional parsing state
- /**********************************************************
- */
-
- /**
- * Flag that indicates that the current token has not yet
- * been fully processed, and needs to be finished for
- * some access (or skipped to obtain the next token)
- */
- protected boolean _tokenIncomplete = false;
-
- /**
- * Type byte of the current token
- */
- protected int _typeByte;
-
- /**
- * Specific flag that is set when we encountered a 32-bit
- * floating point value; needed since numeric super classes do
- * not track distinction between float and double, but Smile
- * format does, and we want to retain that separation.
- */
- protected boolean _got32BitFloat;
-
- /*
- /**********************************************************
- /* Symbol handling, decoding
- /**********************************************************
- */
-
- /**
- * Symbol table that contains field names encountered so far
- */
- final protected BytesToNameCanonicalizer _symbols;
-
- /**
- * Temporary buffer used for name parsing.
- */
- protected int[] _quadBuffer = NO_INTS;
-
- /**
- * Quads used for hash calculation
- */
- protected int _quad1, _quad2;
-
- /**
- * Array of recently seen field names, which may be back referenced
- * by later fields.
- * Defaults set to enable handling even if no header found.
- */
- protected String[] _seenNames = NO_STRINGS;
-
- protected int _seenNameCount = 0;
-
- /**
- * Array of recently seen field names, which may be back referenced
- * by later fields
- * Defaults set to disable handling if no header found.
- */
- protected String[] _seenStringValues = null;
-
- protected int _seenStringValueCount = -1;
-
- /*
- /**********************************************************
- /* Thread-local recycling
- /**********************************************************
- */
-
- /**
- * <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftRerefence}
- * to a buffer recycler used to provide a low-cost
- * buffer recycling for Smile-specific buffers.
- */
- final protected static ThreadLocal<SoftReference<SmileBufferRecycler<String>>> _smileRecyclerRef
- = new ThreadLocal<SoftReference<SmileBufferRecycler<String>>>();
-
- /*
- /**********************************************************
- /* Life-cycle
- /**********************************************************
- */
-
- public SmileParser(IOContext ctxt, int parserFeatures, int smileFeatures,
- ObjectCodec codec,
- BytesToNameCanonicalizer sym,
- InputStream in, byte[] inputBuffer, int start, int end,
- boolean bufferRecyclable)
- {
- super(ctxt, parserFeatures);
- _objectCodec = codec;
- _symbols = sym;
-
- _inputStream = in;
- _inputBuffer = inputBuffer;
- _inputPtr = start;
- _inputEnd = end;
- _bufferRecyclable = bufferRecyclable;
-
- _tokenInputRow = -1;
- _tokenInputCol = -1;
- _smileBufferRecycler = _smileBufferRecycler();
- }
-
- @Override
- public ObjectCodec getCodec() {
- return _objectCodec;
- }
-
- @Override
- public void setCodec(ObjectCodec c) {
- _objectCodec = c;
- }
-
- /**
- * Helper method called when it looks like input might contain the signature;
- * and it is necessary to detect and handle signature to get configuration
- * information it might have.
- *
- * @return True if valid signature was found and handled; false if not
- */
- protected boolean handleSignature(boolean consumeFirstByte, boolean throwException)
- throws IOException, JsonParseException
- {
- if (consumeFirstByte) {
- ++_inputPtr;
- }
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- if (_inputBuffer[_inputPtr] != SmileConstants.HEADER_BYTE_2) {
- if (throwException) {
- _reportError("Malformed content: signature not valid, starts with 0x3a but followed by 0x"
- +Integer.toHexString(_inputBuffer[_inputPtr])+", not 0x29");
- }
- return false;
- }
- if (++_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- if (_inputBuffer[_inputPtr] != SmileConstants.HEADER_BYTE_3) {
- if (throwException) {
- _reportError("Malformed content: signature not valid, starts with 0x3a, 0x29, but followed by 0x"
- +Integer.toHexString(_inputBuffer[_inputPtr])+", not 0xA");
- }
- return false;
- }
- // Good enough; just need version info from 4th byte...
- if (++_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int ch = _inputBuffer[_inputPtr++];
- int versionBits = (ch >> 4) & 0x0F;
- // but failure with version number is fatal, can not ignore
- if (versionBits != SmileConstants.HEADER_VERSION_0) {
- _reportError("Header version number bits (0x"+Integer.toHexString(versionBits)+") indicate unrecognized version; only 0x0 handled by parser");
- }
-
- // can avoid tracking names, if explicitly disabled
- if ((ch & SmileConstants.HEADER_BIT_HAS_SHARED_NAMES) == 0) {
- _seenNames = null;
- _seenNameCount = -1;
- }
- // conversely, shared string values must be explicitly enabled
- if ((ch & SmileConstants.HEADER_BIT_HAS_SHARED_STRING_VALUES) != 0) {
- _seenStringValues = NO_STRINGS;
- _seenStringValueCount = 0;
- }
- _mayContainRawBinary = ((ch & SmileConstants.HEADER_BIT_HAS_RAW_BINARY) != 0);
- return true;
- }
-
- /**
- * @since 1.7
- */
- protected final static SmileBufferRecycler<String> _smileBufferRecycler()
- {
- SoftReference<SmileBufferRecycler<String>> ref = _smileRecyclerRef.get();
- SmileBufferRecycler<String> br = (ref == null) ? null : ref.get();
-
- if (br == null) {
- br = new SmileBufferRecycler<String>();
- _smileRecyclerRef.set(new SoftReference<SmileBufferRecycler<String>>(br));
- }
- return br;
- }
-
- /*
- /**********************************************************
- /* Former StreamBasedParserBase methods
- /**********************************************************
- */
-
- @Override
- public int releaseBuffered(OutputStream out) throws IOException
- {
- int count = _inputEnd - _inputPtr;
- if (count < 1) {
- return 0;
- }
- // let's just advance ptr to end
- int origPtr = _inputPtr;
- out.write(_inputBuffer, origPtr, count);
- return count;
- }
-
- @Override
- public Object getInputSource() {
- return _inputStream;
- }
-
- /**
- * Overridden since we do not really have character-based locations,
- * but we do have byte offset to specify.
- */
- @Override
- public JsonLocation getTokenLocation()
- {
- return new JsonLocation(_ioContext.getSourceReference(),
- _tokenInputTotal, // bytes
- -1, -1, -1); // char offset, line, column
- }
-
- /**
- * Overridden since we do not really have character-based locations,
- * but we do have byte offset to specify.
- */
- @Override
- public JsonLocation getCurrentLocation()
- {
- return new JsonLocation(_ioContext.getSourceReference(),
- _currInputProcessed + _inputPtr, // bytes
- -1, -1, -1); // char offset, line, column
- }
-
- /*
- /**********************************************************
- /* Low-level reading, other
- /**********************************************************
- */
-
- @Override
- protected final boolean loadMore()
- throws IOException
- {
- _currInputProcessed += _inputEnd;
- //_currInputRowStart -= _inputEnd;
-
- if (_inputStream != null) {
- int count = _inputStream.read(_inputBuffer, 0, _inputBuffer.length);
- if (count > 0) {
- _inputPtr = 0;
- _inputEnd = count;
- return true;
- }
- // End of input
- _closeInput();
- // Should never return 0, so let's fail
- if (count == 0) {
- throw new IOException("InputStream.read() returned 0 characters when trying to read "+_inputBuffer.length+" bytes");
- }
- }
- return false;
- }
-
- /**
- * Helper method that will try to load at least specified number bytes in
- * input buffer, possible moving existing data around if necessary
- *
- * @since 1.6
- */
- protected final boolean _loadToHaveAtLeast(int minAvailable)
- throws IOException
- {
- // No input stream, no leading (either we are closed, or have non-stream input source)
- if (_inputStream == null) {
- return false;
- }
- // Need to move remaining data in front?
- int amount = _inputEnd - _inputPtr;
- if (amount > 0 && _inputPtr > 0) {
- _currInputProcessed += _inputPtr;
- //_currInputRowStart -= _inputPtr;
- System.arraycopy(_inputBuffer, _inputPtr, _inputBuffer, 0, amount);
- _inputEnd = amount;
- } else {
- _inputEnd = 0;
- }
- _inputPtr = 0;
- while (_inputEnd < minAvailable) {
- int count = _inputStream.read(_inputBuffer, _inputEnd, _inputBuffer.length - _inputEnd);
- if (count < 1) {
- // End of input
- _closeInput();
- // Should never return 0, so let's fail
- if (count == 0) {
- throw new IOException("InputStream.read() returned 0 characters when trying to read "+amount+" bytes");
- }
- return false;
- }
- _inputEnd += count;
- }
- return true;
- }
-
- @Override
- protected void _closeInput() throws IOException
- {
- /* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
- * on the underlying InputStream, unless we "own" it, or auto-closing
- * feature is enabled.
- */
- if (_inputStream != null) {
- if (_ioContext.isResourceManaged() || isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) {
- _inputStream.close();
- }
- _inputStream = null;
- }
- }
-
- /*
- /**********************************************************
- /* Overridden methods
- /**********************************************************
- */
-
- @Override
- protected void _finishString() throws IOException, JsonParseException
- {
- // should never be called; but must be defined for superclass
- _throwInternal();
- }
-
- @Override
- public void close() throws IOException
- {
- super.close();
- // Merge found symbols, if any:
- _symbols.release();
- }
-
- @Override
- public boolean hasTextCharacters()
- {
- if (_currToken == JsonToken.VALUE_STRING) {
- // yes; is or can be made available efficiently as char[]
- return _textBuffer.hasTextAsCharacters();
- }
- if (_currToken == JsonToken.FIELD_NAME) {
- // not necessarily; possible but:
- return _nameCopied;
- }
- // other types, no benefit from accessing as char[]
- return false;
- }
-
- /**
- * Method called to release internal buffers owned by the base
- * reader. This may be called along with {@link #_closeInput} (for
- * example, when explicitly closing this reader instance), or
- * separately (if need be).
- */
- @Override
- protected void _releaseBuffers() throws IOException
- {
- super._releaseBuffers();
- if (_bufferRecyclable) {
- byte[] buf = _inputBuffer;
- if (buf != null) {
- _inputBuffer = null;
- _ioContext.releaseReadIOBuffer(buf);
- }
- }
- {
- String[] nameBuf = _seenNames;
- if (nameBuf != null && nameBuf.length > 0) {
- _seenNames = null;
- /* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer;
- * but we only need to clear up to count as it is not a hash area
- */
- if (_seenNameCount > 0) {
- Arrays.fill(nameBuf, 0, _seenNameCount, null);
- }
- _smileBufferRecycler.releaseSeenNamesBuffer(nameBuf);
- }
- }
- {
- String[] valueBuf = _seenStringValues;
- if (valueBuf != null && valueBuf.length > 0) {
- _seenStringValues = null;
- /* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer;
- * but we only need to clear up to count as it is not a hash area
- */
- if (_seenStringValueCount > 0) {
- Arrays.fill(valueBuf, 0, _seenStringValueCount, null);
- }
- _smileBufferRecycler.releaseSeenStringValuesBuffer(valueBuf);
- }
- }
- }
-
- /*
- /**********************************************************
- /* Extended API
- /**********************************************************
- */
-
- public boolean mayContainRawBinary() {
- return _mayContainRawBinary;
- }
-
- /*
- /**********************************************************
- /* JsonParser impl
- /**********************************************************
- */
-
- @Override
- public JsonToken nextToken() throws IOException, JsonParseException
- {
- _numTypesValid = NR_UNKNOWN;
- // For longer tokens (text, binary), we'll only read when requested
- if (_tokenIncomplete) {
- _skipIncomplete();
- }
- _tokenInputTotal = _currInputProcessed + _inputPtr;
- // also: clear any data retained so far
- _binaryValue = null;
- // Two main modes: values, and field names.
- if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
- return (_currToken = _handleFieldName());
- }
- if (_inputPtr >= _inputEnd) {
- if (!loadMore()) {
- _handleEOF();
- /* NOTE: here we can and should close input, release buffers,
- * since this is "hard" EOF, not a boundary imposed by
- * header token.
- */
- close();
- return (_currToken = null);
- }
- }
- int ch = _inputBuffer[_inputPtr++];
- _typeByte = ch;
- switch ((ch >> 5) & 0x7) {
- case 0: // short shared string value reference
- if (ch == 0) { // important: this is invalid, don't accept
- _reportError("Invalid token byte 0x00");
- }
- return _handleSharedString(ch-1);
-
- case 1: // simple literals, numbers
- {
- int typeBits = ch & 0x1F;
- if (typeBits < 4) {
- switch (typeBits) {
- case 0x00:
- _textBuffer.resetWithEmpty();
- return (_currToken = JsonToken.VALUE_STRING);
- case 0x01:
- return (_currToken = JsonToken.VALUE_NULL);
- case 0x02: // false
- return (_currToken = JsonToken.VALUE_FALSE);
- default: // 0x03 == true
- return (_currToken = JsonToken.VALUE_TRUE);
- }
- }
- // next 3 bytes define subtype
- if (typeBits < 8) { // VInt (zigzag), BigInteger
- if ((typeBits & 0x3) <= 0x2) { // 0x3 reserved (should never occur)
- _tokenIncomplete = true;
- _numTypesValid = 0;
- return (_currToken = JsonToken.VALUE_NUMBER_INT);
- }
- break;
- }
- if (typeBits < 12) { // floating-point
- int subtype = typeBits & 0x3;
- if (subtype <= 0x2) { // 0x3 reserved (should never occur)
- _tokenIncomplete = true;
- _numTypesValid = 0;
- _got32BitFloat = (subtype == 0);
- return (_currToken = JsonToken.VALUE_NUMBER_FLOAT);
- }
- break;
- }
- if (typeBits == 0x1A) { // == 0x3A == ':' -> possibly header signature for next chunk?
- if (handleSignature(false, false)) {
- /* Ok, now; end-marker and header both imply doc boundary and a
- * 'null token'; but if both are seen, they are collapsed.
- * We can check this by looking at current token; if it's null,
- * need to get non-null token
- */
- if (_currToken == null) {
- return nextToken();
- }
- return (_currToken = null);
- }
- }
- _reportError("Unrecognized token byte 0x3A (malformed segment header?");
- }
- // and everything else is reserved, for now
- break;
- case 2: // tiny ASCII
- // fall through
- case 3: // short ASCII
- // fall through
- case 4: // tiny Unicode
- // fall through
- case 5: // short Unicode
- // No need to decode, unless we have to keep track of back-references (for shared string values)
- _currToken = JsonToken.VALUE_STRING;
- if (_seenStringValueCount >= 0) { // shared text values enabled
- _addSeenStringValue();
- } else {
- _tokenIncomplete = true;
- }
- return _currToken;
- case 6: // small integers; zigzag encoded
- _numberInt = SmileUtil.zigzagDecode(ch & 0x1F);
- _numTypesValid = NR_INT;
- return (_currToken = JsonToken.VALUE_NUMBER_INT);
- case 7: // binary/long-text/long-shared/start-end-markers
- switch (ch & 0x1F) {
- case 0x00: // long variable length ASCII
- case 0x04: // long variable length unicode
- _tokenIncomplete = true;
- return (_currToken = JsonToken.VALUE_STRING);
- case 0x08: // binary, 7-bit
- _tokenIncomplete = true;
- return (_currToken = JsonToken.VALUE_EMBEDDED_OBJECT);
- case 0x0C: // long shared string
- case 0x0D:
- case 0x0E:
- case 0x0F:
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- return _handleSharedString(((ch & 0x3) << 8) + (_inputBuffer[_inputPtr++] & 0xFF));
- case 0x18: // START_ARRAY
- _parsingContext = _parsingContext.createChildArrayContext(-1, -1);
- return (_currToken = JsonToken.START_ARRAY);
- case 0x19: // END_ARRAY
- if (!_parsingContext.inArray()) {
- _reportMismatchedEndMarker(']', '}');
- }
- _parsingContext = _parsingContext.getParent();
- return (_currToken = JsonToken.END_ARRAY);
- case 0x1A: // START_OBJECT
- _parsingContext = _parsingContext.createChildObjectContext(-1, -1);
- return (_currToken = JsonToken.START_OBJECT);
- case 0x1B: // not used in this mode; would be END_OBJECT
- _reportError("Invalid type marker byte 0xFB in value mode (would be END_OBJECT in key mode)");
- case 0x1D: // binary, raw
- _tokenIncomplete = true;
- return (_currToken = JsonToken.VALUE_EMBEDDED_OBJECT);
- case 0x1F: // 0xFF, end of content
- return (_currToken = null);
- }
- break;
- }
- // If we get this far, type byte is corrupt
- _reportError("Invalid type marker byte 0x"+Integer.toHexString(ch & 0xFF)+" for expected value token");
- return null;
- }
-
- private final JsonToken _handleSharedString(int index)
- throws IOException, JsonParseException
- {
- if (index >= _seenStringValueCount) {
- _reportInvalidSharedStringValue(index);
- }
- _textBuffer.resetWithString(_seenStringValues[index]);
- return (_currToken = JsonToken.VALUE_STRING);
- }
-
- private final void _addSeenStringValue()
- throws IOException, JsonParseException
- {
- _finishToken();
- if (_seenStringValueCount < _seenStringValues.length) {
- // !!! TODO: actually only store char[], first time around?
- _seenStringValues[_seenStringValueCount++] = _textBuffer.contentsAsString();
- return;
- }
- _expandSeenStringValues();
- }
-
- private final void _expandSeenStringValues()
- {
- String[] oldShared = _seenStringValues;
- int len = oldShared.length;
- String[] newShared;
- if (len == 0) {
- newShared = _smileBufferRecycler.allocSeenStringValuesBuffer();
- if (newShared == null) {
- newShared = new String[SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH];
- }
- } else if (len == SmileConstants.MAX_SHARED_STRING_VALUES) { // too many? Just flush...
- newShared = oldShared;
- _seenStringValueCount = 0; // could also clear, but let's not yet bother
- } else {
- int newSize = (len == SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH) ? 256 : SmileConstants.MAX_SHARED_STRING_VALUES;
- newShared = new String[newSize];
- System.arraycopy(oldShared, 0, newShared, 0, oldShared.length);
- }
- _seenStringValues = newShared;
- _seenStringValues[_seenStringValueCount++] = _textBuffer.contentsAsString();
- }
-
- @Override
- public String getCurrentName() throws IOException, JsonParseException
- {
- return _parsingContext.getCurrentName();
- }
-
- @Override
- public NumberType getNumberType()
- throws IOException, JsonParseException
- {
- if (_got32BitFloat) {
- return NumberType.FLOAT;
- }
- return super.getNumberType();
- }
-
- /*
- /**********************************************************
- /* Public API, traversal, nextXxxValue/nextFieldName
- /**********************************************************
- */
-
- @Override
- public boolean nextFieldName(SerializableString str)
- throws IOException, JsonParseException
- {
- // Two parsing modes; can only succeed if expecting field name, so handle that first:
- if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
- byte[] nameBytes = str.asQuotedUTF8();
- final int byteLen = nameBytes.length;
- // need room for type byte, name bytes, possibly end marker, so:
- if ((_inputPtr + byteLen + 1) < _inputEnd) { // maybe...
- int ptr = _inputPtr;
- int ch = _inputBuffer[ptr++];
- _typeByte = ch;
- main_switch:
- switch ((ch >> 6) & 3) {
- case 0: // misc, including end marker
- switch (ch) {
- case 0x20: // empty String as name, legal if unusual
- _currToken = JsonToken.FIELD_NAME;
- _inputPtr = ptr;
- _parsingContext.setCurrentName("");
- return (byteLen == 0);
- case 0x30: // long shared
- case 0x31:
- case 0x32:
- case 0x33:
- {
- int index = ((ch & 0x3) << 8) + (_inputBuffer[ptr++] & 0xFF);
- if (index >= _seenNameCount) {
- _reportInvalidSharedName(index);
- }
- String name = _seenNames[index];
- _parsingContext.setCurrentName(name);
- _inputPtr = ptr;
- _currToken = JsonToken.FIELD_NAME;
- return (name.equals(str.getValue()));
- }
- //case 0x34: // long ASCII/Unicode name; let's not even try...
- }
- break;
- case 1: // short shared, can fully process
- {
- int index = (ch & 0x3F);
- if (index >= _seenNameCount) {
- _reportInvalidSharedName(index);
- }
- _parsingContext.setCurrentName(_seenNames[index]);
- String name = _seenNames[index];
- _parsingContext.setCurrentName(name);
- _inputPtr = ptr;
- _currToken = JsonToken.FIELD_NAME;
- return (name.equals(str.getValue()));
- }
- case 2: // short ASCII
- {
- int len = 1 + (ch & 0x3f);
- if (len == byteLen) {
- int i = 0;
- for (; i < len; ++i) {
- if (nameBytes[i] != _inputBuffer[ptr+i]) {
- break main_switch;
- }
- }
- // yes, does match...
- _inputPtr = ptr + len;
- final String name = str.getValue();
- if (_seenNames != null) {
- if (_seenNameCount >= _seenNames.length) {
- _seenNames = _expandSeenNames(_seenNames);
- }
- _seenNames[_seenNameCount++] = name;
- }
- _parsingContext.setCurrentName(name);
- _currToken = JsonToken.FIELD_NAME;
- return true;
- }
- }
- break;
- case 3: // short Unicode
- // all valid, except for 0xFF
- {
- int len = (ch & 0x3F);
- if (len > 0x37) {
- if (len == 0x3B) {
- _currToken = JsonToken.END_OBJECT;
- if (!_parsingContext.inObject()) {
- _reportMismatchedEndMarker('}', ']');
- }
- _inputPtr = ptr;
- _parsingContext = _parsingContext.getParent();
- return false;
- }
- // error, but let's not worry about that here
- break;
- }
- len += 2; // values from 2 to 57...
- if (len == byteLen) {
- int i = 0;
- for (; i < len; ++i) {
- if (nameBytes[i] != _inputBuffer[ptr+i]) {
- break main_switch;
- }
- }
- // yes, does match...
- _inputPtr = ptr + len;
- final String name = str.getValue();
- if (_seenNames != null) {
- if (_seenNameCount >= _seenNames.length) {
- _seenNames = _expandSeenNames(_seenNames);
- }
- _seenNames[_seenNameCount++] = name;
- }
- _parsingContext.setCurrentName(name);
- _currToken = JsonToken.FIELD_NAME;
- return true;
- }
- }
- break;
- }
- }
- // otherwise fall back to default processing:
- JsonToken t = _handleFieldName();
- _currToken = t;
- return (t == JsonToken.FIELD_NAME) && str.getValue().equals(_parsingContext.getCurrentName());
- }
- // otherwise just fall back to default handling; should occur rarely
- return (nextToken() == JsonToken.FIELD_NAME) && str.getValue().equals(getCurrentName());
- }
-
- @Override
- public String nextTextValue()
- throws IOException, JsonParseException
- {
- // can't get text value if expecting name, so
- if (!_parsingContext.inObject() || _currToken == JsonToken.FIELD_NAME) {
- if (_tokenIncomplete) {
- _skipIncomplete();
- }
- int ptr = _inputPtr;
- if (ptr >= _inputEnd) {
- if (!loadMore()) {
- _handleEOF();
- close();
- _currToken = null;
- return null;
- }
- ptr = _inputPtr;
- }
- int ch = _inputBuffer[ptr++];
- _tokenInputTotal = _currInputProcessed + _inputPtr;
-
- // also: clear any data retained so far
- _binaryValue = null;
- _typeByte = ch;
-
- switch ((ch >> 5) & 0x7) {
- case 0: // short shared string value reference
- if (ch == 0) { // important: this is invalid, don't accept
- _reportError("Invalid token byte 0x00");
- }
- // _handleSharedString...
- {
- --ch;
- if (ch >= _seenStringValueCount) {
- _reportInvalidSharedStringValue(ch);
- }
- _inputPtr = ptr;
- String text = _seenStringValues[ch];
- _textBuffer.resetWithString(text);
- _currToken = JsonToken.VALUE_STRING;
- return text;
- }
-
- case 1: // simple literals, numbers
- {
- int typeBits = ch & 0x1F;
- if (typeBits == 0x00) {
- _inputPtr = ptr;
- _textBuffer.resetWithEmpty();
- _currToken = JsonToken.VALUE_STRING;
- return "";
- }
- }
- break;
- case 2: // tiny ASCII
- // fall through
- case 3: // short ASCII
- _currToken = JsonToken.VALUE_STRING;
- _inputPtr = ptr;
- _decodeShortAsciiValue(1 + (ch & 0x3F));
- {
- // No need to decode, unless we have to keep track of back-references (for shared string values)
- String text;
- if (_seenStringValueCount >= 0) { // shared text values enabled
- if (_seenStringValueCount < _seenStringValues.length) {
- text = _textBuffer.contentsAsString();
- _seenStringValues[_seenStringValueCount++] = text;
- } else {
- _expandSeenStringValues();
- text = _textBuffer.contentsAsString();
- }
- } else {
- text = _textBuffer.contentsAsString();
- }
- return text;
- }
-
- case 4: // tiny Unicode
- // fall through
- case 5: // short Unicode
- _currToken = JsonToken.VALUE_STRING;
- _inputPtr = ptr;
- _decodeShortUnicodeValue(2 + (ch & 0x3F));
- {
- // No need to decode, unless we have to keep track of back-references (for shared string values)
- String text;
- if (_seenStringValueCount >= 0) { // shared text values enabled
- if (_seenStringValueCount < _seenStringValues.length) {
- text = _textBuffer.contentsAsString();
- _seenStringValues[_seenStringValueCount++] = text;
- } else {
- _expandSeenStringValues();
- text = _textBuffer.contentsAsString();
- }
- } else {
- text = _textBuffer.contentsAsString();
- }
- return text;
- }
- case 6: // small integers; zigzag encoded
- break;
- case 7: // binary/long-text/long-shared/start-end-markers
- // TODO: support longer strings too?
- /*
- switch (ch & 0x1F) {
- case 0x00: // long variable length ASCII
- case 0x04: // long variable length unicode
- _tokenIncomplete = true;
- return (_currToken = JsonToken.VALUE_STRING);
- case 0x08: // binary, 7-bit
- break main;
- case 0x0C: // long shared string
- case 0x0D:
- case 0x0E:
- case 0x0F:
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- return _handleSharedString(((ch & 0x3) << 8) + (_inputBuffer[_inputPtr++] & 0xFF));
- }
- break;
- */
- break;
- }
- }
- // otherwise fall back to generic handling:
- return (nextToken() == JsonToken.VALUE_STRING) ? getText() : null;
- }
-
- @Override
- public int nextIntValue(int defaultValue)
- throws IOException, JsonParseException
- {
- if (nextToken() == JsonToken.VALUE_NUMBER_INT) {
- return getIntValue();
- }
- return defaultValue;
- }
-
- @Override
- public long nextLongValue(long defaultValue)
- throws IOException, JsonParseException
- {
- if (nextToken() == JsonToken.VALUE_NUMBER_INT) {
- return getLongValue();
- }
- return defaultValue;
- }
-
- @Override
- public Boolean nextBooleanValue()
- throws IOException, JsonParseException
- {
- switch (nextToken()) {
- case VALUE_TRUE:
- return Boolean.TRUE;
- case VALUE_FALSE:
- return Boolean.FALSE;
- }
- return null;
- }
-
- /*
- /**********************************************************
- /* Public API, access to token information, text
- /**********************************************************
- */
-
- /**
- * Method for accessing textual representation of the current event;
- * if no current event (before first call to {@link #nextToken}, or
- * after encountering end-of-input), returns null.
- * Method can be called for any event.
- */
- @Override
- public String getText()
- throws IOException, JsonParseException
- {
- if (_tokenIncomplete) {
- _tokenIncomplete = false;
- // Let's inline part of "_finishToken", common case
- int tb = _typeByte;
- int type = (tb >> 5) & 0x7;
- if (type == 2 || type == 3) { // tiny & short ASCII
- _decodeShortAsciiValue(1 + (tb & 0x3F));
- return _textBuffer.contentsAsString();
- }
- if (type == 4 || type == 5) { // tiny & short Unicode
- // short unicode; note, lengths 2 - 65 (off-by-one compared to ASCII)
- _decodeShortUnicodeValue(2 + (tb & 0x3F));
- return _textBuffer.contentsAsString();
- }
- _finishToken();
- }
- if (_currToken == JsonToken.VALUE_STRING) {
- return _textBuffer.contentsAsString();
- }
- JsonToken t = _currToken;
- if (t == null) { // null only before/after document
- return null;
- }
- if (t == JsonToken.FIELD_NAME) {
- return _parsingContext.getCurrentName();
- }
- if (t.isNumeric()) {
- // TODO: optimize?
- return getNumberValue().toString();
- }
- return _currToken.asString();
- }
-
- @Override
- public char[] getTextCharacters()
- throws IOException, JsonParseException
- {
- if (_currToken != null) { // null only before/after document
- if (_tokenIncomplete) {
- _finishToken();
- }
- switch (_currToken) {
- case VALUE_STRING:
- return _textBuffer.getTextBuffer();
- case FIELD_NAME:
- if (!_nameCopied) {
- String name = _parsingContext.getCurrentName();
- int nameLen = name.length();
- if (_nameCopyBuffer == null) {
- _nameCopyBuffer = _ioContext.allocNameCopyBuffer(nameLen);
- } else if (_nameCopyBuffer.length < nameLen) {
- _nameCopyBuffer = new char[nameLen];
- }
- name.getChars(0, nameLen, _nameCopyBuffer, 0);
- _nameCopied = true;
- }
- return _nameCopyBuffer;
-
- // fall through
- case VALUE_NUMBER_INT:
- case VALUE_NUMBER_FLOAT:
- // TODO: optimize
- return getNumberValue().toString().toCharArray();
-
- default:
- return _currToken.asCharArray();
- }
- }
- return null;
- }
-
- @Override
- public int getTextLength()
- throws IOException, JsonParseException
- {
- if (_currToken != null) { // null only before/after document
- if (_tokenIncomplete) {
- _finishToken();
- }
- switch (_currToken) {
- case VALUE_STRING:
- return _textBuffer.size();
- case FIELD_NAME:
- return _parsingContext.getCurrentName().length();
- // fall through
- case VALUE_NUMBER_INT:
- case VALUE_NUMBER_FLOAT:
- // TODO: optimize
- return getNumberValue().toString().length();
-
- default:
- return _currToken.asCharArray().length;
- }
- }
- return 0;
- }
-
- @Override
- public int getTextOffset() throws IOException, JsonParseException
- {
- return 0;
- }
-
- /*
- /**********************************************************
- /* Public API, access to token information, binary
- /**********************************************************
- */
-
- @Override
- public byte[] getBinaryValue(Base64Variant b64variant)
- throws IOException, JsonParseException
- {
- if (_tokenIncomplete) {
- _finishToken();
- }
- if (_currToken != JsonToken.VALUE_EMBEDDED_OBJECT ) {
- // Todo, maybe: support base64 for text?
- _reportError("Current token ("+_currToken+") not VALUE_EMBEDDED_OBJECT, can not access as binary");
- }
- return _binaryValue;
- }
-
- @Override
- protected byte[] _decodeBase64(Base64Variant b64variant)
- throws IOException, JsonParseException
- {
- // Should never get called, but must be defined for base class
- _throwInternal();
- return null;
- }
-
- /*
- /**********************************************************
- /* Internal methods, field name parsing
- /**********************************************************
- */
-
- /**
- * Method that handles initial token type recognition for token
- * that has to be either FIELD_NAME or END_OBJECT.
- */
- protected final JsonToken _handleFieldName() throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int ch = _inputBuffer[_inputPtr++];
- // is this needed?
- _typeByte = ch;
- switch ((ch >> 6) & 3) {
- case 0: // misc, including end marker
- switch (ch) {
- case 0x20: // empty String as name, legal if unusual
- _parsingContext.setCurrentName("");
- return JsonToken.FIELD_NAME;
- case 0x30: // long shared
- case 0x31:
- case 0x32:
- case 0x33:
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int index = ((ch & 0x3) << 8) + (_inputBuffer[_inputPtr++] & 0xFF);
- if (index >= _seenNameCount) {
- _reportInvalidSharedName(index);
- }
- _parsingContext.setCurrentName(_seenNames[index]);
- }
- return JsonToken.FIELD_NAME;
- case 0x34: // long ASCII/Unicode name
- _handleLongFieldName();
- return JsonToken.FIELD_NAME;
- }
- break;
- case 1: // short shared, can fully process
- {
- int index = (ch & 0x3F);
- if (index >= _seenNameCount) {
- _reportInvalidSharedName(index);
- }
- _parsingContext.setCurrentName(_seenNames[index]);
- }
- return JsonToken.FIELD_NAME;
- case 2: // short ASCII
- {
- int len = 1 + (ch & 0x3f);
- String name;
- Name n = _findDecodedFromSymbols(len);
- if (n != null) {
- name = n.getName();
- _inputPtr += len;
- } else {
- name = _decodeShortAsciiName(len);
- name = _addDecodedToSymbols(len, name);
- }
- if (_seenNames != null) {
- if (_seenNameCount >= _seenNames.length) {
- _seenNames = _expandSeenNames(_seenNames);
- }
- _seenNames[_seenNameCount++] = name;
- }
- _parsingContext.setCurrentName(name);
- }
- return JsonToken.FIELD_NAME;
- case 3: // short Unicode
- // all valid, except for 0xFF
- ch &= 0x3F;
- {
- if (ch > 0x37) {
- if (ch == 0x3B) {
- if (!_parsingContext.inObject()) {
- _reportMismatchedEndMarker('}', ']');
- }
- _parsingContext = _parsingContext.getParent();
- return JsonToken.END_OBJECT;
- }
- } else {
- final int len = ch + 2; // values from 2 to 57...
- String name;
- Name n = _findDecodedFromSymbols(len);
- if (n != null) {
- name = n.getName();
- _inputPtr += len;
- } else {
- name = _decodeShortUnicodeName(len);
- name = _addDecodedToSymbols(len, name);
- }
- if (_seenNames != null) {
- if (_seenNameCount >= _seenNames.length) {
- _seenNames = _expandSeenNames(_seenNames);
- }
- _seenNames[_seenNameCount++] = name;
- }
- _parsingContext.setCurrentName(name);
- return JsonToken.FIELD_NAME;
- }
- }
- break;
- }
- // Other byte values are illegal
- _reportError("Invalid type marker byte 0x"+Integer.toHexString(_typeByte)+" for expected field name (or END_OBJECT marker)");
- return null;
- }
-
- /**
- * Method called to try to expand shared name area to fit one more potentially
- * shared String. If area is already at its biggest size, will just clear
- * the area (by setting next-offset to 0)
- */
- private final String[] _expandSeenNames(String[] oldShared)
- {
- int len = oldShared.length;
- String[] newShared;
- if (len == 0) {
- newShared = _smileBufferRecycler.allocSeenNamesBuffer();
- if (newShared == null) {
- newShared = new String[SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH];
- }
- } else if (len == SmileConstants.MAX_SHARED_NAMES) { // too many? Just flush...
- newShared = oldShared;
- _seenNameCount = 0; // could also clear, but let's not yet bother
- } else {
- int newSize = (len == SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH) ? 256 : SmileConstants.MAX_SHARED_NAMES;
- newShared = new String[newSize];
- System.arraycopy(oldShared, 0, newShared, 0, oldShared.length);
- }
- return newShared;
- }
-
- private final String _addDecodedToSymbols(int len, String name)
- {
- if (len < 5) {
- return _symbols.addName(name, _quad1, 0).getName();
- }
- if (len < 9) {
- return _symbols.addName(name, _quad1, _quad2).getName();
- }
- int qlen = (len + 3) >> 2;
- return _symbols.addName(name, _quadBuffer, qlen).getName();
- }
-
- private final String _decodeShortAsciiName(int len)
- throws IOException, JsonParseException
- {
- // note: caller ensures we have enough bytes available
- char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- int outPtr = 0;
- final byte[] inBuf = _inputBuffer;
- int inPtr = _inputPtr;
-
- // loop unrolling seems to help here:
- for (int inEnd = inPtr + len - 3; inPtr < inEnd; ) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- }
- int left = (len & 3);
- if (left > 0) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- if (left > 1) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- if (left > 2) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- }
- }
- }
- _inputPtr = inPtr;
- _textBuffer.setCurrentLength(len);
- return _textBuffer.contentsAsString();
- }
-
- /**
- * Helper method used to decode short Unicode string, length for which actual
- * length (in bytes) is known
- *
- * @param len Length between 1 and 64
- */
- private final String _decodeShortUnicodeName(int len)
- throws IOException, JsonParseException
- {
- // note: caller ensures we have enough bytes available
- int outPtr = 0;
- char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- int inPtr = _inputPtr;
- _inputPtr += len;
- final int[] codes = SmileConstants.sUtf8UnitLengths;
- final byte[] inBuf = _inputBuffer;
- for (int end = inPtr + len; inPtr < end; ) {
- int i = inBuf[inPtr++] & 0xFF;
- int code = codes[i];
- if (code != 0) {
- // trickiest one, need surrogate handling
- switch (code) {
- case 1:
- i = ((i & 0x1F) << 6) | (inBuf[inPtr++] & 0x3F);
- break;
- case 2:
- i = ((i & 0x0F) << 12)
- | ((inBuf[inPtr++] & 0x3F) << 6)
- | (inBuf[inPtr++] & 0x3F);
- break;
- case 3:
- i = ((i & 0x07) << 18)
- | ((inBuf[inPtr++] & 0x3F) << 12)
- | ((inBuf[inPtr++] & 0x3F) << 6)
- | (inBuf[inPtr++] & 0x3F);
- // note: this is the codepoint value; need to split, too
- i -= 0x10000;
- outBuf[outPtr++] = (char) (0xD800 | (i >> 10));
- i = 0xDC00 | (i & 0x3FF);
- break;
- default: // invalid
- _reportError("Invalid byte "+Integer.toHexString(i)+" in short Unicode text block");
- }
- }
- outBuf[outPtr++] = (char) i;
- }
- _textBuffer.setCurrentLength(outPtr);
- return _textBuffer.contentsAsString();
- }
-
- // note: slightly edited copy of UTF8StreamParser.addName()
- private final Name _decodeLongUnicodeName(int[] quads, int byteLen, int quadLen)
- throws IOException, JsonParseException
- {
- int lastQuadBytes = byteLen & 3;
- // Ok: must decode UTF-8 chars. No other validation SHOULD be needed (except bounds checks?)
- /* Note: last quad is not correctly aligned (leading zero bytes instead
- * need to shift a bit, instead of trailing). Only need to shift it
- * for UTF-8 decoding; need revert for storage (since key will not
- * be aligned, to optimize lookup speed)
- */
- int lastQuad;
-
- if (lastQuadBytes < 4) {
- lastQuad = quads[quadLen-1];
- // 8/16/24 bit left shift
- quads[quadLen-1] = (lastQuad << ((4 - lastQuadBytes) << 3));
- } else {
- lastQuad = 0;
- }
-
- char[] cbuf = _textBuffer.emptyAndGetCurrentSegment();
- int cix = 0;
-
- for (int ix = 0; ix < byteLen; ) {
- int ch = quads[ix >> 2]; // current quad, need to shift+mask
- int byteIx = (ix & 3);
- ch = (ch >> ((3 - byteIx) << 3)) & 0xFF;
- ++ix;
-
- if (ch > 127) { // multi-byte
- int needed;
- if ((ch & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF)
- ch &= 0x1F;
- needed = 1;
- } else if ((ch & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF)
- ch &= 0x0F;
- needed = 2;
- } else if ((ch & 0xF8) == 0xF0) { // 4 bytes; double-char with surrogates and all...
- ch &= 0x07;
- needed = 3;
- } else { // 5- and 6-byte chars not valid chars
- _reportInvalidInitial(ch);
- needed = ch = 1; // never really gets this far
- }
- if ((ix + needed) > byteLen) {
- _reportInvalidEOF(" in long field name");
- }
-
- // Ok, always need at least one more:
- int ch2 = quads[ix >> 2]; // current quad, need to shift+mask
- byteIx = (ix & 3);
- ch2 = (ch2 >> ((3 - byteIx) << 3));
- ++ix;
-
- if ((ch2 & 0xC0) != 0x080) {
- _reportInvalidOther(ch2);
- }
- ch = (ch << 6) | (ch2 & 0x3F);
- if (needed > 1) {
- ch2 = quads[ix >> 2];
- byteIx = (ix & 3);
- ch2 = (ch2 >> ((3 - byteIx) << 3));
- ++ix;
-
- if ((ch2 & 0xC0) != 0x080) {
- _reportInvalidOther(ch2);
- }
- ch = (ch << 6) | (ch2 & 0x3F);
- if (needed > 2) { // 4 bytes? (need surrogates on output)
- ch2 = quads[ix >> 2];
- byteIx = (ix & 3);
- ch2 = (ch2 >> ((3 - byteIx) << 3));
- ++ix;
- if ((ch2 & 0xC0) != 0x080) {
- _reportInvalidOther(ch2 & 0xFF);
- }
- ch = (ch << 6) | (ch2 & 0x3F);
- }
- }
- if (needed > 2) { // surrogate pair? once again, let's output one here, one later on
- ch -= 0x10000; // to normalize it starting with 0x0
- if (cix >= cbuf.length) {
- cbuf = _textBuffer.expandCurrentSegment();
- }
- cbuf[cix++] = (char) (0xD800 + (ch >> 10));
- ch = 0xDC00 | (ch & 0x03FF);
- }
- }
- if (cix >= cbuf.length) {
- cbuf = _textBuffer.expandCurrentSegment();
- }
- cbuf[cix++] = (char) ch;
- }
-
- // Ok. Now we have the character array, and can construct the String
- String baseName = new String(cbuf, 0, cix);
- // And finally, un-align if necessary
- if (lastQuadBytes < 4) {
- quads[quadLen-1] = lastQuad;
- }
- return _symbols.addName(baseName, quads, quadLen);
- }
-
- private final void _handleLongFieldName() throws IOException, JsonParseException
- {
- // First: gather quads we need, looking for end marker
- final byte[] inBuf = _inputBuffer;
- int quads = 0;
- int bytes = 0;
- int q = 0;
-
- while (true) {
- byte b = inBuf[_inputPtr++];
- if (BYTE_MARKER_END_OF_STRING == b) {
- bytes = 0;
- break;
- }
- q = ((int) b) & 0xFF;
- b = inBuf[_inputPtr++];
- if (BYTE_MARKER_END_OF_STRING == b) {
- bytes = 1;
- break;
- }
- q = (q << 8) | (b & 0xFF);
- b = inBuf[_inputPtr++];
- if (BYTE_MARKER_END_OF_STRING == b) {
- bytes = 2;
- break;
- }
- q = (q << 8) | (b & 0xFF);
- b = inBuf[_inputPtr++];
- if (BYTE_MARKER_END_OF_STRING == b) {
- bytes = 3;
- break;
- }
- q = (q << 8) | (b & 0xFF);
- if (quads >= _quadBuffer.length) {
- _quadBuffer = _growArrayTo(_quadBuffer, _quadBuffer.length + 256); // grow by 1k
- }
- _quadBuffer[quads++] = q;
- }
- // and if we have more bytes, append those too
- int byteLen = (quads << 2);
- if (bytes > 0) {
- if (quads >= _quadBuffer.length) {
- _quadBuffer = _growArrayTo(_quadBuffer, _quadBuffer.length + 256);
- }
- _quadBuffer[quads++] = q;
- byteLen += bytes;
- }
-
- // Know this name already?
- String name;
- Name n = _symbols.findName(_quadBuffer, quads);
- if (n != null) {
- name = n.getName();
- } else {
- name = _decodeLongUnicodeName(_quadBuffer, byteLen, quads).getName();
- }
- if (_seenNames != null) {
- if (_seenNameCount >= _seenNames.length) {
- _seenNames = _expandSeenNames(_seenNames);
- }
- _seenNames[_seenNameCount++] = name;
- }
- _parsingContext.setCurrentName(name);
- }
-
- /**
- * Helper method for trying to find specified encoded UTF-8 byte sequence
- * from symbol table; if successful avoids actual decoding to String
- */
- private final Name _findDecodedFromSymbols(int len)
- throws IOException, JsonParseException
- {
- if ((_inputEnd - _inputPtr) < len) {
- _loadToHaveAtLeast(len);
- }
- // First: maybe we already have this name decoded?
- if (len < 5) {
- int inPtr = _inputPtr;
- final byte[] inBuf = _inputBuffer;
- int q = inBuf[inPtr] & 0xFF;
- if (--len > 0) {
- q = (q << 8) + (inBuf[++inPtr] & 0xFF);
- if (--len > 0) {
- q = (q << 8) + (inBuf[++inPtr] & 0xFF);
- if (--len > 0) {
- q = (q << 8) + (inBuf[++inPtr] & 0xFF);
- }
- }
- }
- _quad1 = q;
- return _symbols.findName(q);
- }
- if (len < 9) {
- int inPtr = _inputPtr;
- final byte[] inBuf = _inputBuffer;
- // First quadbyte is easy
- int q1 = (inBuf[inPtr] & 0xFF) << 8;
- q1 += (inBuf[++inPtr] & 0xFF);
- q1 <<= 8;
- q1 += (inBuf[++inPtr] & 0xFF);
- q1 <<= 8;
- q1 += (inBuf[++inPtr] & 0xFF);
- int q2 = (inBuf[++inPtr] & 0xFF);
- len -= 5;
- if (len > 0) {
- q2 = (q2 << 8) + (inBuf[++inPtr] & 0xFF);
- if (--len > 0) {
- q2 = (q2 << 8) + (inBuf[++inPtr] & 0xFF);
- if (--len > 0) {
- q2 = (q2 << 8) + (inBuf[++inPtr] & 0xFF);
- }
- }
- }
- _quad1 = q1;
- _quad2 = q2;
- return _symbols.findName(q1, q2);
- }
- return _findDecodedMedium(len);
- }
-
- /**
- * Method for locating names longer than 8 bytes (in UTF-8)
- */
- private final Name _findDecodedMedium(int len)
- throws IOException, JsonParseException
- {
- // first, need enough buffer to store bytes as ints:
- {
- int bufLen = (len + 3) >> 2;
- if (bufLen > _quadBuffer.length) {
- _quadBuffer = _growArrayTo(_quadBuffer, bufLen);
- }
- }
- // then decode, full quads first
- int offset = 0;
- int inPtr = _inputPtr;
- final byte[] inBuf = _inputBuffer;
- do {
- int q = (inBuf[inPtr++] & 0xFF) << 8;
- q |= inBuf[inPtr++] & 0xFF;
- q <<= 8;
- q |= inBuf[inPtr++] & 0xFF;
- q <<= 8;
- q |= inBuf[inPtr++] & 0xFF;
- _quadBuffer[offset++] = q;
- } while ((len -= 4) > 3);
- // and then leftovers
- if (len > 0) {
- int q = inBuf[inPtr] & 0xFF;
- if (--len > 0) {
- q = (q << 8) + (inBuf[++inPtr] & 0xFF);
- if (--len > 0) {
- q = (q << 8) + (inBuf[++inPtr] & 0xFF);
- }
- }
- _quadBuffer[offset++] = q;
- }
- return _symbols.findName(_quadBuffer, offset);
- }
-
- private static int[] _growArrayTo(int[] arr, int minSize)
- {
- int[] newArray = new int[minSize + 4];
- if (arr != null) {
- // !!! TODO: JDK 1.6, Arrays.copyOf
- System.arraycopy(arr, 0, newArray, 0, arr.length);
- }
- return newArray;
- }
-
- /*
- /**********************************************************
- /* Internal methods, secondary parsing
- /**********************************************************
- */
-
- @Override
- protected void _parseNumericValue(int expType)
- throws IOException, JsonParseException
- {
- if (_tokenIncomplete) {
- int tb = _typeByte;
- // ensure we got a numeric type with value that is lazily parsed
- if (((tb >> 5) & 0x7) != 1) {
- _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors");
- }
- _tokenIncomplete = false;
- _finishNumberToken(tb);
- }
- }
-
- /**
- * Method called to finish parsing of a token so that token contents
- * are retriable
- */
- protected void _finishToken()
- throws IOException, JsonParseException
- {
- _tokenIncomplete = false;
- int tb = _typeByte;
-
- int type = ((tb >> 5) & 0x7);
- if (type == 1) { // simple literals, numbers
- _finishNumberToken(tb);
- return;
- }
- if (type <= 3) { // tiny & short ASCII
- _decodeShortAsciiValue(1 + (tb & 0x3F));
- return;
- }
- if (type <= 5) { // tiny & short Unicode
- // short unicode; note, lengths 2 - 65 (off-by-one compared to ASCII)
- _decodeShortUnicodeValue(2 + (tb & 0x3F));
- return;
- }
- if (type == 7) {
- tb &= 0x1F;
- // next 3 bytes define subtype
- switch (tb >> 2) {
- case 0: // long variable length ASCII
- _decodeLongAscii();
- return;
- case 1: // long variable length unicode
- _decodeLongUnicode();
- return;
- case 2: // binary, 7-bit
- _binaryValue = _read7BitBinaryWithLength();
- return;
- case 7: // binary, raw
- _finishRawBinary();
- return;
- }
- }
- // sanity check
- _throwInternal();
- }
-
- protected final void _finishNumberToken(int tb)
- throws IOException, JsonParseException
- {
- tb &= 0x1F;
- int type = (tb >> 2);
- if (type == 1) { // VInt (zigzag) or BigDecimal
- int subtype = tb & 0x03;
- if (subtype == 0) { // (v)int
- _finishInt();
- } else if (subtype == 1) { // (v)long
- _finishLong();
- } else if (subtype == 2) {
- _finishBigInteger();
- } else {
- _throwInternal();
- }
- return;
- }
- if (type == 2) { // other numbers
- switch (tb & 0x03) {
- case 0: // float
- _finishFloat();
- return;
- case 1: // double
- _finishDouble();
- return;
- case 2: // big-decimal
- _finishBigDecimal();
- return;
- }
- }
- _throwInternal();
- }
-
- /*
- /**********************************************************
- /* Internal methods, secondary Number parsing
- /**********************************************************
- */
-
- private final void _finishInt() throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int value = _inputBuffer[_inputPtr++];
- int i;
- if (value < 0) { // 6 bits
- value &= 0x3F;
- } else {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = _inputBuffer[_inputPtr++];
- if (i >= 0) { // 13 bits
- value = (value << 7) + i;
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = _inputBuffer[_inputPtr++];
- if (i >= 0) {
- value = (value << 7) + i;
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = _inputBuffer[_inputPtr++];
- if (i >= 0) {
- value = (value << 7) + i;
- // and then we must get negative
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = _inputBuffer[_inputPtr++];
- if (i >= 0) {
- _reportError("Corrupt input; 32-bit VInt extends beyond 5 data bytes");
- }
- }
- }
- }
- value = (value << 6) + (i & 0x3F);
- }
- _numberInt = SmileUtil.zigzagDecode(value);
- _numTypesValid = NR_INT;
- }
-
- private final void _finishLong()
- throws IOException, JsonParseException
- {
- // Ok, first, will always get 4 full data bytes first; 1 was already passed
- long l = (long) _fourBytesToInt();
- // and loop for the rest
- while (true) {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int value = _inputBuffer[_inputPtr++];
- if (value < 0) {
- l = (l << 6) + (value & 0x3F);
- _numberLong = SmileUtil.zigzagDecode(l);
- _numTypesValid = NR_LONG;
- return;
- }
- l = (l << 7) + value;
- }
- }
-
- private final void _finishBigInteger()
- throws IOException, JsonParseException
- {
- byte[] raw = _read7BitBinaryWithLength();
- _numberBigInt = new BigInteger(raw);
- _numTypesValid = NR_BIGINT;
- }
-
- private final void _finishFloat()
- throws IOException, JsonParseException
- {
- // just need 5 bytes to get int32 first; all are unsigned
- int i = _fourBytesToInt();
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = (i << 7) + _inputBuffer[_inputPtr++];
- float f = Float.intBitsToFloat(i);
- _numberDouble = (double) f;
- _numTypesValid = NR_DOUBLE;
- }
-
- private final void _finishDouble()
- throws IOException, JsonParseException
- {
- // ok; let's take two sets of 4 bytes (each is int)
- long hi = _fourBytesToInt();
- long value = (hi << 28) + (long) _fourBytesToInt();
- // and then remaining 2 bytes
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- value = (value << 7) + _inputBuffer[_inputPtr++];
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- value = (value << 7) + _inputBuffer[_inputPtr++];
- _numberDouble = Double.longBitsToDouble(value);
- _numTypesValid = NR_DOUBLE;
- }
-
- private final int _fourBytesToInt()
- throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int i = _inputBuffer[_inputPtr++]; // first 7 bits
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = (i << 7) + _inputBuffer[_inputPtr++]; // 14 bits
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- i = (i << 7) + _inputBuffer[_inputPtr++]; // 21
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- return (i << 7) + _inputBuffer[_inputPtr++];
- }
-
- private final void _finishBigDecimal()
- throws IOException, JsonParseException
- {
- int scale = SmileUtil.zigzagDecode(_readUnsignedVInt());
- byte[] raw = _read7BitBinaryWithLength();
- _numberBigDecimal = new BigDecimal(new BigInteger(raw), scale);
- _numTypesValid = NR_BIGDECIMAL;
- }
-
- private final int _readUnsignedVInt()
- throws IOException, JsonParseException
- {
- int value = 0;
- while (true) {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int i = _inputBuffer[_inputPtr++];
- if (i < 0) { // last byte
- value = (value << 6) + (i & 0x3F);
- return value;
- }
- value = (value << 7) + i;
- }
- }
-
- private final byte[] _read7BitBinaryWithLength()
- throws IOException, JsonParseException
- {
- int byteLen = _readUnsignedVInt();
- byte[] result = new byte[byteLen];
- int ptr = 0;
- int lastOkPtr = byteLen - 7;
-
- // first, read all 7-by-8 byte chunks
- while (ptr <= lastOkPtr) {
- if ((_inputEnd - _inputPtr) < 8) {
- _loadToHaveAtLeast(8);
- }
- int i1 = (_inputBuffer[_inputPtr++] << 25)
- + (_inputBuffer[_inputPtr++] << 18)
- + (_inputBuffer[_inputPtr++] << 11)
- + (_inputBuffer[_inputPtr++] << 4);
- int x = _inputBuffer[_inputPtr++];
- i1 += x >> 3;
- int i2 = ((x & 0x7) << 21)
- + (_inputBuffer[_inputPtr++] << 14)
- + (_inputBuffer[_inputPtr++] << 7)
- + _inputBuffer[_inputPtr++];
- // Ok: got our 7 bytes, just need to split, copy
- result[ptr++] = (byte)(i1 >> 24);
- result[ptr++] = (byte)(i1 >> 16);
- result[ptr++] = (byte)(i1 >> 8);
- result[ptr++] = (byte)i1;
- result[ptr++] = (byte)(i2 >> 16);
- result[ptr++] = (byte)(i2 >> 8);
- result[ptr++] = (byte)i2;
- }
- // and then leftovers: n+1 bytes to decode n bytes
- int toDecode = (result.length - ptr);
- if (toDecode > 0) {
- if ((_inputEnd - _inputPtr) < (toDecode+1)) {
- _loadToHaveAtLeast(toDecode+1);
- }
- int value = _inputBuffer[_inputPtr++];
- for (int i = 1; i < toDecode; ++i) {
- value = (value << 7) + _inputBuffer[_inputPtr++];
- result[ptr++] = (byte) (value >> (7 - i));
- }
- // last byte is different, has remaining 1 - 6 bits, right-aligned
- value <<= toDecode;
- result[ptr] = (byte) (value + _inputBuffer[_inputPtr++]);
- }
- return result;
- }
-
- /*
- /**********************************************************
- /* Internal methods, secondary String parsing
- /**********************************************************
- */
-
- protected final void _decodeShortAsciiValue(int len)
- throws IOException, JsonParseException
- {
- if ((_inputEnd - _inputPtr) < len) {
- _loadToHaveAtLeast(len);
- }
- // Note: we count on fact that buffer must have at least 'len' (<= 64) empty char slots
- final char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- int outPtr = 0;
- final byte[] inBuf = _inputBuffer;
- int inPtr = _inputPtr;
-
- // loop unrolling SHOULD be faster (as with _decodeShortAsciiName), but somehow
- // is NOT; as per testing, benchmarking... very weird.
- /*
- for (int inEnd = inPtr + len - 3; inPtr < inEnd; ) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- }
- int left = (len & 3);
- if (left > 0) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- if (left > 1) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- if (left > 2) {
- outBuf[outPtr++] = (char) inBuf[inPtr++];
- }
- }
- }
- */
-
- // meaning: regular tight loop is no slower, typically faster here:
- for (final int end = inPtr + len; inPtr < end; ++inPtr) {
- outBuf[outPtr++] = (char) inBuf[inPtr];
- }
-
- _inputPtr = inPtr;
- _textBuffer.setCurrentLength(len);
- }
-
- protected final void _decodeShortUnicodeValue(int len)
- throws IOException, JsonParseException
- {
- if ((_inputEnd - _inputPtr) < len) {
- _loadToHaveAtLeast(len);
- }
- int outPtr = 0;
- char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- int inPtr = _inputPtr;
- _inputPtr += len;
- final int[] codes = SmileConstants.sUtf8UnitLengths;
- final byte[] inputBuf = _inputBuffer;
- for (int end = inPtr + len; inPtr < end; ) {
- int i = inputBuf[inPtr++] & 0xFF;
- int code = codes[i];
- if (code != 0) {
- // trickiest one, need surrogate handling
- switch (code) {
- case 1:
- i = ((i & 0x1F) << 6) | (inputBuf[inPtr++] & 0x3F);
- break;
- case 2:
- i = ((i & 0x0F) << 12)
- | ((inputBuf[inPtr++] & 0x3F) << 6)
- | (inputBuf[inPtr++] & 0x3F);
- break;
- case 3:
- i = ((i & 0x07) << 18)
- | ((inputBuf[inPtr++] & 0x3F) << 12)
- | ((inputBuf[inPtr++] & 0x3F) << 6)
- | (inputBuf[inPtr++] & 0x3F);
- // note: this is the codepoint value; need to split, too
- i -= 0x10000;
- outBuf[outPtr++] = (char) (0xD800 | (i >> 10));
- i = 0xDC00 | (i & 0x3FF);
- break;
- default: // invalid
- _reportError("Invalid byte "+Integer.toHexString(i)+" in short Unicode text block");
- }
- }
- outBuf[outPtr++] = (char) i;
- }
- _textBuffer.setCurrentLength(outPtr);
- }
-
- private final void _decodeLongAscii()
- throws IOException, JsonParseException
- {
- int outPtr = 0;
- char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- main_loop:
- while (true) {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int inPtr = _inputPtr;
- int left = _inputEnd - inPtr;
- if (outPtr >= outBuf.length) {
- outBuf = _textBuffer.finishCurrentSegment();
- outPtr = 0;
- }
- left = Math.min(left, outBuf.length - outPtr);
- do {
- byte b = _inputBuffer[inPtr++];
- if (b == SmileConstants.BYTE_MARKER_END_OF_STRING) {
- _inputPtr = inPtr;
- break main_loop;
- }
- outBuf[outPtr++] = (char) b;
- } while (--left > 0);
- _inputPtr = inPtr;
- }
- _textBuffer.setCurrentLength(outPtr);
- }
-
- private final void _decodeLongUnicode()
- throws IOException, JsonParseException
- {
- int outPtr = 0;
- char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
- final int[] codes = SmileConstants.sUtf8UnitLengths;
- int c;
- final byte[] inputBuffer = _inputBuffer;
-
- main_loop:
- while (true) {
- // First the tight ASCII loop:
- ascii_loop:
- while (true) {
- int ptr = _inputPtr;
- if (ptr >= _inputEnd) {
- loadMoreGuaranteed();
- ptr = _inputPtr;
- }
- if (outPtr >= outBuf.length) {
- outBuf = _textBuffer.finishCurrentSegment();
- outPtr = 0;
- }
- int max = _inputEnd;
- {
- int max2 = ptr + (outBuf.length - outPtr);
- if (max2 < max) {
- max = max2;
- }
- }
- while (ptr < max) {
- c = (int) inputBuffer[ptr++] & 0xFF;
- if (codes[c] != 0) {
- _inputPtr = ptr;
- break ascii_loop;
- }
- outBuf[outPtr++] = (char) c;
- }
- _inputPtr = ptr;
- }
- // Ok: end marker, escape or multi-byte?
- if (c == SmileConstants.INT_MARKER_END_OF_STRING) {
- break main_loop;
- }
-
- switch (codes[c]) {
- case 1: // 2-byte UTF
- c = _decodeUtf8_2(c);
- break;
- case 2: // 3-byte UTF
- if ((_inputEnd - _inputPtr) >= 2) {
- c = _decodeUtf8_3fast(c);
- } else {
- c = _decodeUtf8_3(c);
- }
- break;
- case 4: // 4-byte UTF
- c = _decodeUtf8_4(c);
- // Let's add first part right away:
- outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
- if (outPtr >= outBuf.length) {
- outBuf = _textBuffer.finishCurrentSegment();
- outPtr = 0;
- }
- c = 0xDC00 | (c & 0x3FF);
- // And let the other char output down below
- break;
- default:
- // Is this good enough error message?
- _reportInvalidChar(c);
- }
- // Need more room?
- if (outPtr >= outBuf.length) {
- outBuf = _textBuffer.finishCurrentSegment();
- outPtr = 0;
- }
- // Ok, let's add char to output:
- outBuf[outPtr++] = (char) c;
- }
- _textBuffer.setCurrentLength(outPtr);
- }
-
- private final void _finishRawBinary()
- throws IOException, JsonParseException
- {
- int byteLen = _readUnsignedVInt();
- _binaryValue = new byte[byteLen];
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int ptr = 0;
- while (true) {
- int toAdd = Math.min(byteLen, _inputEnd - _inputPtr);
- System.arraycopy(_inputBuffer, _inputPtr, _binaryValue, ptr, toAdd);
- _inputPtr += toAdd;
- ptr += toAdd;
- byteLen -= toAdd;
- if (byteLen <= 0) {
- return;
- }
- loadMoreGuaranteed();
- }
- }
-
- /*
- /**********************************************************
- /* Internal methods, skipping
- /**********************************************************
- */
-
- /**
- * Method called to skip remainders of an incomplete token, when
- * contents themselves will not be needed any more
- */
- protected void _skipIncomplete() throws IOException, JsonParseException
- {
- _tokenIncomplete = false;
- int tb = _typeByte;
- switch ((tb >> 5) & 0x7) {
- case 1: // simple literals, numbers
- tb &= 0x1F;
- // next 3 bytes define subtype
- switch (tb >> 2) {
- case 1: // VInt (zigzag)
- // easy, just skip until we see sign bit... (should we try to limit damage?)
- switch (tb & 0x3) {
- case 1: // vlong
- _skipBytes(4); // min 5 bytes
- // fall through
- case 0: // vint
- while (true) {
- final int end = _inputEnd;
- final byte[] buf = _inputBuffer;
- while (_inputPtr < end) {
- if (buf[_inputPtr++] < 0) {
- return;
- }
- }
- loadMoreGuaranteed();
- }
- case 2: // big-int
- // just has binary data
- _skip7BitBinary();
- return;
- }
- break;
- case 2: // other numbers
- switch (tb & 0x3) {
- case 0: // float
- _skipBytes(5);
- return;
- case 1: // double
- _skipBytes(10);
- return;
- case 2: // big-decimal
- // first, skip scale
- _readUnsignedVInt();
- // then length-prefixed binary serialization
- _skip7BitBinary();
- return;
- }
- break;
- }
- break;
- case 2: // tiny ASCII
- // fall through
- case 3: // short ASCII
- _skipBytes(1 + (tb & 0x3F));
- return;
- case 4: // tiny unicode
- // fall through
- case 5: // short unicode
- _skipBytes(2 + (tb & 0x3F));
- return;
- case 7:
- tb &= 0x1F;
- // next 3 bytes define subtype
- switch (tb >> 2) {
- case 0: // long variable length ASCII
- case 1: // long variable length unicode
- /* Doesn't matter which one, just need to find the end marker
- * (note: can potentially skip invalid UTF-8 too)
- */
- while (true) {
- final int end = _inputEnd;
- final byte[] buf = _inputBuffer;
- while (_inputPtr < end) {
- if (buf[_inputPtr++] == BYTE_MARKER_END_OF_STRING) {
- return;
- }
- }
- loadMoreGuaranteed();
- }
- // never gets here
- case 2: // binary, 7-bit
- _skip7BitBinary();
- return;
- case 7: // binary, raw
- _skipBytes(_readUnsignedVInt());
- return;
- }
- }
- _throwInternal();
- }
-
- protected void _skipBytes(int len)
- throws IOException, JsonParseException
- {
- while (true) {
- int toAdd = Math.min(len, _inputEnd - _inputPtr);
- _inputPtr += toAdd;
- len -= toAdd;
- if (len <= 0) {
- return;
- }
- loadMoreGuaranteed();
- }
- }
-
- /**
- * Helper method for skipping length-prefixed binary data
- * section
- */
- protected void _skip7BitBinary()
- throws IOException, JsonParseException
- {
- int origBytes = _readUnsignedVInt();
- // Ok; 8 encoded bytes for 7 payload bytes first
- int chunks = origBytes / 7;
- int encBytes = chunks * 8;
- // and for last 0 - 6 bytes, last+1 (except none if no leftovers)
- origBytes -= 7 * chunks;
- if (origBytes > 0) {
- encBytes += 1 + origBytes;
- }
- _skipBytes(encBytes);
- }
-
- /*
- /**********************************************************
- /* Internal methods, UTF8 decoding
- /**********************************************************
- */
-
- private final int _decodeUtf8_2(int c)
- throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- return ((c & 0x1F) << 6) | (d & 0x3F);
- }
-
- private final int _decodeUtf8_3(int c1)
- throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- c1 &= 0x0F;
- int d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- int c = (c1 << 6) | (d & 0x3F);
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- c = (c << 6) | (d & 0x3F);
- return c;
- }
-
- private final int _decodeUtf8_3fast(int c1)
- throws IOException, JsonParseException
- {
- c1 &= 0x0F;
- int d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- int c = (c1 << 6) | (d & 0x3F);
- d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- c = (c << 6) | (d & 0x3F);
- return c;
- }
-
- /**
- * @return Character value <b>minus 0x10000</c>; this so that caller
- * can readily expand it to actual surrogates
- */
- private final int _decodeUtf8_4(int c)
- throws IOException, JsonParseException
- {
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- int d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- c = ((c & 0x07) << 6) | (d & 0x3F);
-
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
- c = (c << 6) | (d & 0x3F);
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
- }
- d = (int) _inputBuffer[_inputPtr++];
- if ((d & 0xC0) != 0x080) {
- _reportInvalidOther(d & 0xFF, _inputPtr);
- }
-
- /* note: won't change it to negative here, since caller
- * already knows it'll need a surrogate
- */
- return ((c << 6) | (d & 0x3F)) - 0x10000;
- }
-
- /*
- /**********************************************************
- /* Internal methods, error reporting
- /**********************************************************
- */
-
- protected void _reportInvalidSharedName(int index) throws IOException
- {
- if (_seenNames == null) {
- _reportError("Encountered shared name reference, even though document header explicitly declared no shared name references are included");
- }
- _reportError("Invalid shared name reference "+index+"; only got "+_seenNameCount+" names in buffer (invalid content)");
- }
-
- protected void _reportInvalidSharedStringValue(int index) throws IOException
- {
- if (_seenStringValues == null) {
- _reportError("Encountered shared text value reference, even though document header did not declared shared text value references may be included");
- }
- _reportError("Invalid shared text value reference "+index+"; only got "+_seenStringValueCount+" names in buffer (invalid content)");
- }
-
- protected void _reportInvalidChar(int c) throws JsonParseException
- {
- // Either invalid WS or illegal UTF-8 start char
- if (c < ' ') {
- _throwInvalidSpace(c);
- }
- _reportInvalidInitial(c);
- }
-
- protected void _reportInvalidInitial(int mask)
- throws JsonParseException
- {
- _reportError("Invalid UTF-8 start byte 0x"+Integer.toHexString(mask));
- }
-
- protected void _reportInvalidOther(int mask)
- throws JsonParseException
- {
- _reportError("Invalid UTF-8 middle byte 0x"+Integer.toHexString(mask));
- }
-
- protected void _reportInvalidOther(int mask, int ptr)
- throws JsonParseException
- {
- _inputPtr = ptr;
- _reportInvalidOther(mask);
- }
-}
-
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParserBootstrapper.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParserBootstrapper.java.svn-base
deleted file mode 100644
index d8bd1b2..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileParserBootstrapper.java.svn-base
+++ /dev/null
@@ -1,274 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import org.codehaus.jackson.JsonLocation;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.format.InputAccessor;
-import org.codehaus.jackson.format.MatchStrength;
-import org.codehaus.jackson.io.IOContext;
-import org.codehaus.jackson.sym.BytesToNameCanonicalizer;
-
-import static org.codehaus.jackson.smile.SmileConstants.*;
-
-/**
- * Simple bootstrapper version used with Smile format parser.
- */
-public class SmileParserBootstrapper
-{
- /*
- /**********************************************************
- /* Configuration
- /**********************************************************
- */
-
- final IOContext _context;
-
- final InputStream _in;
-
- /*
- /**********************************************************
- /* Input buffering
- /**********************************************************
- */
-
- final byte[] _inputBuffer;
-
- private int _inputPtr;
-
- private int _inputEnd;
-
- /**
- * Flag that indicates whether buffer above is to be recycled
- * after being used or not.
- */
- private final boolean _bufferRecyclable;
-
- /*
- /**********************************************************
- /* Input location
- /**********************************************************
- */
-
- /**
- * Current number of input units (bytes or chars) that were processed in
- * previous blocks,
- * before contents of current input buffer.
- *<p>
- * Note: includes possible BOMs, if those were part of the input.
- */
- protected int _inputProcessed;
-
- /*
- /**********************************************************
- /* Data gathered
- /**********************************************************
- */
-
- /*
- /**********************************************************
- /* Life-cycle
- /**********************************************************
- */
-
- public SmileParserBootstrapper(IOContext ctxt, InputStream in)
- {
- _context = ctxt;
- _in = in;
- _inputBuffer = ctxt.allocReadIOBuffer();
- _inputEnd = _inputPtr = 0;
- _inputProcessed = 0;
- _bufferRecyclable = true;
- }
-
- public SmileParserBootstrapper(IOContext ctxt, byte[] inputBuffer, int inputStart, int inputLen)
- {
- _context = ctxt;
- _in = null;
- _inputBuffer = inputBuffer;
- _inputPtr = inputStart;
- _inputEnd = (inputStart + inputLen);
- // Need to offset this for correct location info
- _inputProcessed = -inputStart;
- _bufferRecyclable = false;
- }
-
- public SmileParser constructParser(int generalParserFeatures, int smileFeatures,
- ObjectCodec codec, BytesToNameCanonicalizer rootByteSymbols)
- throws IOException, JsonParseException
- {
- boolean intern = JsonParser.Feature.INTERN_FIELD_NAMES.enabledIn(generalParserFeatures);
- BytesToNameCanonicalizer can = rootByteSymbols.makeChild(true, intern);
- // We just need a single byte, really, to know if it starts with header
- ensureLoaded(1);
- SmileParser p = new SmileParser(_context, generalParserFeatures, smileFeatures,
- codec, can,
- _in, _inputBuffer, _inputPtr, _inputEnd, _bufferRecyclable);
- boolean hadSig = false;
- if (_inputPtr < _inputEnd) { // only false for empty doc
- if (_inputBuffer[_inputPtr] == SmileConstants.HEADER_BYTE_1) {
- // need to ensure it gets properly handled so caller won't see the signature
- hadSig = p.handleSignature(true, true);
- }
- }
- if (!hadSig && (smileFeatures & SmileParser.Feature.REQUIRE_HEADER.getMask()) != 0) {
- // Ok, first, let's see if it looks like plain JSON...
- String msg;
-
- byte firstByte = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr] : 0;
- if (firstByte == '{' || firstByte == '[') {
- msg = "Input does not start with Smile format header (first byte = 0x"
- +Integer.toHexString(firstByte & 0xFF)+") -- rather, it starts with '"+((char) firstByte)
- +"' (plain JSON input?) -- can not parse";
- } else {
- msg = "Input does not start with Smile format header (first byte = 0x"
- +Integer.toHexString(firstByte & 0xFF)+") and parser has REQUIRE_HEADER enabled: can not parse";
- }
- throw new JsonParseException(msg, JsonLocation.NA);
- }
- return p;
- }
-
- /*
- /**********************************************************
- /* Encoding detection for data format auto-detection
- /**********************************************************
- */
-
- /**
- * Helper
- *
- * @since 1.8
- */
- public static MatchStrength hasSmileFormat(InputAccessor acc) throws IOException
- {
- // Ok: ideally we start with the header -- if so, we are golden
- if (!acc.hasMoreBytes()) {
- return MatchStrength.INCONCLUSIVE;
- }
- // We always need at least two bytes to determine, so
- byte b1 = acc.nextByte();
- if (!acc.hasMoreBytes()) {
- return MatchStrength.INCONCLUSIVE;
- }
- byte b2 = acc.nextByte();
-
- // First: do we see 3 "magic bytes"? If so, we are golden
- if (b1 == SmileConstants.HEADER_BYTE_1) { // yeah, looks like marker
- if (b2 != SmileConstants.HEADER_BYTE_2) {
- return MatchStrength.NO_MATCH;
- }
- if (!acc.hasMoreBytes()) {
- return MatchStrength.INCONCLUSIVE;
- }
- return (acc.nextByte() == SmileConstants.HEADER_BYTE_3) ?
- MatchStrength.FULL_MATCH : MatchStrength.NO_MATCH;
- }
- // Otherwise: ideally either Object or Array:
- if (b1 == SmileConstants.TOKEN_LITERAL_START_OBJECT) {
- /* Object is bit easier, because now we need to get new name; i.e. can
- * rule out name back-refs
- */
- if (b2 == SmileConstants.TOKEN_KEY_LONG_STRING) {
- return MatchStrength.SOLID_MATCH;
- }
- int ch = (int) b2 & 0xFF;
- if (ch >= 0x80 && ch < 0xF8) {
- return MatchStrength.SOLID_MATCH;
- }
- return MatchStrength.NO_MATCH;
- }
- // Array bit trickier
- if (b1 == SmileConstants.TOKEN_LITERAL_START_ARRAY) {
- if (!acc.hasMoreBytes()) {
- return MatchStrength.INCONCLUSIVE;
- }
- /* For arrays, we will actually accept much wider range of values (including
- * things that could otherwise collide)
- */
- if (likelySmileValue(b2) || possibleSmileValue(b2, true)) {
- return MatchStrength.SOLID_MATCH;
- }
- return MatchStrength.NO_MATCH;
- }
- // Scalar values are pretty weak, albeit possible; require more certain match, consider it weak:
- if (likelySmileValue(b1) || possibleSmileValue(b2, false)) {
- return MatchStrength.SOLID_MATCH;
- }
- return MatchStrength.NO_MATCH;
- }
-
- private static boolean likelySmileValue(byte b)
- {
- int ch = (int) b & 0xFF;
- if (ch >= 0xE0) { // good range for known values
- switch (ch) {
- case TOKEN_MISC_LONG_TEXT_ASCII: // 0xE0
- case TOKEN_MISC_LONG_TEXT_UNICODE: // 0xE4
- case TOKEN_MISC_BINARY_7BIT: // 0xE8
- case TOKEN_LITERAL_START_ARRAY: // 0xF8
- case TOKEN_LITERAL_START_OBJECT: // 0xFA
- return true;
- }
- // Others will not work (end object/array; reserved; shared strings)
- return false;
- }
- // ASCII ctrl char range is pretty good match too
- if (ch >= 0x80 && ch <= 0x9F) {
- return true;
- }
- return false;
- }
-
- /**
- * @param lenient Whether to consider more speculative matches or not
- * (typically true when there is context like start-array)
- */
- private static boolean possibleSmileValue(byte b, boolean lenient)
- {
- int ch = (int) b & 0xFF;
- // note: we know that likely matches have been handled already, so...
- if (ch >= 0x80) {
- return (ch <= 0xE0);
- }
- if (lenient) {
- if (ch >= 0x40) { // tiny/short ASCII
- return true;
- }
- if (ch >- 0x20) { // various constants
- return (ch < 0x2C); // many reserved bytes that can't be seen
- }
- }
- return false;
- }
-
- /*
- /**********************************************************
- /* Internal methods, raw input access
- /**********************************************************
- */
-
- protected boolean ensureLoaded(int minimum)
- throws IOException
- {
- if (_in == null) { // block source; nothing more to load
- return false;
- }
-
- /* Let's assume here buffer has enough room -- this will always
- * be true for the limited used this method gets
- */
- int gotten = (_inputEnd - _inputPtr);
- while (gotten < minimum) {
- int count = _in.read(_inputBuffer, _inputEnd, _inputBuffer.length - _inputEnd);
- if (count < 1) {
- return false;
- }
- _inputEnd += count;
- gotten += count;
- }
- return true;
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileUtil.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileUtil.java.svn-base
deleted file mode 100644
index 9dbe0ce..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileUtil.java.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.codehaus.jackson.smile;
-
-/**
- * Class for miscellaneous helper methods.
- */
-public class SmileUtil
-{
- public static int zigzagEncode(int input) {
- // Canonical version:
- //return (input << 1) ^ (input >> 31);
- // but this is even better
- if (input < 0) {
- return (input << 1) ^ -1;
- }
- return (input << 1);
- }
-
- public static int zigzagDecode(int encoded) {
- // canonical:
- //return (encoded >>> 1) ^ (-(encoded & 1));
- if ((encoded & 1) == 0) { // positive
- return (encoded >>> 1);
- }
- // negative
- return (encoded >>> 1) ^ -1;
- }
-
- public static long zigzagEncode(long input) {
- // Canonical version
- //return (input << 1) ^ (input >> 63);
- if (input < 0L) {
- return (input << 1) ^ -1L;
- }
- return (input << 1);
- }
-
- public static long zigzagDecode(long encoded) {
- // canonical:
- //return (encoded >>> 1) ^ (-(encoded & 1));
- if ((encoded & 1) == 0) { // positive
- return (encoded >>> 1);
- }
- // negative
- return (encoded >>> 1) ^ -1L;
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/Tool.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/Tool.java.svn-base
deleted file mode 100644
index e30b628..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/Tool.java.svn-base
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.smile.SmileFactory;
-
-/**
- * Simple command-line utility that can be used to encode JSON as Smile, or
- * decode JSON from Smile: direction is indicated by single command-line
- * option of either "-e" (encode) or "-d" (decode).
- *
- * @author tatu
- *
- * @since 1.6.2
- */
-public class Tool
-{
- public final static String SUFFIX = ".lzf";
-
- public final JsonFactory jsonFactory;
- public final SmileFactory smileFactory;
-
- public Tool()
- {
- jsonFactory = new JsonFactory();
- smileFactory = new SmileFactory();
- // check all shared refs (-> small size); add header, not trailing marker; do not use raw binary
- smileFactory.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, true);
- smileFactory.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
- smileFactory.configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, true);
- smileFactory.configure(SmileGenerator.Feature.WRITE_HEADER, true);
- smileFactory.configure(SmileGenerator.Feature.WRITE_END_MARKER, false);
- // also: do not require header
- smileFactory.configure(SmileParser.Feature.REQUIRE_HEADER, false);
- }
-
- private void process(String[] args) throws IOException
- {
- String oper = null;
- String filename = null;
-
- if (args.length == 2) {
- oper = args[0];
- filename = args[1];
- } else if (args.length == 1) {
- oper = args[0];
- } else {
- showUsage();
- }
-
- boolean encode = "-e".equals(oper);
- if (encode) {
- encode(inputStream(filename));
- } else if ("-d".equals(oper)) {
- decode(inputStream(filename));
- } else if ("-v".equals(oper)) {
- // need to read twice (encode, verify/compare)
- verify(inputStream(filename), inputStream(filename));
- } else {
- showUsage();
- }
- }
-
- private InputStream inputStream(String filename) throws IOException
- {
- // if no argument given, read from stdin
- if (filename == null) {
- return System.in;
- }
- File src = new File(filename);
- if (!src.exists()) {
- System.err.println("File '"+filename+"' does not exist.");
- System.exit(1);
- }
- return new FileInputStream(src);
- }
-
- private void decode(InputStream in) throws IOException
- {
- JsonParser jp = smileFactory.createJsonParser(in);
- JsonGenerator jg = jsonFactory.createJsonGenerator(System.out, JsonEncoding.UTF8);
-
- while (true) {
- /* Just one trick: since Smile can have segments (multiple 'documents' in output
- * stream), we should not stop at first end marker, only bail out if two are seen
- */
- if (jp.nextToken() == null) {
- if (jp.nextToken() == null) {
- break;
- }
- }
- jg.copyCurrentEvent(jp);
- }
- jp.close();
- jg.close();
- }
-
- private void encode(InputStream in) throws IOException
- {
- JsonParser jp = jsonFactory.createJsonParser(in);
- JsonGenerator jg = smileFactory.createJsonGenerator(System.out, JsonEncoding.UTF8);
- while ((jp.nextToken()) != null) {
- jg.copyCurrentEvent(jp);
- }
- jp.close();
- jg.close();
- }
-
- private void verify(InputStream in, InputStream in2) throws IOException
- {
- JsonParser jp = jsonFactory.createJsonParser(in);
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(4000);
- JsonGenerator jg = smileFactory.createJsonGenerator(bytes, JsonEncoding.UTF8);
-
- // First, read, encode in memory buffer
- while ((jp.nextToken()) != null) {
- jg.copyCurrentEvent(jp);
- }
- jp.close();
- jg.close();
-
- // and then re-read both, verify
- jp = jsonFactory.createJsonParser(in2);
- byte[] smile = bytes.toByteArray();
- JsonParser jp2 = smileFactory.createJsonParser(smile);
-
- JsonToken t;
- int count = 0;
- while ((t = jp.nextToken()) != null) {
- JsonToken t2 = jp2.nextToken();
- ++count;
- if (t != t2) {
- throw new IOException("Input and encoded differ, token #"+count+"; expected "+t+", got "+t2);
- }
- // also, need to have same texts...
- String text1 = jp.getText();
- String text2 = jp2.getText();
- if (!text1.equals(text2)) {
- throw new IOException("Input and encoded differ, token #"+count+"; expected text '"+text1+"', got '"+text2+"'");
- }
- }
-
- System.out.println("OK: verified "+count+" tokens (from "+smile.length+" bytes of Smile encoded data), input and encoded contents are identical");
- }
-
- protected void showUsage()
- {
- System.err.println("Usage: java "+getClass().getName()+" -e/-d [file]");
- System.err.println(" (if no file given, reads from stdin -- always writes to stdout)");
- System.err.println(" -d: decode Smile encoded input as JSON");
- System.err.println(" -e: encode JSON (text) input as Smile");
- System.err.println(" -v: encode JSON (text) input as Smile; read back, verify, do not write out");
- System.exit(1);
- }
-
- public static void main(String[] args) throws IOException {
- new Tool().process(args);
- }
-
-}
diff --git a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/package-info.java.svn-base b/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/package-info.java.svn-base
deleted file mode 100644
index 82d4a5e..0000000
--- a/src/main/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/package-info.java.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Package that contains experimental implementation of
- * "Binary-Encoded JSON-Like" data format handlers (parser,
- * generator, factory produce both, supporting constants).
- *<p>
- * See <a href="http://wiki.fasterxml.com/SmileFormat">Smile format specification</a> for more details.
- *
- * @since 1.6
- */
-package org.codehaus.jackson.smile;
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops
deleted file mode 100644
index 87768a2..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/all-wcprops
+++ /dev/null
@@ -1,107 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 64
-/jackson/!svn/ver/1914/trunk/src/test/org/codehaus/jackson/smile
-END
-TestGeneratorWithRawUtf8.java
-K 25
-svn:wc:ra_dav:version-url
-V 94
-/jackson/!svn/ver/1533/trunk/src/test/org/codehaus/jackson/smile/TestGeneratorWithRawUtf8.java
-END
-TestSmileDocBoundary.java
-K 25
-svn:wc:ra_dav:version-url
-V 90
-/jackson/!svn/ver/1039/trunk/src/test/org/codehaus/jackson/smile/TestSmileDocBoundary.java
-END
-SmileTestBase.java
-K 25
-svn:wc:ra_dav:version-url
-V 83
-/jackson/!svn/ver/1912/trunk/src/test/org/codehaus/jackson/smile/SmileTestBase.java
-END
-TestSmileUtil.java
-K 25
-svn:wc:ra_dav:version-url
-V 82
-/jackson/!svn/ver/995/trunk/src/test/org/codehaus/jackson/smile/TestSmileUtil.java
-END
-TestSmileDetection.java
-K 25
-svn:wc:ra_dav:version-url
-V 88
-/jackson/!svn/ver/1558/trunk/src/test/org/codehaus/jackson/smile/TestSmileDetection.java
-END
-TestSmileFeatures.java
-K 25
-svn:wc:ra_dav:version-url
-V 87
-/jackson/!svn/ver/1419/trunk/src/test/org/codehaus/jackson/smile/TestSmileFeatures.java
-END
-TestSmileGeneratorLongStrings.java
-K 25
-svn:wc:ra_dav:version-url
-V 99
-/jackson/!svn/ver/1295/trunk/src/test/org/codehaus/jackson/smile/TestSmileGeneratorLongStrings.java
-END
-TestSmileGeneratorNumbers.java
-K 25
-svn:wc:ra_dav:version-url
-V 95
-/jackson/!svn/ver/1039/trunk/src/test/org/codehaus/jackson/smile/TestSmileGeneratorNumbers.java
-END
-TestSmileParserLocation.java
-K 25
-svn:wc:ra_dav:version-url
-V 93
-/jackson/!svn/ver/1874/trunk/src/test/org/codehaus/jackson/smile/TestSmileParserLocation.java
-END
-TestSmileGenerator.java
-K 25
-svn:wc:ra_dav:version-url
-V 88
-/jackson/!svn/ver/1109/trunk/src/test/org/codehaus/jackson/smile/TestSmileGenerator.java
-END
-TestSmileGeneratorBufferRecycle.java
-K 25
-svn:wc:ra_dav:version-url
-V 101
-/jackson/!svn/ver/1600/trunk/src/test/org/codehaus/jackson/smile/TestSmileGeneratorBufferRecycle.java
-END
-TestSmileParserSymbolHandling.java
-K 25
-svn:wc:ra_dav:version-url
-V 99
-/jackson/!svn/ver/1804/trunk/src/test/org/codehaus/jackson/smile/TestSmileParserSymbolHandling.java
-END
-TestSmileParserNumbers.java
-K 25
-svn:wc:ra_dav:version-url
-V 92
-/jackson/!svn/ver/1039/trunk/src/test/org/codehaus/jackson/smile/TestSmileParserNumbers.java
-END
-TestGeneratorWithSerializedString.java
-K 25
-svn:wc:ra_dav:version-url
-V 103
-/jackson/!svn/ver/1514/trunk/src/test/org/codehaus/jackson/smile/TestGeneratorWithSerializedString.java
-END
-TestSmileParser.java
-K 25
-svn:wc:ra_dav:version-url
-V 85
-/jackson/!svn/ver/1914/trunk/src/test/org/codehaus/jackson/smile/TestSmileParser.java
-END
-TestSmileGeneratorSymbols.java
-K 25
-svn:wc:ra_dav:version-url
-V 95
-/jackson/!svn/ver/1688/trunk/src/test/org/codehaus/jackson/smile/TestSmileGeneratorSymbols.java
-END
-TestSmileParserBinary.java
-K 25
-svn:wc:ra_dav:version-url
-V 91
-/jackson/!svn/ver/1155/trunk/src/test/org/codehaus/jackson/smile/TestSmileParserBinary.java
-END
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/entries b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/entries
deleted file mode 100644
index 910c1b9..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/entries
+++ /dev/null
@@ -1,606 +0,0 @@
-10
-
-dir
-2123
-https://svn.codehaus.org/jackson/trunk/src/test/org/codehaus/jackson/smile
-https://svn.codehaus.org/jackson
-
-
-
-2011-07-28T04:49:59.578667Z
-1914
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-cc757fca-8a48-0410-80b4-e22f7f27f4c6
-
-TestSmileDocBoundary.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-7ca4846f8c0224f0655ae4e96530b951
-2010-07-30T04:31:24.730655Z
-1039
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3365
-
-TestGeneratorWithRawUtf8.java
-file
-
-
-
-
-2011-02-12T03:25:25.000000Z
-27aa51d69e0958b3e68a365e37c61a3e
-2011-02-11T20:12:25.870021Z
-1533
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7648
-
-SmileTestBase.java
-file
-
-
-
-
-2011-07-28T03:44:30.000000Z
-812e68c409f8010f84513429d559f25a
-2011-07-27T20:02:03.879040Z
-1912
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2541
-
-TestSmileUtil.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-c0229a216ccb1fbb115d607e622dfb37
-2010-07-20T19:35:47.171895Z
-995
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1725
-
-TestSmileFeatures.java
-file
-
-
-
-
-2010-12-24T07:45:45.000000Z
-d7406a282daff2de887fcb2ea3a87026
-2010-12-23T22:45:27.409571Z
-1419
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1077
-
-TestSmileDetection.java
-file
-
-
-
-
-2011-02-17T06:50:51.000000Z
-a36bd46cc1232938ea31a31fc11972d8
-2011-02-17T06:51:16.269013Z
-1558
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6299
-
-TestSmileGeneratorLongStrings.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-effc11f38dc34c716dcc541005e4e8df
-2010-12-03T23:50:08.895870Z
-1295
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3026
-
-TestSmileGeneratorNumbers.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-d6145fba10b04bc48770285c7becc7f6
-2010-07-30T04:31:24.730655Z
-1039
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4260
-
-TestSmileParserLocation.java
-file
-
-
-
-
-2011-07-21T02:12:37.000000Z
-09a0de08b49c472fb1ab20b78d3104b2
-2011-07-19T23:27:22.841507Z
-1874
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2362
-
-TestSmileGenerator.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-275896591b02ba4dad1ef836fcdfce0d
-2010-08-28T06:21:23.853200Z
-1109
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6946
-
-TestSmileGeneratorBufferRecycle.java
-file
-
-
-
-
-2011-03-04T00:13:18.000000Z
-f1db3fdb471526c8852c1fcd82c0394c
-2011-03-03T19:05:29.785553Z
-1600
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2129
-
-TestSmileParserSymbolHandling.java
-file
-
-
-
-
-2011-06-25T03:52:13.000000Z
-886d71f7052fae4f016692a7467c8857
-2011-06-25T03:55:50.390480Z
-1804
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-21412
-
-TestSmileParserNumbers.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-390c1cbfd132d0a1a9e77a633c84c186
-2010-07-30T04:31:24.730655Z
-1039
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11622
-
-TestGeneratorWithSerializedString.java
-file
-
-
-
-
-2011-02-02T02:22:29.000000Z
-d24cc1cd5560ca1788cee09bdc8b9123
-2011-01-31T04:16:42.975882Z
-1514
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3119
-
-TestSmileParser.java
-file
-
-
-
-
-2011-07-28T04:33:47.000000Z
-0fcb0cdbcbd7519c991f308635fe150e
-2011-07-28T04:49:59.578667Z
-1914
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-15496
-
-TestSmileGeneratorSymbols.java
-file
-
-
-
-
-2011-04-07T02:52:44.000000Z
-17c9394045c80dd6a6fb33885aebd4ed
-2011-04-06T21:18:57.939254Z
-1688
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4923
-
-TestSmileParserBinary.java
-file
-
-
-
-
-2010-12-23T06:08:37.000000Z
-217f1899934e76a14a8bb92585082b8f
-2010-09-30T17:33:38.628421Z
-1155
-cowtowncoder
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5809
-
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileTestBase.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileTestBase.java.svn-base
deleted file mode 100644
index fdb4e84..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/SmileTestBase.java.svn-base
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.codehaus.jackson.*;
-
-abstract class SmileTestBase
- extends main.BaseTest
-{
- protected SmileParser _smileParser(byte[] input) throws IOException {
- return _smileParser(input, false);
- }
-
- protected SmileParser _smileParser(byte[] input, boolean requireHeader) throws IOException
- {
- SmileFactory f = smileFactory(requireHeader, false, false);
- return _smileParser(f, input);
- }
-
- protected SmileParser _smileParser(SmileFactory f, byte[] input)
- throws IOException
- {
- return f.createJsonParser(input);
- }
-
- protected SmileFactory smileFactory(boolean requireHeader,
- boolean writeHeader, boolean writeEndMarker)
- throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileParser.Feature.REQUIRE_HEADER, requireHeader);
- f.configure(SmileGenerator.Feature.WRITE_HEADER, writeHeader);
- f.configure(SmileGenerator.Feature.WRITE_END_MARKER, writeEndMarker);
- return f;
- }
-
- protected byte[] _smileDoc(String json) throws IOException
- {
- return _smileDoc(json, true);
- }
-
- protected byte[] _smileDoc(String json, boolean writeHeader) throws IOException
- {
- return _smileDoc(new SmileFactory(), json, writeHeader);
- }
-
- protected byte[] _smileDoc(SmileFactory smileFactory, String json, boolean writeHeader) throws IOException
- {
- JsonFactory jf = new JsonFactory();
- JsonParser jp = jf.createJsonParser(json);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- JsonGenerator jg = smileGenerator(out, writeHeader);
-
- while (jp.nextToken() != null) {
- jg.copyCurrentEvent(jp);
- }
- jp.close();
- jg.close();
- return out.toByteArray();
- }
-
- protected SmileGenerator smileGenerator(ByteArrayOutputStream result, boolean addHeader)
- throws IOException
- {
- return smileGenerator(new SmileFactory(), result, addHeader);
- }
-
- protected SmileGenerator smileGenerator(SmileFactory f,
- ByteArrayOutputStream result, boolean addHeader)
- throws IOException
- {
- f.configure(SmileGenerator.Feature.WRITE_HEADER, addHeader);
- return f.createJsonGenerator(result, null);
- }
-
- protected void _verifyBytes(byte[] actBytes, byte... expBytes)
- {
- Assert.assertArrayEquals(expBytes, actBytes);
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithRawUtf8.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithRawUtf8.java.svn-base
deleted file mode 100644
index 2e77853..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithRawUtf8.java.svn-base
+++ /dev/null
@@ -1,222 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import org.codehaus.jackson.*;
-
-/**
- * Test similar to {@link org.codehaus.jackson.main.TestRawStringWriting},
- * to verify handling of "raw String value" write methods that by-pass
- * most encoding steps, for potential higher output speed (in cases where
- * input naturally comes as UTF-8 encoded byte arrays).
- *
- * @since 1.7
- */
-public class TestGeneratorWithRawUtf8 extends SmileTestBase
-{
- public void testUtf8RawStrings() throws Exception
- {
- // Let's create set of Strings to output; no ctrl chars as we do raw
- List<byte[]> strings = generateStrings(new Random(28), 750000, false);
- ByteArrayOutputStream out = new ByteArrayOutputStream(16000);
- SmileFactory jf = new SmileFactory();
- JsonGenerator jgen = jf.createJsonGenerator(out, JsonEncoding.UTF8);
- jgen.writeStartArray();
- for (byte[] str : strings) {
- jgen.writeRawUTF8String(str, 0, str.length);
- }
- jgen.writeEndArray();
- jgen.close();
- byte[] json = out.toByteArray();
-
- // Ok: let's verify that stuff was written out ok
- JsonParser jp = jf.createJsonParser(json);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- for (byte[] inputBytes : strings) {
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- String string = jp.getText();
- byte[] outputBytes = string.getBytes("UTF-8");
- assertEquals(inputBytes.length, outputBytes.length);
- assertArrayEquals(inputBytes, outputBytes);
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- }
-
- /**
- * Unit test for "JsonGenerator.writeUTF8String()", which needs
- * to handle escaping properly
- */
- public void testUtf8StringsWithEscaping() throws Exception
- {
- // Let's create set of Strings to output; do include control chars too:
- List<byte[]> strings = generateStrings(new Random(28), 720000, true);
- ByteArrayOutputStream out = new ByteArrayOutputStream(16000);
- SmileFactory jf = new SmileFactory();
- JsonGenerator jgen = jf.createJsonGenerator(out, JsonEncoding.UTF8);
- jgen.writeStartArray();
- for (byte[] str : strings) {
- jgen.writeUTF8String(str, 0, str.length);
- }
- jgen.writeEndArray();
- jgen.close();
- byte[] json = out.toByteArray();
-
- // Ok: let's verify that stuff was written out ok
- JsonParser jp = jf.createJsonParser(json);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- for (byte[] inputBytes : strings) {
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- String string = jp.getText();
- byte[] outputBytes = string.getBytes("UTF-8");
- assertEquals(inputBytes.length, outputBytes.length);
- assertArrayEquals(inputBytes, outputBytes);
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- }
-
- /**
- * Test to point out an issue with "raw" UTF-8 encoding
- *
- * @author David Yu
- */
- public void testIssue492() throws Exception
- {
- doTestIssue492(false);
- doTestIssue492(true);
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private void doTestIssue492(boolean asUtf8String) throws Exception
- {
- SmileFactory factory = new SmileFactory();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator generator = factory.createJsonGenerator(out);
-
- generator.writeStartObject();
-
- generator.writeFieldName("name");
-
- if(asUtf8String)
- {
- byte[] text = "PojoFoo".getBytes("ASCII");
- generator.writeUTF8String(text, 0, text.length);
- }
- else
- {
- generator.writeString("PojoFoo");
- }
-
- generator.writeFieldName("collection");
-
- generator.writeStartObject();
-
- generator.writeFieldName("v");
-
- generator.writeStartArray();
-
- if(asUtf8String)
- {
- byte[] text = "1".getBytes("ASCII");
- generator.writeUTF8String(text, 0, text.length);
- }
- else
- {
- generator.writeString("1");
- }
-
- generator.writeEndArray();
-
- generator.writeEndObject();
-
- generator.writeEndObject();
-
- generator.close();
-
- byte[] data = out.toByteArray();
-
- ByteArrayInputStream in = new ByteArrayInputStream(data);
- SmileParser parser = factory.createJsonParser(in);
-
- assertToken(parser.nextToken(), JsonToken.START_OBJECT);
-
- assertToken(parser.nextToken(), JsonToken.FIELD_NAME);
- assertEquals(parser.getCurrentName(), "name");
- assertToken(parser.nextToken(), JsonToken.VALUE_STRING);
- assertEquals(parser.getText(), "PojoFoo");
-
- assertToken(parser.nextToken(), JsonToken.FIELD_NAME);
- assertEquals(parser.getCurrentName(), "collection");
- assertToken(parser.nextToken(), JsonToken.START_OBJECT);
-
- assertToken(parser.nextToken(), JsonToken.FIELD_NAME);
- assertEquals("Should have property with name 'v'", parser.getCurrentName(), "v");
- assertToken(parser.nextToken(), JsonToken.START_ARRAY);
-
- assertToken(parser.nextToken(), JsonToken.VALUE_STRING);
- assertEquals("Should get String value '1'", parser.getText(), "1");
-
- assertToken(parser.nextToken(), JsonToken.END_ARRAY);
- assertToken(parser.nextToken(), JsonToken.END_OBJECT);
-
-
- assertToken(parser.nextToken(), JsonToken.END_OBJECT);
- parser.close();
- }
-
- private List<byte[]> generateStrings(Random rnd, int totalLength, boolean includeCtrlChars)
- throws IOException
- {
- ArrayList<byte[]> strings = new ArrayList<byte[]>();
- do {
- int len = 2;
- int bits = rnd.nextInt(14);
- while (--bits >= 0) {
- len += len;
- }
- len = 1 + ((len + len) / 3);
- String str = generateString(rnd, len, includeCtrlChars);
- byte[] bytes = str.getBytes("UTF-8");
- strings.add(bytes);
- totalLength -= bytes.length;
- } while (totalLength > 0);
- return strings;
- }
-
- private String generateString(Random rnd, int length, boolean includeCtrlChars)
- {
- StringBuilder sb = new StringBuilder(length);
- do {
- int i;
- switch (rnd.nextInt(3)) {
- case 0: // 3 byte one
- i = 2048 + rnd.nextInt(16383);
- break;
- case 1: // 2 byte
- i = 128 + rnd.nextInt(1024);
- break;
- default: // ASCII
- i = rnd.nextInt(192);
- if (!includeCtrlChars) {
- i += 32;
- // but also need to avoid backslash, double-quote
- if (i == '\\' || i == '"') {
- i = '@'; // just arbitrary choice
- }
- }
- }
- sb.append((char) i);
- } while (sb.length() < length);
- return sb.toString();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithSerializedString.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithSerializedString.java.svn-base
deleted file mode 100644
index 4c85e67..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestGeneratorWithSerializedString.java.svn-base
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.ByteArrayOutputStream;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.io.SerializedString;
-
-public class TestGeneratorWithSerializedString extends SmileTestBase
-{
- final static String NAME_WITH_QUOTES = "\"name\"";
- final static String NAME_WITH_LATIN1 = "P\u00f6ll\u00f6";
-
- private final SerializedString quotedName = new SerializedString(NAME_WITH_QUOTES);
- private final SerializedString latin1Name = new SerializedString(NAME_WITH_LATIN1);
-
- public void testSimple() throws Exception
- {
- SmileFactory sf = new SmileFactory();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- JsonGenerator jgen = sf.createJsonGenerator(out);
- _writeSimple(jgen);
- jgen.close();
- byte[] smileB = out.toByteArray();
- _verifySimple(sf.createJsonParser(smileB));
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private void _writeSimple(JsonGenerator jgen) throws Exception
- {
- // Let's just write array of 2 objects
- jgen.writeStartArray();
-
- jgen.writeStartObject();
- jgen.writeFieldName(quotedName);
- jgen.writeString("a");
- jgen.writeFieldName(latin1Name);
- jgen.writeString("b");
- jgen.writeEndObject();
-
- jgen.writeStartObject();
- jgen.writeFieldName(latin1Name);
- jgen.writeString("c");
- jgen.writeFieldName(quotedName);
- jgen.writeString("d");
- jgen.writeEndObject();
-
- jgen.writeEndArray();
- }
-
- private void _verifySimple(JsonParser jp) throws Exception
- {
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
-
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(NAME_WITH_QUOTES, jp.getText());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("a", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(NAME_WITH_LATIN1, jp.getText());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("b", jp.getText());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
-
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(NAME_WITH_LATIN1, jp.getText());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("c", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(NAME_WITH_QUOTES, jp.getText());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("d", jp.getText());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
-
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- assertNull(jp.nextToken());
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDetection.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDetection.java.svn-base
deleted file mode 100644
index 7da8d7b..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDetection.java.svn-base
+++ /dev/null
@@ -1,148 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.format.DataFormatDetector;
-import org.codehaus.jackson.format.DataFormatMatcher;
-import org.codehaus.jackson.format.MatchStrength;
-
-public class TestSmileDetection extends SmileTestBase
-{
-
- public void testSimpleObjectWithHeader() throws IOException
- {
- SmileFactory f = new SmileFactory();
- DataFormatDetector detector = new DataFormatDetector(f);
- byte[] doc = _smileDoc("{\"a\":3}", true);
- DataFormatMatcher matcher = detector.findFormat(doc);
- // should have match
- assertTrue(matcher.hasMatch());
- assertEquals("Smile", matcher.getMatchedFormatName());
- assertSame(f, matcher.getMatch());
- // with header, should be full match
- assertEquals(MatchStrength.FULL_MATCH, matcher.getMatchStrength());
- // and so:
- JsonParser jp = matcher.createParserWithMatch();
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("a", jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(3, jp.getIntValue());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- assertNull(jp.nextToken());
- jp.close();
- }
-
- public void testSimpleObjectWithoutHeader() throws IOException
- {
- SmileFactory f = new SmileFactory();
- DataFormatDetector detector = new DataFormatDetector(f);
- f.disable(SmileParser.Feature.REQUIRE_HEADER);
- byte[] doc = _smileDoc("{\"abc\":false}", false);
- DataFormatMatcher matcher = detector.findFormat(doc);
- assertTrue(matcher.hasMatch());
- assertEquals("Smile", matcher.getMatchedFormatName());
- assertSame(f, matcher.getMatch());
- assertEquals(MatchStrength.SOLID_MATCH, matcher.getMatchStrength());
- JsonParser jp = matcher.createParserWithMatch();
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("abc", jp.getCurrentName());
- assertToken(JsonToken.VALUE_FALSE, jp.nextToken());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- assertNull(jp.nextToken());
- jp.close();
- }
-
- public void testSimpleArrayWithHeader() throws IOException
- {
- SmileFactory f = new SmileFactory();
- DataFormatDetector detector = new DataFormatDetector(f);
- byte[] doc = _smileDoc("[ true, 7 ]", true);
- DataFormatMatcher matcher = detector.findFormat(doc);
- // should have match
- assertTrue(matcher.hasMatch());
- assertEquals("Smile", matcher.getMatchedFormatName());
- assertSame(f, matcher.getMatch());
- // with header, should be full match
- assertEquals(MatchStrength.FULL_MATCH, matcher.getMatchStrength());
- JsonParser jp = matcher.createParserWithMatch();
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(7, jp.getIntValue());
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- assertNull(jp.nextToken());
- jp.close();
- }
-
- public void testSimpleArrayWithoutHeader() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.disable(SmileParser.Feature.REQUIRE_HEADER);
- DataFormatDetector detector = new DataFormatDetector(f);
- byte[] doc = _smileDoc("[ -13 ]", false);
- DataFormatMatcher matcher = detector.findFormat(doc);
- assertTrue(matcher.hasMatch());
- assertEquals("Smile", matcher.getMatchedFormatName());
- assertSame(f, matcher.getMatch());
- assertEquals(MatchStrength.SOLID_MATCH, matcher.getMatchStrength());
- JsonParser jp = matcher.createParserWithMatch();
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- assertNull(jp.nextToken());
- jp.close();
- }
-
- /*
- /**********************************************************
- /* Simple negative tests
- /**********************************************************
- */
-
- /*
- * Also let's ensure no match is found if data doesn't support it...
- * Let's use 0xFD since it can not be included (except in raw binary;
- * use of which requires header to be present)
- */
- public void testSimpleInvalid() throws Exception
- {
- DataFormatDetector detector = new DataFormatDetector(new SmileFactory());
- byte FD = (byte) 0xFD;
- byte[] DOC = new byte[] { FD, FD, FD, FD };
- DataFormatMatcher matcher = detector.findFormat(new ByteArrayInputStream(DOC));
- assertFalse(matcher.hasMatch());
- assertEquals(MatchStrength.INCONCLUSIVE, matcher.getMatchStrength());
- assertNull(matcher.createParserWithMatch());
- }
-
- /*
- /**********************************************************
- /* Fallback tests to ensure Smile is found even against JSON
- /**********************************************************
- */
-
- public void testSmileVsJson() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.disable(SmileParser.Feature.REQUIRE_HEADER);
- DataFormatDetector detector = new DataFormatDetector(new JsonFactory(), f);
- // to make it bit trickier, leave out header
- byte[] doc = _smileDoc("[ \"abc\" ]", false);
- DataFormatMatcher matcher = detector.findFormat(doc);
- assertTrue(matcher.hasMatch());
- assertEquals("Smile", matcher.getMatchedFormatName());
- assertSame(f, matcher.getMatch());
- // without header, just solid
- assertEquals(MatchStrength.SOLID_MATCH, matcher.getMatchStrength());
- JsonParser jp = matcher.createParserWithMatch();
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- assertNull(jp.nextToken());
- jp.close();
- }
-
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDocBoundary.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDocBoundary.java.svn-base
deleted file mode 100644
index 293fb98..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileDocBoundary.java.svn-base
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import org.codehaus.jackson.JsonToken;
-
-/**
- * Unit tests for verifying that multiple document output and document
- * boundaries and/or header mark handling works as expected
- */
-public class TestSmileDocBoundary
- extends SmileTestBase
-{
- public void testNoHeadersNoEndMarker() throws Exception
- {
- _verifyMultiDoc(false, false);
- }
-
- public void testHeadersNoEndMarker() throws Exception
- {
- _verifyMultiDoc(true, false);
- }
-
- public void testEndMarkerNoHeader() throws Exception
- {
- _verifyMultiDoc(false, true);
- }
-
- public void testHeaderAndEndMarker() throws Exception
- {
- _verifyMultiDoc(true, true);
- }
-
- public void testExtraHeader() throws Exception
- {
- // also; sprinkling headers can be used to segment document
- for (boolean addHeader : new boolean[] { false, true }) {
- SmileFactory f = smileFactory(false, false, false);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator jg = f.createJsonGenerator(out);
- jg.writeNumber(1);
- if (addHeader) jg.writeHeader();
- jg.writeNumber(2);
- if (addHeader) jg.writeHeader();
- jg.writeNumber(3);
- jg.close();
-
- SmileParser jp = f.createJsonParser(out.toByteArray());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(1, jp.getIntValue());
- if (addHeader) {
- assertNull(jp.nextToken());
- }
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(2, jp.getIntValue());
- if (addHeader) {
- assertNull(jp.nextToken());
- }
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(3, jp.getIntValue());
- assertNull(jp.nextToken());
- jg.close();
- }
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- protected void _verifyMultiDoc(boolean addHeader, boolean addEndMarker) throws Exception
- {
- SmileFactory f = smileFactory(false, addHeader, addEndMarker);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator jg = f.createJsonGenerator(out);
- // First doc, JSON Object
- jg.writeStartObject();
- jg.writeEndObject();
- jg.close();
- // and second, array
- jg = f.createJsonGenerator(out);
- jg.writeStartArray();
- jg.writeEndArray();
- jg.close();
-
- // and read it back
- SmileParser jp = f.createJsonParser(out.toByteArray());
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
-
- // now: if one of header or end marker (or, both) enabled, should get null here:
- if (addHeader || addEndMarker) {
- assertNull(jp.nextToken());
- }
-
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
-
- // end
- assertNull(jp.nextToken());
- // and no more:
- assertNull(jp.nextToken());
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileFeatures.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileFeatures.java.svn-base
deleted file mode 100644
index 100196c..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileFeatures.java.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import org.codehaus.jackson.map.*;
-import org.codehaus.jackson.smile.SmileFactory;
-
-public class TestSmileFeatures
- extends SmileTestBase
-{
- /*
- /**********************************************************
- /* Helper types
- /**********************************************************
- */
-
- static class Bean {
- public int value;
- }
-
- /*
- /**********************************************************
- /* Unit tests
- /**********************************************************
- */
- // Let's ensure indentation doesn't break anything (should be NOP)
- public void testIndent() throws Exception
- {
- ObjectMapper mapper = new ObjectMapper(new SmileFactory());
- mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
- Bean bean = new Bean();
- bean.value = 42;
-
- byte[] smile = mapper.writeValueAsBytes(bean);
- Bean result = mapper.readValue(smile, 0, smile.length, Bean.class);
- assertEquals(42, result.value);
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGenerator.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGenerator.java.svn-base
deleted file mode 100644
index 01cedd1..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGenerator.java.svn-base
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import static org.codehaus.jackson.smile.SmileConstants.*;
-
-public class TestSmileGenerator
- extends SmileTestBase
-{
- /**
- * Test for verifying handling of 'true', 'false' and 'null' literals
- */
- public void testSimpleLiterals() throws Exception
- {
- // false, no header (or frame marker)
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeBoolean(true);
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_TRUE);
-
- // false, no header or frame marker
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeBoolean(false);
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_FALSE);
-
- // null, no header or frame marker
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNull();
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_NULL);
-
- // And then with some other combinations:
- // true, but with header
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, true);
- gen.writeBoolean(true);
- gen.close();
-
- // note: version, and 'check shared names', but not 'check shared strings' or 'raw binary'
- int b4 = HEADER_BYTE_4 | SmileConstants.HEADER_BIT_HAS_SHARED_NAMES;
-
- _verifyBytes(out.toByteArray(),
- HEADER_BYTE_1, HEADER_BYTE_2, HEADER_BYTE_3, (byte) b4,
- SmileConstants.TOKEN_LITERAL_TRUE);
-
- // null, with header and end marker
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, true);
- gen.enable(SmileGenerator.Feature.WRITE_END_MARKER);
- gen.writeNull();
- gen.close();
- _verifyBytes(out.toByteArray(),
- HEADER_BYTE_1, HEADER_BYTE_2, HEADER_BYTE_3, (byte) b4,
- TOKEN_LITERAL_NULL, BYTE_MARKER_END_OF_CONTENT);
- }
-
- public void testSimpleArray() throws Exception
- {
- // First: empty array (2 bytes)
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartArray();
- gen.writeEndArray();
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_START_ARRAY,
- SmileConstants.TOKEN_LITERAL_END_ARRAY);
-
- // then simple array with 3 literals
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeStartArray();
- gen.writeBoolean(true);
- gen.writeNull();
- gen.writeBoolean(false);
- gen.writeEndArray();
- gen.close();
- assertEquals(5, out.toByteArray().length);
-
- // and then array containing another array and short String
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeStartArray();
- gen.writeStartArray();
- gen.writeEndArray();
- gen.writeString("12");
- gen.writeEndArray();
- gen.close();
- // 4 bytes for start/end arrays; 3 bytes for short ascii string
- assertEquals(7, out.toByteArray().length);
- }
-
- public void testShortAscii() throws Exception
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeString("abc");
- gen.close();
- _verifyBytes(out.toByteArray(), (byte)0x42, (byte) 'a', (byte) 'b', (byte) 'c');
- }
-
-
- public void testTrivialObject() throws Exception
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartObject();
- gen.writeNumberField("a", 6);
- gen.writeEndObject();
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_START_OBJECT,
- (byte) 0x80, (byte) 'a', (byte) (0xC0 + SmileUtil.zigzagEncode(6)),
- SmileConstants.TOKEN_LITERAL_END_OBJECT);
- }
-
- public void test2FieldObject() throws Exception
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartObject();
- gen.writeNumberField("a", 1);
- gen.writeNumberField("b", 2);
- gen.writeEndObject();
- gen.close();
- _verifyBytes(out.toByteArray(), SmileConstants.TOKEN_LITERAL_START_OBJECT,
- (byte) 0x80, (byte) 'a', (byte) (0xC0 + SmileUtil.zigzagEncode(1)),
- (byte) 0x80, (byte) 'b', (byte) (0xC0 + SmileUtil.zigzagEncode(2)),
- SmileConstants.TOKEN_LITERAL_END_OBJECT);
- }
-
- public void testAnotherObject() throws Exception
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartObject();
- gen.writeNumberField("a", 8);
- gen.writeFieldName("b");
- gen.writeStartArray();
- gen.writeBoolean(true);
- gen.writeEndArray();
- gen.writeFieldName("c");
- gen.writeStartObject();
- gen.writeEndObject();
-
- gen.writeFieldName("d");
- gen.writeStartObject();
- gen.writeFieldName("3");
- gen.writeNull();
- gen.writeEndObject();
-
- gen.writeEndObject();
- gen.close();
- assertEquals(21, out.toByteArray().length);
- }
-
- /**
- * Test to verify that
- */
- public void testSharedStrings() throws Exception
- {
- // first, no sharing, 2 separate Strings
- final String VALUE = "abcde12345";
- byte[] data = writeRepeatedString(false, VALUE);
- int BASE_LEN = 28;
- assertEquals(BASE_LEN, data.length);
- data = writeRepeatedString(true, VALUE);
- if (data.length >= BASE_LEN) { // should be less
- fail("Expected shared String length to be < "+BASE_LEN+", was "+data.length);
- }
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private byte[] writeRepeatedString(boolean shared, String value) throws Exception
- {
- SmileFactory f = new SmileFactory();
- // need header to enable shared string values
- f.configure(SmileGenerator.Feature.WRITE_HEADER, true);
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, shared);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = f.createJsonGenerator(out);
- gen.writeStartArray();
- gen.writeString(value);
- gen.writeString(value);
- gen.writeEndArray();
- gen.close();
- return out.toByteArray();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorBufferRecycle.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorBufferRecycle.java.svn-base
deleted file mode 100644
index 3a2d68a..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorBufferRecycle.java.svn-base
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.jackson.*;
-
-/* Test based on kimchy's issue (see https://gist.github.com/853232);
- * exhibits an issue with buffer recycling.
- *
- * @since 1.8
- */
-public class TestSmileGeneratorBufferRecycle extends SmileTestBase
-{
- public void testMaps() throws Exception
- {
- SmileFactory factory = new SmileFactory();
-
- Map<?,?> props1 = buildMap("", 65);
- Map<?,?> props2 = buildMap("", 1);
-
- writeMapAndParse(factory, props1);
- writeMapAndParse(factory, props2);
- writeMapAndParse(factory, props1);
- writeMapAndParse(factory, props2);
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private static void writeMapAndParse(SmileFactory factory, Map<?,?> map) throws Exception {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- // generate
- JsonGenerator generator = factory.createJsonGenerator(os);
- writeMap(generator, map);
- generator.close();
-
- // parse
- JsonParser parser = factory.createJsonParser(os.toByteArray());
- while (parser.nextToken() != null) {
-
- }
- }
-
- private static Map<?,?> buildMap(String prefix, int size) {
- HashMap<String,String> props = new HashMap<String, String>();
- for (int it = 0; it < size; it++) {
- String key = prefix + "prop_" + it;
- props.put(key, "a");
- }
- return props;
- }
-
-
- // A sample utility to write a map
-
- public static void writeMap(JsonGenerator gen, Map<?,?> map) throws IOException {
- gen.writeStartObject();
-
- for (Map.Entry<?,?> entry : map.entrySet()) {
- gen.writeFieldName((String) entry.getKey());
- Object value = entry.getValue();
- if (value == null) {
- gen.writeNull();
- } else {
- gen.writeString(value.toString());
- }
- }
-
- gen.writeEndObject();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorLongStrings.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorLongStrings.java.svn-base
deleted file mode 100644
index 5477a44..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorLongStrings.java.svn-base
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.jackson.*;
-
-public class TestSmileGeneratorLongStrings extends SmileTestBase
-{
- final static int DOC_LEN = 2000000; // 2 meg test doc
-
- public void testLongWithMultiBytes() throws Exception
- {
- SmileFactory f = new SmileFactory();
- ArrayList<String> strings = new ArrayList<String>();
- Random rnd = new Random(123);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(DOC_LEN);
- SmileGenerator gen = f.createJsonGenerator(out);
- gen.writeStartArray();
-
- // Let's create 1M doc, first using Strings
- while (out.size() < (DOC_LEN - 10000)) {
- String str = generateString(5000, rnd);
- strings.add(str);
- gen.writeString(str);
- }
- gen.writeEndArray();
- gen.close();
- // Written ok; let's try parsing then
- _verifyStrings(f, out.toByteArray(), strings);
-
- // Then same with char[]
- out = new ByteArrayOutputStream(DOC_LEN);
- gen = f.createJsonGenerator(out);
- gen.writeStartArray();
-
- // Let's create 1M doc, first using Strings
- for (int i = 0, len = strings.size(); i < len; ++i) {
- char[] ch = strings.get(i).toCharArray();
- gen.writeString(ch, 0, ch.length);
- }
- gen.writeEndArray();
- gen.close();
- _verifyStrings(f, out.toByteArray(), strings);
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- protected String generateString(int length, Random rnd) throws Exception
- {
- StringBuilder sw = new StringBuilder(length+10);
- do {
- // First, add 7 ascii characters
- int num = 4 + (rnd.nextInt() & 7);
- while (--num >= 0) {
- sw.append((char) ('A' + num));
- }
- // Then a unicode char of 2, 3 or 4 bytes long
- switch (rnd.nextInt() % 3) {
- case 0:
- sw.append((char) (256 + rnd.nextInt() & 511));
- break;
- case 1:
- sw.append((char) (2048 + rnd.nextInt() & 4095));
- break;
- default:
- sw.append((char) (65536 + rnd.nextInt() & 0x3FFF));
- break;
- }
- } while (sw.length() < length);
- return sw.toString();
- }
-
- private void _verifyStrings(JsonFactory f, byte[] input, List<String> strings)
- throws IOException
- {
- JsonParser jp = f.createJsonParser(input);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- for (int i = 0, len = strings.size(); i < len; ++i) {
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals(strings.get(i), jp.getText());
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- jp.close();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorNumbers.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorNumbers.java.svn-base
deleted file mode 100644
index babfb52..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorNumbers.java.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.ByteArrayOutputStream;
-
-public class TestSmileGeneratorNumbers
- extends SmileTestBase
-{
- public void testSmallInts() throws Exception
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeNumber(3);
- gen.close();
- _verifyBytes(out.toByteArray(), (byte) (0xC0 + SmileUtil.zigzagEncode(3)));
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(0);
- gen.close();
- _verifyBytes(out.toByteArray(), (byte) (0xC0 + SmileUtil.zigzagEncode(0)));
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(-6);
- gen.close();
- _verifyBytes(out.toByteArray(), (byte) (0xC0 + SmileUtil.zigzagEncode(-6)));
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(15);
- gen.close();
- _verifyBytes(out.toByteArray(), (byte) (0xC0 + SmileUtil.zigzagEncode(15)));
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(-16);
- gen.close();
- _verifyBytes(out.toByteArray(), (byte) (0xC0 + SmileUtil.zigzagEncode(-16)));
- }
-
- public void testOtherInts() throws Exception
- {
- // beyond tiny ints, 6-bit values take 2 bytes
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeNumber(16);
- gen.close();
- assertEquals(2, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(-17);
- gen.close();
- assertEquals(2, out.toByteArray().length);
-
- // and up to 13-bit values take 3 bytes
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(0xFFF);
- gen.close();
- assertEquals(3, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(-4096);
- gen.close();
- assertEquals(3, out.toByteArray().length);
-
- // up to 20, 4 bytes... and so forth
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(0x1000);
- gen.close();
- assertEquals(4, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(500000);
- gen.close();
- assertEquals(4, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(Integer.MAX_VALUE);
- gen.close();
- assertEquals(6, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(Integer.MIN_VALUE);
- gen.close();
- assertEquals(6, out.toByteArray().length);
-
- // up to longest ones, taking 11 bytes
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(Long.MAX_VALUE);
- gen.close();
- assertEquals(11, out.toByteArray().length);
-
- out = new ByteArrayOutputStream();
- gen = smileGenerator(out, false);
- gen.writeNumber(Long.MIN_VALUE);
- gen.close();
- assertEquals(11, out.toByteArray().length);
- }
-
- public void testFloats() throws Exception
- {
- // float length is fixed, 6 bytes
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeNumber(0.125f);
- gen.close();
- assertEquals(6, out.toByteArray().length);
- }
-
- public void testDoubles() throws Exception
- {
- // double length is fixed, 11 bytes
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeNumber(0.125);
- gen.close();
- assertEquals(11, out.toByteArray().length);
- }
-
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorSymbols.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorSymbols.java.svn-base
deleted file mode 100644
index 2cfd21e..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileGeneratorSymbols.java.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.ByteArrayOutputStream;
-
-import org.codehaus.jackson.*;
-
-public class TestSmileGeneratorSymbols extends SmileTestBase
-{
- /**
- * Simple test to verify that second reference will not output new String, but
- * rather references one output earlier.
- */
- public void testSharedNameSimple() throws Exception
- {
- // false, no header (or frame marker)
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartArray();
- gen.writeStartObject();
- gen.writeNumberField("abc", 1);
- gen.writeEndObject();
- gen.writeStartObject();
- gen.writeNumberField("abc", 2);
- gen.writeEndObject();
- gen.writeEndArray();
- gen.close();
- byte[] result = out.toByteArray();
- assertEquals(13, result.length);
- }
-
- // same as above, but with name >= 64 characters
- public void testSharedNameSimpleLong() throws Exception
- {
- String digits = "01234567899";
-
- // Base is 76 chars; loop over couple of shorter ones too
-
- final String LONG_NAME = "a"+digits+"b"+digits+"c"+digits+"d"+digits+"e"+digits+"f"+digits+"ABCD";
-
- for (int i = 0; i < 4; ++i) {
- int strLen = LONG_NAME.length() - i;
- String field = LONG_NAME.substring(0, strLen);
- // false, no header (or frame marker)
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SmileGenerator gen = smileGenerator(out, false);
- gen.writeStartArray();
- gen.writeStartObject();
- gen.writeNumberField(field, 1);
- gen.writeEndObject();
- gen.writeStartObject();
- gen.writeNumberField(field, 2);
- gen.writeEndObject();
- gen.writeEndArray();
- gen.close();
- byte[] result = out.toByteArray();
- assertEquals(11 + field.length(), result.length);
-
- // better also parse it back...
- JsonParser parser = _smileParser(result);
- assertToken(JsonToken.START_ARRAY, parser.nextToken());
-
- assertToken(JsonToken.START_OBJECT, parser.nextToken());
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals(field, parser.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, parser.nextToken());
- assertEquals(1, parser.getIntValue());
- assertToken(JsonToken.END_OBJECT, parser.nextToken());
-
- assertToken(JsonToken.START_OBJECT, parser.nextToken());
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals(field, parser.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, parser.nextToken());
- assertEquals(2, parser.getIntValue());
- assertToken(JsonToken.END_OBJECT, parser.nextToken());
-
- assertToken(JsonToken.END_ARRAY, parser.nextToken());
- }
- }
-
- public void testLongNamesNonShared() throws Exception
- {
- _testLongNames(false);
- }
-
- public void testLongNamesShared() throws Exception
- {
- _testLongNames(true);
- }
-
- /*
- /**********************************************************
- /* Secondary methods
- /**********************************************************
- */
-
- // For issue [JACKSON-552]
- public void _testLongNames(boolean shareNames) throws Exception
- {
- // 68 bytes long (on boundary)
- final String FIELD_NAME = "dossier.domaine.supportsDeclaratifsForES.SupportDeclaratif.reference";
- final String VALUE = "11111";
-
- SmileFactory factory = new SmileFactory();
- factory.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, shareNames);
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- JsonGenerator gen = factory.createJsonGenerator(os);
- gen.writeStartObject();
- gen.writeObjectFieldStart("query");
- gen.writeStringField(FIELD_NAME, VALUE);
- gen.writeEndObject();
- gen.writeEndObject();
- gen.close();
-
- JsonParser parser = factory.createJsonParser(os.toByteArray());
- assertNull(parser.getCurrentToken());
- assertToken(JsonToken.START_OBJECT, parser.nextToken());
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals("query", parser.getCurrentName());
- assertToken(JsonToken.START_OBJECT, parser.nextToken());
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals(FIELD_NAME, parser.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, parser.nextToken());
- assertEquals(VALUE, parser.getText());
- assertToken(JsonToken.END_OBJECT, parser.nextToken());
- assertToken(JsonToken.END_OBJECT, parser.nextToken());
- }
-
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParser.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParser.java.svn-base
deleted file mode 100644
index 16247d9..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParser.java.svn-base
+++ /dev/null
@@ -1,404 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonToken;
-
-public class TestSmileParser
- extends SmileTestBase
-{
- // Unit tests for verifying that if header/signature is required,
- // lacking it is fatal
- public void testMandatoryHeader() throws IOException
- {
- // first test failing case
- byte[] data = _smileDoc("[ null ]", false);
- try {
- _smileParser(data, true);
- fail("Should have gotten exception for missing header");
- } catch (Exception e) {
- verifyException(e, "does not start with Smile format header");
- }
-
- // and then test passing one
- SmileParser p = _smileParser(data, false);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_NULL, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- }
-
- public void testSimple() throws IOException
- {
- byte[] data = _smileDoc("[ true, null, false ]");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertToken(JsonToken.VALUE_NULL, p.nextToken());
- assertToken(JsonToken.VALUE_FALSE, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-
- public void testArrayWithString() throws IOException
- {
- byte[] data = _smileDoc("[ \"abc\" ]");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals("abc", p.getText());
- assertEquals(0, p.getTextOffset());
- assertEquals(3, p.getTextLength());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- p.close();
- }
-
- public void testEmptyStrings() throws IOException
- {
- // first, empty key
- byte[] data = _smileDoc("{ \"\":true }");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("", p.getCurrentName());
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // then empty value
- data = _smileDoc("{ \"abc\":\"\" }");
- p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("abc", p.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals("", p.getText());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // and combinations
- data = _smileDoc("{ \"\":\"\", \"\":\"\" }");
- p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("", p.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals("", p.getText());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("", p.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals("", p.getText());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-
- // Test for ASCII String values longer than 64 bytes; separate
- // since handling differs
- public void testLongAsciiString() throws IOException
- {
- final String DIGITS = "1234567890";
- String LONG = DIGITS + DIGITS + DIGITS + DIGITS;
- LONG = LONG + LONG + LONG + LONG;
- byte[] data = _smileDoc(quote(LONG));
-
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals(LONG, p.getText());
- assertNull(p.nextToken());
- }
-
- //Test for non-ASCII String values longer than 64 bytes; separate
- // since handling differs
- public void testLongUnicodeString() throws IOException
- {
- final String DIGITS = "1234567890";
- final String UNIC = "\u00F06"; // o with umlauts
- String LONG = DIGITS + UNIC + DIGITS + UNIC + UNIC + DIGITS + DIGITS;
- LONG = LONG + LONG + LONG;
- byte[] data = _smileDoc(quote(LONG));
-
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals(LONG, p.getText());
- assertNull(p.nextToken());
- }
-
- public void testTrivialObject() throws IOException
- {
- byte[] data = _smileDoc("{\"abc\":13}");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
-
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("abc", p.getCurrentName());
- assertEquals("abc", p.getText());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(13, p.getIntValue());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- }
-
- public void testSimpleObject() throws IOException
- {
- byte[] data = _smileDoc("{\"a\":8, \"b\" : [ true ], \"c\" : { }, \"d\":{\"e\":null}}");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("a", p.getCurrentName());
- assertEquals("a", p.getText());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(8, p.getIntValue());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("b", p.getCurrentName());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("c", p.getCurrentName());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("d", p.getCurrentName());
-
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("e", p.getCurrentName());
- assertToken(JsonToken.VALUE_NULL, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
-
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- p.close();
- }
-
- public void testNestedObject() throws IOException
- {
- byte[] data = _smileDoc("[{\"a\":{\"b\":[1]}}]");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken()); // a
- assertEquals("a", p.getCurrentName());
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken()); // b
- assertEquals("b", p.getCurrentName());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- }
-
- public void testJsonSampleDoc() throws IOException
- {
- byte[] data = _smileDoc(SAMPLE_DOC_JSON_SPEC);
- verifyJsonSpecSampleDoc(_smileParser(data), true);
- }
-
- public void testUnicodeStringValues() throws IOException
- {
- String uc = "\u00f6stl. v. Greenwich \u3333?";
- byte[] data = _smileDoc("[" +quote(uc)+"]");
-
- // First, just skipping
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // Then accessing data
- p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals(uc, p.getText());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // and then let's create longer text segment as well
- StringBuilder sb = new StringBuilder();
- while (sb.length() < 200) {
- sb.append(uc);
- }
- final String longer = sb.toString();
- data = _smileDoc("["+quote(longer)+"]");
-
- // Ok once again, first skipping, then accessing
- p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- assertEquals(longer, p.getText());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-
- public void testUnicodePropertyNames() throws IOException
- {
- String uc = "\u00f6stl. v. Greenwich \u3333";
- byte[] data = _smileDoc("{" +quote(uc)+":true}");
-
- // First, just skipping
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // Then accessing data
- p = _smileParser(data);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals(uc, p.getCurrentName());
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-
- // Simple test to verify that byte 0 is not used (an implementation
- // might mistakenly consider it a string value reference)
- public void testInvalidByte() throws IOException
- {
- byte[] data = new byte[] { SmileConstants.TOKEN_LITERAL_START_ARRAY,
- (byte) SmileConstants.TOKEN_PREFIX_SHARED_STRING_SHORT,
- (byte) SmileConstants.TOKEN_LITERAL_END_ARRAY
- };
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- // And now should get an error
- try {
- JsonToken t = p.nextToken();
- fail("Expected parse error, got: "+t);
- } catch (IOException e) {
- verifyException(e, "Invalid token byte 0x00");
- }
- }
-
- // [JACKSON-629]
- public void testNameBoundary() throws IOException
- {
- SmileFactory f = smileFactory(true, true, false);
- // let's create 3 meg docs
- final int LEN = 3 * 1000 * 1000;
- final String FIELD = "field01"; // important: 7 chars
-
- for (int offset = 0; offset < 12; ++offset) {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(LEN);
- // To trigger boundary condition, need to shuffle stuff around a bit...
- for (int i = 0; i < offset; ++i) {
- bytes.write(0);
- }
-
- // force back-refs off, easier to trigger problem
- f.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, false);
- SmileGenerator gen = f.createJsonGenerator(bytes);
-
- int count = 0;
- do {
- gen.writeStartObject();
- // importa
- gen.writeNumberField(FIELD, count % 17);
- gen.writeEndObject();
- ++count;
- } while (bytes.size() < (LEN - 100));
- gen.close();
-
- // and then read back
- byte[] json = bytes.toByteArray();
- SmileParser jp = f.createJsonParser(new ByteArrayInputStream(json, offset, json.length-offset));
- int i = 0;
-
- while (i < count) {
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(FIELD, jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals((i % 17), jp.getIntValue());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- ++i;
- }
- // and should be done now
- assertNull(jp.nextToken());
- jp.close();
- }
- }
-
- // [JACKSON-640]: Problem with getTextCharacters/Offset/Length
- public void testCharacters() throws IOException
- {
- // ensure we are using both back-ref types
- SmileFactory sf = new SmileFactory();
- sf.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, true);
- sf.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(100);
-
- JsonGenerator jgen = sf.createJsonGenerator(bytes);
- jgen.writeStartArray();
- jgen.writeStartObject();
- jgen.writeStringField("key", "value");
- jgen.writeEndObject();
- jgen.writeStartObject();
- jgen.writeStringField("key", "value");
- jgen.writeEndObject();
- jgen.writeEndArray();
- jgen.close();
-
- SmileParser p = _smileParser(bytes.toByteArray());
-
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- String str;
-
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- str = new String(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
- assertEquals("key", str);
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- str = new String(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
- assertEquals("value", str);
- assertToken(JsonToken.END_OBJECT, p.nextToken());
-
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- str = new String(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
- assertEquals("key", str);
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- str = new String(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
- assertEquals("value", str);
- assertToken(JsonToken.END_OBJECT, p.nextToken());
-
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserBinary.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserBinary.java.svn-base
deleted file mode 100644
index a94252f..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserBinary.java.svn-base
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-
-import static org.junit.Assert.*;
-
-import org.codehaus.jackson.JsonToken;
-
-public class TestSmileParserBinary
- extends SmileTestBase
-{
- final static int[] SIZES = new int[] {
- 1, 2, 3, 4, 5, 6,
- 7, 8, 12,
- 100, 350, 1900, 6000, 19000, 65000,
- 139000
- };
-
- public void testRawAsArray() throws IOException
- {
- _testBinaryAsArray(true);
- }
-
- public void test7BitAsArray() throws IOException
- {
- _testBinaryAsArray(false);
- }
-
- // Added based on [JACKSON-376]
- public void testRawAsObject() throws IOException
- {
- _testBinaryAsObject(true);
- }
-
- // Added based on [JACKSON-376]
- public void test7BitAsObject() throws IOException
- {
- _testBinaryAsObject(false);
- }
-
- public void testRawAsRootValue() throws IOException
- {
- _testBinaryAsRoot(true);
- }
-
- public void test7BitAsRootValue() throws IOException
- {
- _testBinaryAsRoot(false);
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private void _testBinaryAsRoot(boolean raw) throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw);
- for (int size : SIZES) {
- byte[] data = _generateData(size);
- ByteArrayOutputStream bo = new ByteArrayOutputStream(size+10);
- SmileGenerator g = f.createJsonGenerator(bo);
- g.writeBinary(data);
- g.close();
- byte[] smile = bo.toByteArray();
-
- // and verify
- SmileParser p = f.createJsonParser(smile);
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- byte[] result = p.getBinaryValue();
- assertArrayEquals(data, result);
- assertNull(p.nextToken());
- p.close();
-
- // and second time around, skipping
- p = f.createJsonParser(smile);
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
- }
-
- private void _testBinaryAsArray(boolean raw) throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw);
- for (int size : SIZES) {
- byte[] data = _generateData(size);
- ByteArrayOutputStream bo = new ByteArrayOutputStream(size+10);
- SmileGenerator g = f.createJsonGenerator(bo);
- g.writeStartArray();
- g.writeBinary(data);
- g.writeNumber(1); // just to verify there's no overrun
- g.writeEndArray();
- g.close();
- byte[] smile = bo.toByteArray();
-
- // and verify
- SmileParser p = f.createJsonParser(smile);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- byte[] result = p.getBinaryValue();
- assertArrayEquals(data, result);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(1, p.getIntValue());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // and second time around, skipping
- p = f.createJsonParser(smile);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
- }
-
- private void _testBinaryAsObject(boolean raw) throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw);
- for (int size : SIZES) {
- byte[] data = _generateData(size);
- ByteArrayOutputStream bo = new ByteArrayOutputStream(size+10);
- SmileGenerator g = f.createJsonGenerator(bo);
- g.writeStartObject();
- g.writeFieldName("binary");
- g.writeBinary(data);
- g.writeEndObject();
- g.close();
- byte[] smile = bo.toByteArray();
-
- // and verify
- SmileParser p = f.createJsonParser(smile);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("binary", p.getCurrentName());
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- byte[] result = p.getBinaryValue();
- assertArrayEquals(data, result);
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
-
- // and second time around, skipping
- p = f.createJsonParser(smile);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
- }
-
- private byte[] _generateData(int size)
- {
- byte[] result = new byte[size];
- for (int i = 0; i < size; ++i) {
- result[i] = (byte) (i % 255);
- }
- return result;
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserLocation.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserLocation.java.svn-base
deleted file mode 100644
index ca9d29f..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserLocation.java.svn-base
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonLocation;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-
-public class TestSmileParserLocation
- extends SmileTestBase
-{
- /**
- * Basic unit test to verify that [JACKSON-] has been resolved.
- */
- public void testSimpleOffsets() throws IOException
- {
- byte[] data = _smileDoc("[ true, null, false, 511 ]", true); // true -> write header
-
- JsonParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- JsonLocation loc = p.getCurrentLocation();
- assertNotNull(loc);
- // first: -1 for "not known", for character-based stuff
- assertEquals(-1, loc.getCharOffset());
- assertEquals(-1, loc.getColumnNr());
- assertEquals(-1, loc.getLineNr());
- // but first 4 bytes are for header
- assertEquals(4, loc.getByteOffset());
-
- // array marker is a single byte, so:
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertEquals(5, p.getCurrentLocation().getByteOffset());
- assertEquals(4, p.getTokenLocation().getByteOffset());
-
- // same for true and others except for last int
- assertToken(JsonToken.VALUE_TRUE, p.nextToken());
- assertEquals(6, p.getCurrentLocation().getByteOffset());
- assertEquals(5, p.getTokenLocation().getByteOffset());
-
- assertToken(JsonToken.VALUE_NULL, p.nextToken());
- assertEquals(7, p.getCurrentLocation().getByteOffset());
- assertEquals(6, p.getTokenLocation().getByteOffset());
-
- assertToken(JsonToken.VALUE_FALSE, p.nextToken());
- assertEquals(8, p.getCurrentLocation().getByteOffset());
- assertEquals(7, p.getTokenLocation().getByteOffset());
-
- // 0x1FF takes 3 bytes (type byte, 7/6 bit segments)
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(511, p.getIntValue());
- assertEquals(11, p.getCurrentLocation().getByteOffset());
- assertEquals(8, p.getTokenLocation().getByteOffset());
-
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertEquals(12, p.getCurrentLocation().getByteOffset());
- assertEquals(11, p.getTokenLocation().getByteOffset());
-
- assertNull(p.nextToken());
- p.close();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserNumbers.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserNumbers.java.svn-base
deleted file mode 100644
index d7f38cf..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserNumbers.java.svn-base
+++ /dev/null
@@ -1,301 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-
-public class TestSmileParserNumbers
- extends SmileTestBase
-{
- public void testIntsMedium() throws IOException
- {
- byte[] data = _smileDoc("255");
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(255, p.getIntValue());
- assertEquals("255", p.getText());
-
- data = _smileDoc("-999");
- p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertEquals(-999, p.getIntValue());
- assertEquals("-999", p.getText());
-
- data = _smileDoc("123456789");
- p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertEquals(123456789, p.getIntValue());
- }
-
- public void testMinMaxInts() throws IOException
- {
- byte[] data = _smileDoc(String.valueOf(Integer.MAX_VALUE));
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertEquals(Integer.MAX_VALUE, p.getIntValue());
-
- data = _smileDoc(String.valueOf(Integer.MIN_VALUE));
- p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertEquals(Integer.MIN_VALUE, p.getIntValue());
- }
-
- public void testIntsInObjectSkipping() throws IOException
- {
- byte[] data = _smileDoc("{\"a\":200,\"b\":200}");
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("a", p.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- // let's NOT access value, forcing skipping
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("b", p.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- // let's NOT access value, forcing skipping
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- }
-
- public void testBorderLongs() throws IOException
- {
- long l = (long) Integer.MIN_VALUE - 1L;
- byte[] data = _smileDoc(String.valueOf(l), false);
- assertEquals(6, data.length);
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
- assertEquals(l, p.getLongValue());
-
- l = 1L + (long) Integer.MAX_VALUE;
- data = _smileDoc(String.valueOf(l), false);
- assertEquals(6, data.length);
- p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
- assertEquals(l, p.getLongValue());
- }
-
- public void testLongs() throws IOException
- {
- long l = Long.MAX_VALUE;
- byte[] data = _smileDoc(String.valueOf(l));
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
- assertEquals(l, p.getLongValue());
- assertEquals(String.valueOf(l), p.getText());
-
- l = Long.MIN_VALUE;
- data = _smileDoc(String.valueOf(l));
- p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
- assertEquals(l, p.getLongValue());
- assertEquals(String.valueOf(l), p.getText());
- }
-
- public void testArrayWithInts() throws IOException
- {
- byte[] data = _smileDoc("[ 1, 0, -1, 255, -999, "
- +Integer.MIN_VALUE+","+Integer.MAX_VALUE+","
- +Long.MIN_VALUE+", "+Long.MAX_VALUE+" ]");
- SmileParser p = _smileParser(data);
- assertNull(p.getCurrentToken());
- assertToken(JsonToken.START_ARRAY, p.nextToken());
-
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(1, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(0, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(-1, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
-
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(255, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(-999, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
-
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
- assertEquals(Integer.MIN_VALUE, p.getIntValue());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(Integer.MAX_VALUE, p.getIntValue());
- assertEquals(JsonParser.NumberType.INT, p.getNumberType());
-
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
- assertEquals(Long.MIN_VALUE, p.getLongValue());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(Long.MAX_VALUE, p.getLongValue());
- assertEquals(JsonParser.NumberType.LONG, p.getNumberType());
-
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- p.close();
- }
-
- public void testFloats() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- SmileGenerator g = smileGenerator(bo, false);
- float value = 0.37f;
- g.writeNumber(value);
- g.close();
- byte[] data = bo.toByteArray();
- assertEquals(6, data.length);
-
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(JsonParser.NumberType.FLOAT, p.getNumberType());
- assertEquals(value, p.getFloatValue());
- }
-
- public void testDoubles() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- SmileGenerator g = smileGenerator(bo, false);
- double value = -12.0986;
- g.writeNumber(value);
- g.close();
- byte[] data = bo.toByteArray();
- assertEquals(11, data.length);
-
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(JsonParser.NumberType.DOUBLE, p.getNumberType());
- assertEquals(value, p.getDoubleValue());
- }
-
- public void testArrayWithDoubles() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- SmileGenerator g = smileGenerator(bo, false);
- g.writeStartArray();
- g.writeNumber(0.1f);
- g.writeNumber(0.333);
- g.writeEndArray();
- g.close();
- byte[] data = bo.toByteArray();
- assertEquals(19, data.length);
-
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(JsonParser.NumberType.FLOAT, p.getNumberType());
- assertEquals(0.1f, p.getFloatValue());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(JsonParser.NumberType.DOUBLE, p.getNumberType());
- assertEquals(0.333, p.getDoubleValue());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- }
-
- public void testObjectWithDoubles() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- SmileGenerator g = smileGenerator(bo, false);
- g.writeStartObject();
- g.writeNumberField("x", 0.5);
- g.writeNumberField("y", 0.01338);
- g.writeEndObject();
- g.close();
-
- byte[] data = bo.toByteArray();
-
- // first let's just skip
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- p.close();
-
- // and then check data too (skip codepath distinct)
- p = _smileParser(data);
- assertToken(JsonToken.START_OBJECT, p.nextToken());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("x", p.getText());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(0.5, p.getDoubleValue());
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("y", p.getText());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(0.01338, p.getDoubleValue());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- p.close();
- }
-
- public void testBigInteger() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- BigInteger in = new BigInteger(String.valueOf(Long.MIN_VALUE)+"0012575934");
- SmileGenerator g = smileGenerator(bo, false);
- g.writeNumber(in);
- g.close();
- byte[] data = bo.toByteArray();
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonParser.NumberType.BIG_INTEGER, p.getNumberType());
- assertEquals(BigInteger.class, p.getNumberValue().getClass());
- assertEquals(in, p.getBigIntegerValue());
- p.close();
-
- // second test; verify skipping works
- bo = new ByteArrayOutputStream();
- g = smileGenerator(bo, false);
- g.writeStartArray();
- g.writeNumber(in);
- g.writeEndArray();
- g.close();
- data = bo.toByteArray();
- p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-
- public void testBigDecimal() throws IOException
- {
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- BigDecimal in = new BigDecimal("32599.00001");
- SmileGenerator g = smileGenerator(bo, false);
- g.writeNumber(in);
- g.close();
- byte[] data = bo.toByteArray();
- SmileParser p = _smileParser(data);
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertEquals(JsonParser.NumberType.BIG_DECIMAL, p.getNumberType());
- assertEquals(BigDecimal.class, p.getNumberValue().getClass());
- assertEquals(in, p.getDecimalValue());
- p.close();
-
- // second test; verify skipping works
- bo = new ByteArrayOutputStream();
- g = smileGenerator(bo, false);
- g.writeStartArray();
- g.writeNumber(in);
- g.writeEndArray();
- g.close();
- data = bo.toByteArray();
- p = _smileParser(data);
- assertToken(JsonToken.START_ARRAY, p.nextToken());
- assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- assertNull(p.nextToken());
- p.close();
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserSymbolHandling.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserSymbolHandling.java.svn-base
deleted file mode 100644
index e5f0e92..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileParserSymbolHandling.java.svn-base
+++ /dev/null
@@ -1,560 +0,0 @@
-package org.codehaus.jackson.smile;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.sym.BytesToNameCanonicalizer;
-
-/**
- * Unit tests for verifying that symbol handling works as planned, including
- * efficient reuse of names encountered during parsing.
- */
-public class TestSmileParserSymbolHandling
- extends SmileTestBase
-{
- /*
- /**********************************************************
- /* Helper types, constants
- /**********************************************************
- */
-
- private final static String[] SHARED_SYMBOLS = new String[] {
- "g", "J", "v", "B", "S", "JAVA",
- "h", "J", "LARGE",
- "JAVA", "J", "SMALL"
- };
-
- static class MediaItem
- {
- public Content content;
- public Image[] images;
- }
-
- public enum Size { SMALL, LARGE; }
- public enum Player { JAVA, FLASH; }
-
- static class Image
- {
- public String uri;
- public String title;
- public int width;
- public int height;
- public Size size;
-
- public Image() { }
- public Image(String uri, String title, int w, int h, Size s)
- {
- this.uri = uri;
- this.title = title;
- width = w;
- height = h;
- size = s;
- }
- }
-
- static class Content
- {
- public Player player;
- public String uri;
- public String title;
- public int width;
- public int height;
- public String format;
- public long duration;
- public long size;
- public int bitrate;
- public String[] persons;
- public String copyright;
- }
-
- /*
- /**********************************************************
- /* Unit tests
- /**********************************************************
- */
-
- public void testSimple() throws IOException
- {
- final String STR1 = "a";
-
- byte[] data = _smileDoc("{ "+quote(STR1)+":1, \"foobar\":2, \"longername\":3 }");
- SmileFactory f = new SmileFactory();
- SmileParser p = _smileParser(f, data);
- final BytesToNameCanonicalizer symbols1 = p._symbols;
- assertEquals(0, symbols1.size());
-
- assertEquals(JsonToken.START_OBJECT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- // field names are interned:
- assertSame(STR1, p.getCurrentName());
- assertEquals(1, symbols1.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- assertSame("foobar", p.getCurrentName());
- assertEquals(2, symbols1.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- assertSame("longername", p.getCurrentName());
- assertEquals(3, symbols1.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- assertEquals(3, symbols1.size());
- p.close();
-
- // but let's verify that symbol table gets reused properly
- p = _smileParser(f, data);
- BytesToNameCanonicalizer symbols2 = p._symbols;
- // symbol tables are not reused, but contents are:
- assertNotSame(symbols1, symbols2);
- assertEquals(3, symbols2.size());
-
- assertEquals(JsonToken.START_OBJECT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- // field names are interned:
- assertSame(STR1, p.getCurrentName());
- assertEquals(3, symbols2.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- assertSame("foobar", p.getCurrentName());
- assertEquals(3, symbols2.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.FIELD_NAME, p.nextToken());
- assertSame("longername", p.getCurrentName());
- assertEquals(3, symbols2.size());
- assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
- assertEquals(JsonToken.END_OBJECT, p.nextToken());
- assertNull(p.nextToken());
- assertEquals(3, symbols2.size());
- p.close();
-
- assertEquals(3, symbols2.size());
- p.close();
- }
-
- public void testSharedNames() throws IOException
- {
- final int COUNT = 19000;
-
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.WRITE_HEADER, false);
- f.configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, true);
- ByteArrayOutputStream out = new ByteArrayOutputStream(4000);
- JsonGenerator gen = f.createJsonGenerator(out);
- gen.writeStartArray();
- Random rnd = new Random(COUNT);
- for (int i = 0; i < COUNT; ++i) {
- gen.writeStartObject();
- int nr = rnd.nextInt() % 1200;
- gen.writeNumberField("f"+nr, nr);
- gen.writeEndObject();
- }
- gen.writeEndArray();
- gen.close();
- byte[] json = out.toByteArray();
-
- // And verify
- f.configure(SmileParser.Feature.REQUIRE_HEADER, false);
- JsonParser jp = f.createJsonParser(json);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- rnd = new Random(COUNT);
- for (int i = 0; i < COUNT; ++i) {
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- int nr = rnd.nextInt() % 1200;
- String name = "f"+nr;
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals(name, jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(nr, jp.getIntValue());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
-
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- }
-
- public void testSharedStrings() throws IOException
- {
- final int count = 19000;
- byte[] baseline = writeStringValues(false, count);
- assertEquals(763589, baseline.length);
- verifyStringValues(baseline, count);
-
- // and then shared; should be much smaller
- byte[] shared = writeStringValues(true, count);
- if (shared.length >= baseline.length) {
- fail("Expected shared String length < "+baseline.length+", was "+shared.length);
- }
- verifyStringValues(shared, count);
- }
-
- public void testSharedStringsInArrays() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(4000);
- JsonGenerator gen = f.createJsonGenerator(out);
- gen.writeStartArray();
- for (String value : SHARED_SYMBOLS) {
- gen.writeString(value);
- }
- gen.writeEndArray();
- gen.close();
-
- byte[] smile = out.toByteArray();
-
- JsonParser jp = f.createJsonParser(smile);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- for (String value : SHARED_SYMBOLS) {
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals(value, jp.getText());
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- }
-
- public void testSharedStringsInObject() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
- ByteArrayOutputStream out = new ByteArrayOutputStream(4000);
- JsonGenerator gen = f.createJsonGenerator(out);
- gen.writeStartObject();
- for (int i = 0; i < SHARED_SYMBOLS.length; ++i) {
- gen.writeFieldName("a"+i);
- gen.writeString(SHARED_SYMBOLS[i]);
- }
- gen.writeEndObject();
- gen.close();
-
- byte[] smile = out.toByteArray();
-
- JsonParser jp = f.createJsonParser(smile);
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- for (int i = 0; i < SHARED_SYMBOLS.length; ++i) {
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("a"+i, jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals(SHARED_SYMBOLS[i], jp.getText());
- }
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- }
-
- public void testSharedStringsMixed() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(4000);
- JsonGenerator gen = f.createJsonGenerator(out);
- gen.writeStartObject();
-
- gen.writeFieldName("media");
- gen.writeStartObject();
-
- gen.writeStringField("uri", "g");
- gen.writeStringField("title", "J");
- gen.writeNumberField("width", 640);
- gen.writeStringField("format", "v");
- gen.writeFieldName("persons");
- gen.writeStartArray();
- gen.writeString("B");
- gen.writeString("S");
- gen.writeEndArray();
- gen.writeStringField("player", "JAVA");
- gen.writeStringField("copyright", "NONE");
-
- gen.writeEndObject(); // media
-
- gen.writeFieldName("images");
- gen.writeStartArray();
-
- // 3 instances of identical entries
- for (int i = 0; i < 3; ++i) {
- gen.writeStartObject();
- gen.writeStringField("uri", "h");
- gen.writeStringField("title", "J");
- gen.writeNumberField("width", 1024);
- gen.writeNumberField("height", 768);
- gen.writeEndObject();
- }
- gen.writeEndArray();
-
- gen.writeEndObject();
- gen.close();
-
- byte[] smile = out.toByteArray();
-
- JsonParser jp = f.createJsonParser(smile);
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("media", jp.getCurrentName());
-
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("uri", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("g", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("title", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("J", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("width", jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(640, jp.getIntValue());
-
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("format", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("v", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("persons", jp.getCurrentName());
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("B", jp.getText());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("S", jp.getText());
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("player", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("JAVA", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("copyright", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("NONE", jp.getText());
-
- assertToken(JsonToken.END_OBJECT, jp.nextToken()); // media
-
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("images", jp.getCurrentName());
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
-
- // 3 instances of identical entries:
- for (int i = 0; i < 3; ++i) {
- assertToken(JsonToken.START_OBJECT, jp.nextToken());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("uri", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("h", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("title", jp.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals("J", jp.getText());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("width", jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(1024, jp.getIntValue());
- assertToken(JsonToken.FIELD_NAME, jp.nextToken());
- assertEquals("height", jp.getCurrentName());
- assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
- assertEquals(768, jp.getIntValue());
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- }
-
- assertToken(JsonToken.END_ARRAY, jp.nextToken()); // images
-
- assertToken(JsonToken.END_OBJECT, jp.nextToken());
- }
-
- public void testDataBindingAndShared() throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, true);
- MediaItem item = new MediaItem();
- Content c = new Content();
- c.uri = "g";
- c.title = "J";
- c.width = 640;
- c.height = 480;
- c.format = "v";
- c.duration = 18000000L;
- c.size = 58982400L;
- c.bitrate = 262144;
- c.persons = new String[] { "B", "S" };
- c.player = Player.JAVA;
- c.copyright = "NONE";
- item.content = c;
- item.images = new Image[] {
- new Image("h", "J", 1024, 768, Size.LARGE),
- new Image("h", "J", 320, 240, Size.LARGE)
- };
-
- // Ok: let's just do quick comparison (yes/no)...
- ObjectMapper plain = new ObjectMapper();
- ObjectMapper smiley = new ObjectMapper(f);
- String exp = plain.writeValueAsString(item);
- byte[] smile = smiley.writeValueAsBytes(item);
- MediaItem result = smiley.readValue(smile, 0, smile.length, MediaItem.class);
- String actual = plain.writeValueAsString(result);
- assertEquals(exp, actual);
- }
-
- /**
- * Reproducing [JACKSON-561] (and [JACKSON-562])
- */
- public void testIssue562() throws IOException
- {
- JsonFactory factory = new SmileFactory();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- JsonGenerator gen = factory.createJsonGenerator(bos);
- gen.writeStartObject();
- gen.writeFieldName("z_aaaabbbbccccddddee");
- gen.writeString("end");
- gen.writeFieldName("a_aaaabbbbccccddddee");
- gen.writeString("start");
- gen.writeEndObject();
- gen.close();
-
- JsonParser parser = factory.createJsonParser(bos.toByteArray());
- assertToken(JsonToken.START_OBJECT, parser.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals("z_aaaabbbbccccddddee", parser.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, parser.nextToken());
- assertEquals("end", parser.getText());
-
- // This one fails...
- assertToken(JsonToken.FIELD_NAME, parser.nextToken());
- assertEquals("a_aaaabbbbccccddddee", parser.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, parser.nextToken());
- assertEquals("start", parser.getText());
-
- assertToken(JsonToken.END_OBJECT, parser.nextToken());
- }
-
- /**
- * Verification that [JACKSON-564] was fixed.
- */
- public void testIssue564() throws Exception
- {
- JsonFactory factory = new SmileFactory();
-
- ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
- JsonGenerator generator = factory.createJsonGenerator(bos1);
- generator.writeStartObject();
- generator.writeFieldName("query");
- generator.writeStartObject();
- generator.writeFieldName("term");
- generator.writeStartObject();
- generator.writeStringField("doc.payload.test_record_main.string_not_analyzed__s", "foo");
- generator.writeEndObject();
- generator.writeEndObject();
- generator.writeEndObject();
- generator.close();
-
- JsonParser parser = factory.createJsonParser(bos1.toByteArray());
- JsonToken token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- assertEquals("query", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- assertEquals("term", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- assertEquals("doc.payload.test_record_main.string_not_analyzed__s", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.VALUE_STRING, token);
- assertEquals("foo", parser.getText());
- parser.close();
-
- ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
- generator = factory.createJsonGenerator(bos2);
- generator.writeStartObject();
- generator.writeFieldName("query");
- generator.writeStartObject();
- generator.writeFieldName("term");
- generator.writeStartObject();
- // note the difference here, teh field is analyzed2 and not analyzed as in the first doc, as well
- // as having a different value, though don't think it matters
- generator.writeStringField("doc.payload.test_record_main.string_not_analyzed2__s", "bar");
- generator.writeEndObject();
- generator.writeEndObject();
- generator.writeEndObject();
- generator.close();
-
- parser = factory.createJsonParser(bos2.toByteArray());
- token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- assertEquals("query", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- assertEquals("term", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.START_OBJECT, token);
- token = parser.nextToken();
- assertToken(JsonToken.FIELD_NAME, token);
- // here we fail..., seems to be a problem with field caching factory level???
- // since we get the field name of the previous (bos1) document field value (withou the 2)
- assertEquals("doc.payload.test_record_main.string_not_analyzed2__s", parser.getCurrentName());
- token = parser.nextToken();
- assertToken(JsonToken.VALUE_STRING, token);
- assertEquals("bar", parser.getText());
-
- parser.close();
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private final String CHARS_40 = "0123456789012345678901234567890123456789";
-
- private byte[] writeStringValues(boolean enableSharing, int COUNT) throws IOException
- {
- SmileFactory f = new SmileFactory();
- f.configure(SmileGenerator.Feature.WRITE_HEADER, true);
- f.configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, enableSharing);
- ByteArrayOutputStream out = new ByteArrayOutputStream(4000);
- JsonGenerator gen = f.createJsonGenerator(out);
- gen.writeStartArray();
- Random rnd = new Random(COUNT);
- for (int i = 0; i < COUNT; ++i) {
- gen.writeString(generateString(rnd.nextInt()));
- }
- gen.writeEndArray();
- gen.close();
- return out.toByteArray();
- }
-
- private void verifyStringValues(byte[] json, int COUNT) throws IOException
- {
- SmileFactory f = new SmileFactory();
- JsonParser jp = f.createJsonParser(json);
- assertToken(JsonToken.START_ARRAY, jp.nextToken());
- Random rnd = new Random(COUNT);
- for (int i = 0; i < COUNT; ++i) {
- String str = generateString(rnd.nextInt());
- assertToken(JsonToken.VALUE_STRING, jp.nextToken());
- assertEquals(str, jp.getText());
- }
- assertToken(JsonToken.END_ARRAY, jp.nextToken());
- }
-
- private String generateString(int rawNr)
- {
- int nr = rawNr % 1100;
- // Actually, let's try longer ones too
- String str = "some kind of String value we use"+nr;
- if (nr > 900) {
- str += CHARS_40;
- }
- return str;
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileUtil.java.svn-base b/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileUtil.java.svn-base
deleted file mode 100644
index 289c988..0000000
--- a/src/test/java/com/fasterxml/jackson/dataformat/smile/.svn/text-base/TestSmileUtil.java.svn-base
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.codehaus.jackson.smile;
-
-public class TestSmileUtil
- extends main.BaseTest
-{
- /**
- * Verification of helper methods used to handle with zigzag encoding
- */
- public void testZigZagInt()
- {
- // simple encode
- assertEquals(0, SmileUtil.zigzagEncode(0));
- assertEquals(1, SmileUtil.zigzagEncode(-1));
- assertEquals(2, SmileUtil.zigzagEncode(1));
- assertEquals(0xFFFFFFFF, SmileUtil.zigzagEncode(Integer.MIN_VALUE));
- assertEquals(0xFFFFFFFE, SmileUtil.zigzagEncode(Integer.MAX_VALUE));
-
- // simple decode
- assertEquals(0, SmileUtil.zigzagDecode(0));
- assertEquals(-1, SmileUtil.zigzagDecode(1));
- assertEquals(1, SmileUtil.zigzagDecode(2));
- assertEquals(0x7fffFFFF, SmileUtil.zigzagDecode(0xFFFFFFFE));
- assertEquals(Integer.MIN_VALUE, SmileUtil.zigzagDecode(0xFFFFFFFF));
-
- // round-trip
- assertEquals(Integer.MIN_VALUE, SmileUtil.zigzagDecode(SmileUtil.zigzagEncode(Integer.MIN_VALUE)));
- assertEquals(Integer.MAX_VALUE, SmileUtil.zigzagDecode(SmileUtil.zigzagEncode(Integer.MAX_VALUE)));
- }
-
- public void testZigZagLong()
- {
- assertEquals(0L, SmileUtil.zigzagEncode(0L));
- assertEquals(-1L, SmileUtil.zigzagEncode(Long.MIN_VALUE));
- assertEquals(-2L, SmileUtil.zigzagEncode(Long.MAX_VALUE));
-
- assertEquals(Long.MAX_VALUE, SmileUtil.zigzagDecode(-2L));
- assertEquals(Long.MIN_VALUE, SmileUtil.zigzagDecode(-1L));
-
- // round-trip
- assertEquals(Long.MIN_VALUE, SmileUtil.zigzagDecode(SmileUtil.zigzagEncode(Long.MIN_VALUE)));
- assertEquals(Long.MAX_VALUE, SmileUtil.zigzagDecode(SmileUtil.zigzagEncode(Long.MAX_VALUE)));
-}
-}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jackson-dataformat-smile.git
More information about the pkg-java-commits
mailing list