From 5d278676e8f7c677a8d6a6ee87a23a5690061fc5 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 29 Nov 2024 18:57:32 -0800 Subject: [PATCH] Implement #528: Smile read/write features (#529) --- release-notes/VERSION | 2 + .../dataformat/smile/SmileFactory.java | 22 +-- .../dataformat/smile/SmileFactoryBuilder.java | 28 ++-- .../dataformat/smile/SmileGenerator.java | 141 +++--------------- .../jackson/dataformat/smile/SmileParser.java | 44 ------ .../dataformat/smile/SmileParserBase.java | 4 +- .../smile/SmileParserBootstrapper.java | 2 +- .../dataformat/smile/SmileReadFeature.java | 47 ++++++ .../dataformat/smile/SmileWriteFeature.java | 110 ++++++++++++++ .../async/NonBlockingByteArrayParser.java | 4 +- .../smile/databind/SmileMapper.java | 24 +-- .../dataformat/smile/BaseTestForSmile.java | 18 +-- .../smile/SmileFactoryPropertiesTest.java | 24 +-- .../smile/async/AsyncSharedStringsTest.java | 14 +- .../smile/async/RootValuesTest.java | 2 +- .../smile/async/SimpleBinaryParseTest.java | 6 +- .../smile/async/SimpleStringArrayTest.java | 14 +- .../smile/async/StringObjectTest.java | 10 +- .../smile/gen/GeneratorBinaryTest.java | 6 +- .../LenientUnicodeSmileGenerationTest.java | 2 +- .../dataformat/smile/gen/TestGenerator.java | 14 +- .../gen/TestGeneratorLongSharedRefs.java | 4 +- .../smile/gen/TestGeneratorSymbols.java | 9 +- .../smile/mapper/BinaryReadTest.java | 4 +- .../smile/mapper/MapperSimpleReadTest.java | 12 +- .../smile/parse/BasicParserTest.java | 6 +- .../smile/parse/ParserBinaryHandlingTest.java | 9 +- .../smile/parse/ParserLocationTest.java | 3 +- .../smile/parse/ParserSymbolHandlingTest.java | 22 +-- .../smile/parse/SmileNumberParsingTest.java | 9 +- 30 files changed, 314 insertions(+), 302 deletions(-) create mode 100644 smile/src/main/java/tools/jackson/dataformat/smile/SmileReadFeature.java create mode 100644 smile/src/main/java/tools/jackson/dataformat/smile/SmileWriteFeature.java diff --git a/release-notes/VERSION b/release-notes/VERSION index d5f3b610c..1b56530c0 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -25,3 +25,5 @@ implementations) #524: JSTEP-8: rename `CBORGenerator.Feature` as `CBORWriteFeature` #526: JSTEP-8: rename `IonParser.Feature` as `IonReadFeature`, `IonGenerator.Feature` as `IonWriteFeature` +#528: JSTEP-8: rename `SmileParser.Feature` as `SmileReadFeature`, + `SmileGenerator.Feature` as `SmileWriteFeature` diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactory.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactory.java index cbef0646a..32c261407 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactory.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactory.java @@ -50,13 +50,13 @@ public class SmileFactory * Bitfield (set of flags) of all parser features that are enabled * by default. */ - final static int DEFAULT_SMILE_PARSER_FEATURE_FLAGS = SmileParser.Feature.collectDefaults(); + final static int DEFAULT_SMILE_PARSER_FEATURE_FLAGS = SmileReadFeature.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(); + final static int DEFAULT_SMILE_GENERATOR_FEATURE_FLAGS = SmileWriteFeature.collectDefaults(); /* /********************************************************************** @@ -163,14 +163,14 @@ public Version version() { /** * Checked whether specified parser feature is enabled. */ - public final boolean isEnabled(SmileParser.Feature f) { + public final boolean isEnabled(SmileReadFeature f) { return f.enabledIn(_formatReadFeatures); } /** * Check whether specified generator feature is enabled. */ - public final boolean isEnabled(SmileGenerator.Feature f) { + public final boolean isEnabled(SmileWriteFeature f) { return f.enabledIn(_formatWriteFeatures); } @@ -191,13 +191,13 @@ public boolean canUseSchema(FormatSchema schema) { } @Override - public Class getFormatReadFeatureType() { - return SmileParser.Feature.class; + public Class getFormatReadFeatureType() { + return SmileReadFeature.class; } @Override - public Class getFormatWriteFeatureType() { - return SmileGenerator.Feature.class; + public Class getFormatWriteFeatureType() { + return SmileWriteFeature.class; } /* @@ -274,15 +274,15 @@ protected JsonGenerator _createGenerator(ObjectWriteContext writeCtxt, SmileGenerator gen = new SmileGenerator(writeCtxt, ioCtxt, writeCtxt.getStreamWriteFeatures(_streamWriteFeatures), smileFeatures, out); - if (SmileGenerator.Feature.WRITE_HEADER.enabledIn(smileFeatures)) { + if (SmileWriteFeature.WRITE_HEADER.enabledIn(smileFeatures)) { gen.writeHeader(); } else { - if (SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { + if (SmileWriteFeature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { throw new StreamWriteException(gen, "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 (!SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT.enabledIn(smileFeatures)) { + if (!SmileWriteFeature.ENCODE_BINARY_AS_7BIT.enabledIn(smileFeatures)) { throw new StreamWriteException(gen, "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)"); diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactoryBuilder.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactoryBuilder.java index 416382734..00e42525c 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactoryBuilder.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileFactoryBuilder.java @@ -43,65 +43,65 @@ public SmileFactory build() { // // // Parser features - public SmileFactoryBuilder enable(SmileParser.Feature f) { + public SmileFactoryBuilder enable(SmileReadFeature f) { _formatReadFeatures |= f.getMask(); return _this(); } - public SmileFactoryBuilder enable(SmileParser.Feature first, SmileParser.Feature... other) { + public SmileFactoryBuilder enable(SmileReadFeature first, SmileReadFeature... other) { _formatReadFeatures |= first.getMask(); - for (SmileParser.Feature f : other) { + for (SmileReadFeature f : other) { _formatReadFeatures |= f.getMask(); } return _this(); } - public SmileFactoryBuilder disable(SmileParser.Feature f) { + public SmileFactoryBuilder disable(SmileReadFeature f) { _formatReadFeatures &= ~f.getMask(); return _this(); } - public SmileFactoryBuilder disable(SmileParser.Feature first, SmileParser.Feature... other) { + public SmileFactoryBuilder disable(SmileReadFeature first, SmileReadFeature... other) { _formatReadFeatures &= ~first.getMask(); - for (SmileParser.Feature f : other) { + for (SmileReadFeature f : other) { _formatReadFeatures &= ~f.getMask(); } return _this(); } - public SmileFactoryBuilder configure(SmileParser.Feature f, boolean state) { + public SmileFactoryBuilder configure(SmileReadFeature f, boolean state) { return state ? enable(f) : disable(f); } // // // Generator features - public SmileFactoryBuilder enable(SmileGenerator.Feature f) { + public SmileFactoryBuilder enable(SmileWriteFeature f) { _formatWriteFeatures |= f.getMask(); return _this(); } - public SmileFactoryBuilder enable(SmileGenerator.Feature first, SmileGenerator.Feature... other) { + public SmileFactoryBuilder enable(SmileWriteFeature first, SmileWriteFeature... other) { _formatWriteFeatures |= first.getMask(); - for (SmileGenerator.Feature f : other) { + for (SmileWriteFeature f : other) { _formatWriteFeatures |= f.getMask(); } return _this(); } - public SmileFactoryBuilder disable(SmileGenerator.Feature f) { + public SmileFactoryBuilder disable(SmileWriteFeature f) { _formatWriteFeatures &= ~f.getMask(); return _this(); } - public SmileFactoryBuilder disable(SmileGenerator.Feature first, SmileGenerator.Feature... other) { + public SmileFactoryBuilder disable(SmileWriteFeature first, SmileWriteFeature... other) { _formatWriteFeatures &= ~first.getMask(); - for (SmileGenerator.Feature f : other) { + for (SmileWriteFeature f : other) { _formatWriteFeatures &= ~f.getMask(); } return _this(); } - public SmileFactoryBuilder configure(SmileGenerator.Feature f, boolean state) { + public SmileFactoryBuilder configure(SmileWriteFeature f, boolean state) { return state ? enable(f) : disable(f); } } diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileGenerator.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileGenerator.java index 085356431..026913b3f 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileGenerator.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileGenerator.java @@ -21,117 +21,10 @@ public class SmileGenerator extends GeneratorBase { - // @since 2.16 protected final static int DEFAULT_NAME_BUFFER_LENGTH = 64; - // @since 2.16 protected final static int DEFAULT_STRING_VALUE_BUFFER_LENGTH = 64; - /** - * Enumeration that defines all togglable features for Smile generators. - */ - public enum Feature - implements FormatFeature - { - /** - * 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. - *

- * 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). - *

- * 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. This setting is enabled - * by default, however, overhead for binary data (14% size expansion, processing overhead) - * is non-negligible. If no binary data is output, feature has no effect. - *

- * 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" property names during generating - * content or not. If enabled, can replace repeating property 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. - *

- * Since property 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. - *

- * 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), - - /** - * Feature that determines if an invalid surrogate encoding found in the - * incoming String should fail with an exception or silently be output - * as the Unicode 'REPLACEMENT CHARACTER' (U+FFFD) or not; if not, - * an exception will be thrown to indicate invalid content. - *

- * Default value is {@code false} (for backwards compatibility) meaning that - * an invalid surrogate will result in exception ({@code StreamWriteException}). - * - * @since 2.13 - */ - LENIENT_UTF_ENCODING(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()); - } - - @Override public boolean enabledByDefault() { return _defaultState; } - @Override public int getMask() { return _mask; } - @Override public boolean enabledIn(int flags) { return (flags & _mask) != 0; } - } - /** * Helper class used for keeping track of possibly shareable String * references (for property names and/or short String values) @@ -191,7 +84,7 @@ public SharedStringNode(String value, int index, SharedStringNode next) /** * Bit flag composed of bits that indicate which - * {@link tools.jackson.dataformat.smile.SmileGenerator.Feature}s + * {@link tools.jackson.dataformat.smile.SmileWriteFeature}s * are enabled. */ protected int _formatFeatures; @@ -298,7 +191,7 @@ public SmileGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, "Internal encoding buffer length (%d) too short, must be at least %d", _outputEnd, MIN_BUFFER_LENGTH)); } - if (!Feature.CHECK_SHARED_NAMES.enabledIn(smileFeatures)) { + if (!SmileWriteFeature.CHECK_SHARED_NAMES.enabledIn(smileFeatures)) { _seenNames = null; _seenNameCount = -1; } else { @@ -306,7 +199,7 @@ public SmileGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, _seenNameCount = 0; } - if (!Feature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { + if (!SmileWriteFeature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { _seenStringValues = null; _seenStringValueCount = -1; } else { @@ -335,7 +228,7 @@ public SmileGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, "Internal encoding buffer length (%d) too short, must be at least %d", _outputEnd, MIN_BUFFER_LENGTH)); } - if (!Feature.CHECK_SHARED_NAMES.enabledIn(smileFeatures)) { + if (!SmileWriteFeature.CHECK_SHARED_NAMES.enabledIn(smileFeatures)) { _seenNames = null; _seenNameCount = -1; } else { @@ -343,7 +236,7 @@ public SmileGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, _seenNameCount = 0; } - if (!Feature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { + if (!SmileWriteFeature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) { _seenStringValues = null; _seenStringValueCount = -1; } else { @@ -362,13 +255,13 @@ public SmileGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, public JsonGenerator writeHeader() throws JacksonException { int last = HEADER_BYTE_4; - if (Feature.CHECK_SHARED_NAMES.enabledIn(_formatFeatures)) { + if (SmileWriteFeature.CHECK_SHARED_NAMES.enabledIn(_formatFeatures)) { last |= SmileConstants.HEADER_BIT_HAS_SHARED_NAMES; } - if (Feature.CHECK_SHARED_STRING_VALUES.enabledIn(_formatFeatures)) { + if (SmileWriteFeature.CHECK_SHARED_STRING_VALUES.enabledIn(_formatFeatures)) { last |= SmileConstants.HEADER_BIT_HAS_SHARED_STRING_VALUES; } - if (!Feature.ENCODE_BINARY_AS_7BIT.enabledIn(_formatFeatures)) { + if (!SmileWriteFeature.ENCODE_BINARY_AS_7BIT.enabledIn(_formatFeatures)) { last |= SmileConstants.HEADER_BIT_HAS_RAW_BINARY; } _writeBytes(HEADER_BYTE_1, HEADER_BYTE_2, HEADER_BYTE_3, (byte) last); @@ -483,21 +376,21 @@ public JsonGenerator writePropertyId(long id) throws JacksonException { /********************************************************************** */ - public SmileGenerator enable(Feature f) { + public SmileGenerator enable(SmileWriteFeature f) { _formatFeatures |= f.getMask(); return this; } - public SmileGenerator disable(Feature f) { + public SmileGenerator disable(SmileWriteFeature f) { _formatFeatures &= ~f.getMask(); return this; } - public final boolean isEnabled(Feature f) { + public final boolean isEnabled(SmileWriteFeature f) { return (_formatFeatures & f.getMask()) != 0; } - public SmileGenerator configure(Feature f, boolean state) { + public SmileGenerator configure(SmileWriteFeature f, boolean state) { if (state) { enable(f); } else { @@ -1257,7 +1150,7 @@ public JsonGenerator writeBinary(Base64Variant b64variant, byte[] data, int offs return writeNull(); } _verifyValueWrite("write Binary value"); - if (isEnabled(Feature.ENCODE_BINARY_AS_7BIT)) { + if (isEnabled(SmileWriteFeature.ENCODE_BINARY_AS_7BIT)) { _writeByte(TOKEN_MISC_BINARY_7BIT); _write7BitBinaryWithLength(data, offset, len); } else { @@ -1279,7 +1172,7 @@ public int writeBinary(InputStream data, int dataLength) } _verifyValueWrite("write Binary value"); int missing; - if (isEnabled(Feature.ENCODE_BINARY_AS_7BIT)) { + if (isEnabled(SmileWriteFeature.ENCODE_BINARY_AS_7BIT)) { _writeByte(TOKEN_MISC_BINARY_7BIT); byte[] encodingBuffer = _ioContext.allocBase64Buffer(); try { @@ -1853,7 +1746,7 @@ && isEnabled(StreamWriteFeature.AUTO_CLOSE_CONTENT)) { } } boolean wasClosed = _closed; - if (!wasClosed && isEnabled(Feature.WRITE_END_MARKER)) { + if (!wasClosed && isEnabled(SmileWriteFeature.WRITE_END_MARKER)) { _writeByte(BYTE_MARKER_END_OF_CONTENT); } _flushBuffer(); @@ -2143,7 +2036,7 @@ private void _mediumUTF8Encode(String str, int inputPtr, int inputEnd) throws Ja private int _invalidSurrogateStart(int code, byte[] outBuf, int outputPtr) throws JacksonException { - if (isEnabled(Feature.LENIENT_UTF_ENCODING)) { + if (isEnabled(SmileWriteFeature.LENIENT_UTF_ENCODING)) { return _appendReplacementChar(outBuf, outputPtr); } // Will be called in two distinct cases: either first character is @@ -2165,7 +2058,7 @@ private int _invalidSurrogateEnd(int surr1, int surr2, byte[] outBuf, int outputPtr) throws JacksonException { - if (isEnabled(Feature.LENIENT_UTF_ENCODING)) { + if (isEnabled(SmileWriteFeature.LENIENT_UTF_ENCODING)) { return _appendReplacementChar(outBuf, outputPtr); } _reportError(String.format( diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java index d16294dc0..b27a26816 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java @@ -17,54 +17,10 @@ public class SmileParser extends SmileParserBase { - /** - * Enumeration that defines all togglable features for Smile generators. - */ - public enum Feature implements FormatFeature - { - /** - * 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, - * 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()); - } - - @Override public boolean enabledByDefault() { return _defaultState; } - @Override public int getMask() { return _mask; } - @Override public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } - } - /** * Flag to indicate if the JDK version is 11 or later. This can be used in some methods * to choose more optimal behavior. In particular, jdk9+ have different internals for * the String class. - * - * @since 2.14.1 */ private static final boolean JDK11_OR_LATER; static { diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java index f7f63c394..8b958cc2f 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java @@ -38,9 +38,9 @@ public abstract class SmileParserBase extends ParserMinimalBase /** * Bit flag composed of bits that indicate which - * {@link SmileParser.Feature}s are enabled. + * {@link SmileReadFeature}s are enabled. *

- * NOTE: currently the only feature ({@link SmileParser.Feature#REQUIRE_HEADER} + * NOTE: currently the only feature ({@link SmileReadFeature#REQUIRE_HEADER} * takes effect during bootstrapping. */ protected int _formatFeatures; diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBootstrapper.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBootstrapper.java index 0896569a2..105d7e7e1 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBootstrapper.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBootstrapper.java @@ -123,7 +123,7 @@ public SmileParser constructParser(ObjectReadContext readCtxt, hadSig = p.handleSignature(true, true); } - if (!hadSig && SmileParser.Feature.REQUIRE_HEADER.enabledIn(smileFeatures)) { + if (!hadSig && SmileReadFeature.REQUIRE_HEADER.enabledIn(smileFeatures)) { // Ok, first, let's see if it looks like plain JSON... String msg; diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileReadFeature.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileReadFeature.java new file mode 100644 index 000000000..ea00d8489 --- /dev/null +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileReadFeature.java @@ -0,0 +1,47 @@ +package tools.jackson.dataformat.smile; + +import tools.jackson.core.FormatFeature; + +/** + * Enumeration that defines all togglable features for Smile parsers. + *

+ * NOTE: in Jackson 2.x this was named {@code SmileParser.Feature}. + */ +public enum SmileReadFeature implements FormatFeature +{ + /** + * 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, + * settings for content are assumed to be defaults. + */ + REQUIRE_HEADER(true) + ; + + private final boolean _defaultState; + private 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 (SmileReadFeature f : values()) { + if (f.enabledByDefault()) { + flags |= f.getMask(); + } + } + return flags; + } + + private SmileReadFeature(boolean defaultState) { + _defaultState = defaultState; + _mask = (1 << ordinal()); + } + + @Override public boolean enabledByDefault() { return _defaultState; } + @Override public int getMask() { return _mask; } + @Override public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } +} diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileWriteFeature.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileWriteFeature.java new file mode 100644 index 000000000..1f46bdc58 --- /dev/null +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileWriteFeature.java @@ -0,0 +1,110 @@ +package tools.jackson.dataformat.smile; + +import tools.jackson.core.FormatFeature; + +/** + * Enumeration that defines all togglable features for Smile generators. + *

+ * NOTE: in Jackson 2.x this was named {@code AvroGenerator.Feature}. + */ +public enum SmileWriteFeature + implements FormatFeature +{ + /** + * 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. + *

+ * 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 SmileParser#close} is called or not. This can be useful when outputting + * multiple adjacent logical content segments (documents) into single + * physical output unit (file). + *

+ * 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. This setting is enabled + * by default, however, overhead for binary data (14% size expansion, processing overhead) + * is non-negligible. If no binary data is output, feature has no effect. + *

+ * 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" property names during generating + * content or not. If enabled, can replace repeating property 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. + *

+ * Since property 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. + *

+ * 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), + + /** + * Feature that determines if an invalid surrogate encoding found in the + * incoming String should fail with an exception or silently be output + * as the Unicode 'REPLACEMENT CHARACTER' (U+FFFD) or not; if not, + * an exception will be thrown to indicate invalid content. + *

+ * Default value is {@code false} (for backwards compatibility) meaning that + * an invalid surrogate will result in exception ({@code StreamWriteException}). + * + * @since 2.13 + */ + LENIENT_UTF_ENCODING(false), + ; + + private final boolean _defaultState; + private 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 (SmileWriteFeature f : values()) { + if (f.enabledByDefault()) { + flags |= f.getMask(); + } + } + return flags; + } + + private SmileWriteFeature(boolean defaultState) { + _defaultState = defaultState; + _mask = (1 << ordinal()); + } + + @Override public boolean enabledByDefault() { return _defaultState; } + @Override public int getMask() { return _mask; } + @Override public boolean enabledIn(int flags) { return (flags & _mask) != 0; } +} diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java index 71d2eab8b..7550099ea 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java @@ -18,7 +18,7 @@ import tools.jackson.core.util.VersionUtil; import tools.jackson.dataformat.smile.SmileConstants; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; import tools.jackson.dataformat.smile.SmileUtil; public class NonBlockingByteArrayParser @@ -178,7 +178,7 @@ public JsonToken nextToken() throws JacksonException _minorState = MINOR_HEADER_INITIAL; return _finishHeader(0); } - if (SmileParser.Feature.REQUIRE_HEADER.enabledIn(_formatFeatures)) { + if (SmileReadFeature.REQUIRE_HEADER.enabledIn(_formatFeatures)) { _reportMissingHeader(ch); } // otherwise fine, just drop through to next state diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/databind/SmileMapper.java b/smile/src/main/java/tools/jackson/dataformat/smile/databind/SmileMapper.java index 3e47bca98..9e08bdc5c 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/databind/SmileMapper.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/databind/SmileMapper.java @@ -7,8 +7,8 @@ import tools.jackson.databind.cfg.MapperBuilderState; import tools.jackson.dataformat.smile.PackageVersion; import tools.jackson.dataformat.smile.SmileFactory; -import tools.jackson.dataformat.smile.SmileGenerator; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; +import tools.jackson.dataformat.smile.SmileWriteFeature; /** * Specialized {@link ObjectMapper} to use with Smile format backend. @@ -47,21 +47,21 @@ protected MapperBuilderState _saveState() { /****************************************************************** */ - public Builder enable(SmileParser.Feature... features) { - for (SmileParser.Feature f : features) { + public Builder enable(SmileReadFeature... features) { + for (SmileReadFeature f : features) { _formatReadFeatures |= f.getMask(); } return this; } - public Builder disable(SmileParser.Feature... features) { - for (SmileParser.Feature f : features) { + public Builder disable(SmileReadFeature... features) { + for (SmileReadFeature f : features) { _formatReadFeatures &= ~f.getMask(); } return this; } - public Builder configure(SmileParser.Feature feature, boolean state) + public Builder configure(SmileReadFeature feature, boolean state) { if (state) { _formatReadFeatures |= feature.getMask(); @@ -71,21 +71,21 @@ public Builder configure(SmileParser.Feature feature, boolean state) return this; } - public Builder enable(SmileGenerator.Feature... features) { - for (SmileGenerator.Feature f : features) { + public Builder enable(SmileWriteFeature... features) { + for (SmileWriteFeature f : features) { _formatWriteFeatures |= f.getMask(); } return this; } - public Builder disable(SmileGenerator.Feature... features) { - for (SmileGenerator.Feature f : features) { + public Builder disable(SmileWriteFeature... features) { + for (SmileWriteFeature f : features) { _formatWriteFeatures &= ~f.getMask(); } return this; } - public Builder configure(SmileGenerator.Feature feature, boolean state) + public Builder configure(SmileWriteFeature feature, boolean state) { if (state) { _formatWriteFeatures |= feature.getMask(); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/BaseTestForSmile.java b/smile/src/test/java/tools/jackson/dataformat/smile/BaseTestForSmile.java index 3d4d380c5..584000125 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/BaseTestForSmile.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/BaseTestForSmile.java @@ -84,9 +84,9 @@ protected ObjectReader _smileReader() { protected ObjectReader _smileReader(boolean requireHeader) { ObjectReader r = SMILE_MAPPER.reader(); if (requireHeader) { - r = r.with(SmileParser.Feature.REQUIRE_HEADER); + r = r.with(SmileReadFeature.REQUIRE_HEADER); } else { - r = r.without(SmileParser.Feature.REQUIRE_HEADER); + r = r.without(SmileReadFeature.REQUIRE_HEADER); } return r; } @@ -124,9 +124,9 @@ protected SmileFactoryBuilder smileFactoryBuilder(boolean requireHeader, boolean writeHeader, boolean writeEndMarker) { return SmileFactory.builder() - .configure(SmileParser.Feature.REQUIRE_HEADER, requireHeader) - .configure(SmileGenerator.Feature.WRITE_HEADER, writeHeader) - .configure(SmileGenerator.Feature.WRITE_END_MARKER, writeEndMarker); + .configure(SmileReadFeature.REQUIRE_HEADER, requireHeader) + .configure(SmileWriteFeature.WRITE_HEADER, writeHeader) + .configure(SmileWriteFeature.WRITE_END_MARKER, writeEndMarker); } protected byte[] _smileDoc(String json) @@ -138,9 +138,9 @@ protected byte[] _smileDoc(ObjectMapper mapper, String json, boolean writeHeader { ObjectWriter w = mapper.writer(); if (writeHeader) { - w = w.with(SmileGenerator.Feature.WRITE_HEADER); + w = w.with(SmileWriteFeature.WRITE_HEADER); } else { - w = w.without(SmileGenerator.Feature.WRITE_HEADER); + w = w.without(SmileWriteFeature.WRITE_HEADER); } return _smileDoc(w, json); } @@ -186,9 +186,9 @@ protected ObjectWriter _smileWriter() { protected ObjectWriter _smileWriter(boolean addHeader) { ObjectWriter w = SMILE_MAPPER.writer(); if (addHeader) { - w = w.with(SmileGenerator.Feature.WRITE_HEADER); + w = w.with(SmileWriteFeature.WRITE_HEADER); } else { - w = w.without(SmileGenerator.Feature.WRITE_HEADER); + w = w.without(SmileWriteFeature.WRITE_HEADER); } return w; } diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/SmileFactoryPropertiesTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/SmileFactoryPropertiesTest.java index 235e2a7a9..720676541 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/SmileFactoryPropertiesTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/SmileFactoryPropertiesTest.java @@ -22,15 +22,15 @@ public class SmileFactoryPropertiesTest extends BaseTestForSmile public void testFactoryDefaults() { SmileFactory f = new SmileFactory(); - assertEquals(SmileParser.Feature.REQUIRE_HEADER.enabledByDefault(), - f.isEnabled(SmileParser.Feature.REQUIRE_HEADER)); - - assertEquals(SmileGenerator.Feature.WRITE_HEADER.enabledByDefault(), - f.isEnabled(SmileGenerator.Feature.WRITE_HEADER)); - assertEquals(SmileGenerator.Feature.CHECK_SHARED_NAMES.enabledByDefault(), - f.isEnabled(SmileGenerator.Feature.CHECK_SHARED_NAMES)); - assertEquals(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES.enabledByDefault(), - f.isEnabled(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES)); + assertEquals(SmileReadFeature.REQUIRE_HEADER.enabledByDefault(), + f.isEnabled(SmileReadFeature.REQUIRE_HEADER)); + + assertEquals(SmileWriteFeature.WRITE_HEADER.enabledByDefault(), + f.isEnabled(SmileWriteFeature.WRITE_HEADER)); + assertEquals(SmileWriteFeature.CHECK_SHARED_NAMES.enabledByDefault(), + f.isEnabled(SmileWriteFeature.CHECK_SHARED_NAMES)); + assertEquals(SmileWriteFeature.CHECK_SHARED_STRING_VALUES.enabledByDefault(), + f.isEnabled(SmileWriteFeature.CHECK_SHARED_STRING_VALUES)); } public void testFactorySerializable() throws Exception @@ -38,7 +38,7 @@ public void testFactorySerializable() throws Exception // Need to handle this in more detail to ensure freeze/thaw'd instances // are used SmileFactory f0 = SmileFactory.builder() - .enable(SmileGenerator.Feature.WRITE_HEADER) + .enable(SmileWriteFeature.WRITE_HEADER) .build(); ObjectMapper m = new ObjectMapper(f0); byte[] doc = _smileDoc(m, SIMPLE_DOC_AS_JSON, true); @@ -91,8 +91,8 @@ public void testVersions() throws Exception public void testCapabilities() throws Exception { assertTrue(SMILE_F.canHandleBinaryNatively()); - assertEquals(SmileParser.Feature.class, SMILE_F.getFormatReadFeatureType()); - assertEquals(SmileGenerator.Feature.class, SMILE_F.getFormatWriteFeatureType()); + assertEquals(SmileReadFeature.class, SMILE_F.getFormatReadFeatureType()); + assertEquals(SmileWriteFeature.class, SMILE_F.getFormatWriteFeatureType()); } public void testInabilityToReadChars() throws Exception diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/AsyncSharedStringsTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/AsyncSharedStringsTest.java index 1fb7b2f68..69d2215db 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/AsyncSharedStringsTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/AsyncSharedStringsTest.java @@ -82,7 +82,7 @@ public void testSharedNames() throws IOException ObjectReader r = _smileReader(false); ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = _smileWriter(false) - .with(SmileGenerator.Feature.CHECK_SHARED_NAMES) + .with(SmileWriteFeature.CHECK_SHARED_NAMES) .createGenerator(out); gen.writeStartArray(); Random rnd = new Random(COUNT); @@ -134,7 +134,7 @@ public void testSharedStringsInArrays() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = _smileWriter() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartArray(); for (String value : SHARED_SYMBOLS) { @@ -159,7 +159,7 @@ public void testSharedStringsInObject() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = _smileWriter() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartObject(); for (int i = 0; i < SHARED_SYMBOLS.length; ++i) { @@ -186,7 +186,7 @@ public void testSharedStringsInObject() throws IOException public void testSharedStringsMixed() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); - JsonGenerator gen = _smileWriter().with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + JsonGenerator gen = _smileWriter().with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartObject(); @@ -305,7 +305,7 @@ public void testSharedStringsMixed() throws IOException public void testDataBindingAndShared() throws IOException { SmileFactory f = SmileFactory.builder() - .enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); MediaItem item = new MediaItem(); Content c = new Content(); @@ -498,9 +498,9 @@ private byte[] writeStringValues(boolean enableSharing, int COUNT) throws IOExce { ObjectWriter w = _smileWriter(true); if (enableSharing) { - w = w.with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + w = w.with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES); } else { - w = w.without(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + w = w.without(SmileWriteFeature.CHECK_SHARED_STRING_VALUES); } ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = w.createGenerator(out); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/RootValuesTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/RootValuesTest.java index 37d4609dd..08e062a6b 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/RootValuesTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/RootValuesTest.java @@ -9,7 +9,7 @@ public class RootValuesTest extends AsyncTestBase { private final SmileFactory F_REQ_HEADERS = SmileFactory.builder() - .enable(SmileParser.Feature.REQUIRE_HEADER) + .enable(SmileReadFeature.REQUIRE_HEADER) .build(); public void testSimpleRootSequence() throws Exception diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleBinaryParseTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleBinaryParseTest.java index 6c89d2847..bfa83611c 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleBinaryParseTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleBinaryParseTest.java @@ -8,15 +8,15 @@ import tools.jackson.core.JsonToken; import tools.jackson.databind.ObjectWriter; -import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class SimpleBinaryParseTest extends AsyncTestBase { private final ObjectWriter W_RAW = _smileWriter(true) - .without(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT); + .without(SmileWriteFeature.ENCODE_BINARY_AS_7BIT); private final ObjectWriter W_7BIT = _smileWriter(true) - .with(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT); + .with(SmileWriteFeature.ENCODE_BINARY_AS_7BIT); final static int[] SIZES = new int[] { 1, 2, 3, 4, 5, 7, 11, diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java index da8a0c2c7..239ffa1b5 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java @@ -10,8 +10,8 @@ import tools.jackson.databind.ObjectWriter; import tools.jackson.dataformat.smile.SmileFactory; -import tools.jackson.dataformat.smile.SmileGenerator; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; +import tools.jackson.dataformat.smile.SmileWriteFeature; import tools.jackson.dataformat.smile.databind.SmileMapper; public class SimpleStringArrayTest extends AsyncTestBase @@ -29,8 +29,8 @@ public class SimpleStringArrayTest extends AsyncTestBase } private final ObjectWriter WRITE_SHARED = _smileWriter(true) - .withFeatures(SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + .withFeatures(SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES); public void testShortAsciiStrings() throws IOException { @@ -117,9 +117,9 @@ public void testLongAsciiStringsLowStringLimit() throws IOException }; SmileFactory f = SmileFactory.builder() .streamReadConstraints(StreamReadConstraints.builder().maxStringLength(10).build()) - .enable(SmileParser.Feature.REQUIRE_HEADER) - .enable(SmileGenerator.Feature.CHECK_SHARED_NAMES) - .enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileReadFeature.REQUIRE_HEADER) + .enable(SmileWriteFeature.CHECK_SHARED_NAMES) + .enable(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); SmileMapper mapper = new SmileMapper(f); byte[] data = _stringDoc(mapper.writer(), input); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/StringObjectTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/StringObjectTest.java index 983801eeb..596495d8a 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/StringObjectTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/StringObjectTest.java @@ -5,7 +5,7 @@ import tools.jackson.core.JsonToken; import tools.jackson.databind.ObjectWriter; -import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class StringObjectTest extends AsyncTestBase { @@ -33,11 +33,11 @@ private void _testBasicFieldsNames(boolean sharedNames) throws IOException ObjectWriter w = _smileWriter(true); if (sharedNames) { - w = w.withFeatures(SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + w = w.withFeatures(SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES); } else { - w = w.withoutFeatures(SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + w = w.withoutFeatures(SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES); } byte[] data = _smileDoc(w, json); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/gen/GeneratorBinaryTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/gen/GeneratorBinaryTest.java index 6cf560fa2..1a5b511ea 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/gen/GeneratorBinaryTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/gen/GeneratorBinaryTest.java @@ -7,7 +7,7 @@ import tools.jackson.core.*; import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileFactory; -import tools.jackson.dataformat.smile.SmileGenerator.Feature; +import tools.jackson.dataformat.smile.SmileWriteFeature; import tools.jackson.dataformat.smile.testutil.ThrottledInputStream; public class GeneratorBinaryTest extends BaseTestForSmile @@ -47,7 +47,7 @@ private void _testStreamingBinaryPartly(boolean rawBinary, boolean throttle) throws Exception { final SmileFactory f = SmileFactory.builder() - .configure(Feature.ENCODE_BINARY_AS_7BIT, rawBinary) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, rawBinary) .build(); final byte[] INPUT = TEXT4.getBytes("UTF-8"); @@ -89,7 +89,7 @@ private void _testStreamingBinaryPartly(boolean rawBinary, boolean throttle) private void _testStreamingBinary(boolean rawBinary, boolean throttle) throws Exception { final SmileFactory f = SmileFactory.builder() - .configure(Feature.ENCODE_BINARY_AS_7BIT, !rawBinary) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, !rawBinary) .build(); final byte[] INPUT = TEXT4.getBytes("UTF-8"); for (int chunkSize : new int[] { 1, 2, 3, 4, 7, 11, 29, 5000 }) { diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/gen/LenientUnicodeSmileGenerationTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/gen/LenientUnicodeSmileGenerationTest.java index 09c3b32d2..ed9384dc9 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/gen/LenientUnicodeSmileGenerationTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/gen/LenientUnicodeSmileGenerationTest.java @@ -15,7 +15,7 @@ public class LenientUnicodeSmileGenerationTest extends BaseTestForSmile private final SmileMapper MAPPER = smileMapper(); private final ObjectWriter LENIENT_WRITER = MAPPER.writer() - .with(SmileGenerator.Feature.LENIENT_UTF_ENCODING); + .with(SmileWriteFeature.LENIENT_UTF_ENCODING); /** * Test that encoding a String containing invalid surrogates fail with an exception diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGenerator.java b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGenerator.java index d427be933..74d0041f3 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGenerator.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGenerator.java @@ -63,7 +63,7 @@ public void testSimpleLiterals() throws Exception // null, with header and end marker out = new ByteArrayOutputStream(); gen = _smileGenerator(out, true); - gen.enable(SmileGenerator.Feature.WRITE_END_MARKER); + gen.enable(SmileWriteFeature.WRITE_END_MARKER); gen.writeNull(); // header (4 bytes) and boolen (1 byte) assertEquals(5, gen.streamWriteOutputBuffered()); @@ -176,8 +176,8 @@ public void testObjectWithEmptyKey() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); SmileFactory f = smileFactory(false, true, false).rebuild() - .enable(SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); JsonGenerator gen = f.createGenerator(ObjectWriteContext.empty(), out); gen.writeStartObject(); @@ -256,8 +256,8 @@ public void testSharedStrings() throws Exception public void testWithMap() throws Exception { final SmileFactory smileFactory = SmileFactory.builder() - .disable(SmileGenerator.Feature.WRITE_HEADER) - .disable(SmileParser.Feature.REQUIRE_HEADER) + .disable(SmileWriteFeature.WRITE_HEADER) + .disable(SmileReadFeature.REQUIRE_HEADER) .build(); final ObjectMapper smileObjectMapper = new ObjectMapper(smileFactory); final HashMap data = new HashMap(); @@ -288,8 +288,8 @@ private byte[] writeRepeatedString(boolean shared, String value) throws Exceptio { // need header to enable shared string values SmileFactory f = SmileFactory.builder() - .enable(SmileGenerator.Feature.WRITE_HEADER) - .configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, shared) + .enable(SmileWriteFeature.WRITE_HEADER) + .configure(SmileWriteFeature.CHECK_SHARED_STRING_VALUES, shared) .build(); ByteArrayOutputStream out = new ByteArrayOutputStream(); JsonGenerator gen = f.createGenerator(ObjectWriteContext.empty(), out); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorLongSharedRefs.java b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorLongSharedRefs.java index 1fd0604fb..3968cda3d 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorLongSharedRefs.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorLongSharedRefs.java @@ -6,7 +6,7 @@ import tools.jackson.databind.ObjectMapper; import tools.jackson.dataformat.smile.BaseTestForSmile; -import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class TestGeneratorLongSharedRefs extends BaseTestForSmile { @@ -91,7 +91,7 @@ public void testIssue18EndOfDocByteViaStringValues() throws Exception // boolean requireHeader, boolean writeHeader, boolean writeEndMarker ObjectMapper mapper = smileMapper(false, true, false); JsonGenerator generator = mapper.writer() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(byteOut); generator.writeStartArray(); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorSymbols.java b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorSymbols.java index d261a2c0d..be3885a2b 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorSymbols.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/gen/TestGeneratorSymbols.java @@ -7,6 +7,7 @@ import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileFactory; import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class TestGeneratorSymbols extends BaseTestForSmile { @@ -155,9 +156,9 @@ public void testExpandSeenStringValues() throws Exception ByteArrayOutputStream out = new ByteArrayOutputStream(); SmileFactory sf = SmileFactory.builder() - .enable(SmileGenerator.Feature.WRITE_HEADER, - SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileWriteFeature.WRITE_HEADER, + SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); JsonGenerator jg = sf.createGenerator(ObjectWriteContext.empty(), out, null); @@ -215,7 +216,7 @@ public void _testLongNames(boolean shareNames) throws Exception final String VALUE = "11111"; SmileFactory factory = SmileFactory.builder() - .configure(SmileGenerator.Feature.CHECK_SHARED_NAMES, shareNames) + .configure(SmileWriteFeature.CHECK_SHARED_NAMES, shareNames) .build(); ByteArrayOutputStream os = new ByteArrayOutputStream(); JsonGenerator gen = factory.createGenerator(ObjectWriteContext.empty(), os); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/mapper/BinaryReadTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/mapper/BinaryReadTest.java index 5a1cd8a9a..f0b940639 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/mapper/BinaryReadTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/mapper/BinaryReadTest.java @@ -16,7 +16,7 @@ import tools.jackson.databind.node.BinaryNode; import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileFactory; -import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; import tools.jackson.dataformat.smile.databind.SmileMapper; import tools.jackson.dataformat.smile.testutil.ThrottledInputStream; @@ -54,7 +54,7 @@ public Bytes3(byte[] b) { // but also one with "raw" regular binary: private final ObjectMapper MAPPER_RAW = SmileMapper.builder( SmileFactory.builder() - .disable(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT) + .disable(SmileWriteFeature.ENCODE_BINARY_AS_7BIT) .build() ).build(); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/mapper/MapperSimpleReadTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/mapper/MapperSimpleReadTest.java index 484aa6380..bd3b790df 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/mapper/MapperSimpleReadTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/mapper/MapperSimpleReadTest.java @@ -17,8 +17,8 @@ import tools.jackson.databind.exc.MismatchedInputException; import tools.jackson.databind.node.ArrayNode; import tools.jackson.dataformat.smile.BaseTestForSmile; -import tools.jackson.dataformat.smile.SmileGenerator; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; +import tools.jackson.dataformat.smile.SmileWriteFeature; import tools.jackson.dataformat.smile.databind.SmileMapper; public class MapperSimpleReadTest extends BaseTestForSmile @@ -178,15 +178,15 @@ private byte[] _generateHugeDoc() throws IOException public void testStreamingFeaturesViaMapper() throws Exception { SmileMapper mapperWithHeaders = SmileMapper.builder() - .enable(SmileGenerator.Feature.WRITE_HEADER) - .enable(SmileParser.Feature.REQUIRE_HEADER) + .enable(SmileWriteFeature.WRITE_HEADER) + .enable(SmileReadFeature.REQUIRE_HEADER) .build(); byte[] encodedWithHeader = mapperWithHeaders.writeValueAsBytes("foo"); assertEquals(8, encodedWithHeader.length); SmileMapper mapperNoHeaders = SmileMapper.builder() - .disable(SmileGenerator.Feature.WRITE_HEADER) - .disable(SmileParser.Feature.REQUIRE_HEADER) + .disable(SmileWriteFeature.WRITE_HEADER) + .disable(SmileReadFeature.REQUIRE_HEADER) .build(); byte[] encodedNoHeader = mapperNoHeaders.writeValueAsBytes("foo"); assertEquals(4, encodedNoHeader.length); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/BasicParserTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/BasicParserTest.java index b032980ab..595944608 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/BasicParserTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/BasicParserTest.java @@ -381,7 +381,7 @@ public void testInvalidByte() throws IOException public void testNameBoundary() throws IOException { SmileFactory f = smileFactory(true, true, false); - f = f.rebuild().disable(SmileGenerator.Feature.CHECK_SHARED_NAMES).build(); + f = f.rebuild().disable(SmileWriteFeature.CHECK_SHARED_NAMES).build(); // let's create 3 meg docs final int LEN = 3 * 1000 * 1000; @@ -431,8 +431,8 @@ public void testCharacters() throws IOException { // ensure we are using both back-ref types SmileFactory sf = SmileFactory.builder() - .enable(SmileGenerator.Feature.CHECK_SHARED_NAMES, - SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileWriteFeature.CHECK_SHARED_NAMES, + SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(100); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserBinaryHandlingTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserBinaryHandlingTest.java index f97d70ffc..94566dfbd 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserBinaryHandlingTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserBinaryHandlingTest.java @@ -12,6 +12,7 @@ import tools.jackson.dataformat.smile.SmileFactory; import tools.jackson.dataformat.smile.SmileGenerator; import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class ParserBinaryHandlingTest extends BaseTestForSmile { @@ -69,7 +70,7 @@ public void testStreamingEncoded() throws IOException { private void _testBinaryAsRoot(boolean raw) throws IOException { SmileFactory f = SmileFactory.builder() - .configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, !raw) .build(); for (int size : SIZES) { byte[] data = _generateData(size); @@ -100,7 +101,7 @@ private void _testBinaryAsRoot(boolean raw) throws IOException private void _testBinaryAsArray(boolean raw) throws IOException { SmileFactory f = SmileFactory.builder() - .configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, !raw) .build(); for (int size : SIZES) { byte[] data = _generateData(size); @@ -139,7 +140,7 @@ private void _testBinaryAsArray(boolean raw) throws IOException private void _testBinaryAsObject(boolean raw) throws IOException { SmileFactory f = SmileFactory.builder() - .configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, !raw) .build(); for (int size : SIZES) { byte[] data = _generateData(size); @@ -179,7 +180,7 @@ private void _testBinaryAsObject(boolean raw) throws IOException private void _testStreaming(boolean raw) throws IOException { SmileFactory f = SmileFactory.builder() - .configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, !raw) + .configure(SmileWriteFeature.ENCODE_BINARY_AS_7BIT, !raw) .build(); for (int size : SIZES) { byte[] data = _generateData(size); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserLocationTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserLocationTest.java index 0039e8f69..fbdc21c73 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserLocationTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserLocationTest.java @@ -5,6 +5,7 @@ import tools.jackson.core.*; import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileGenerator; +import tools.jackson.dataformat.smile.SmileWriteFeature; public class ParserLocationTest extends BaseTestForSmile @@ -71,7 +72,7 @@ public void testAscendingOffsets() throws Exception ByteArrayOutputStream bytes = new ByteArrayOutputStream(COUNT + 10); SmileGenerator gen = _smileGenerator(bytes, true); - gen.disable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES); + gen.disable(SmileWriteFeature.CHECK_SHARED_STRING_VALUES); gen.writeStartArray(); for (int i = 0; i < COUNT; ++i) { gen.writeString("abc123"); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserSymbolHandlingTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserSymbolHandlingTest.java index 225fbc3d5..1d74db827 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserSymbolHandlingTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/ParserSymbolHandlingTest.java @@ -8,8 +8,8 @@ import tools.jackson.databind.ObjectMapper; import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileFactory; -import tools.jackson.dataformat.smile.SmileGenerator; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; +import tools.jackson.dataformat.smile.SmileWriteFeature; /** * Unit tests for verifying that symbol handling works as planned, including @@ -87,8 +87,8 @@ public void testSharedNames() throws IOException ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = MAPPER.writer() - .without(SmileGenerator.Feature.WRITE_HEADER) - .with(SmileGenerator.Feature.CHECK_SHARED_NAMES) + .without(SmileWriteFeature.WRITE_HEADER) + .with(SmileWriteFeature.CHECK_SHARED_NAMES) .createGenerator(out); gen.writeStartArray(); Random rnd = new Random(COUNT); @@ -104,7 +104,7 @@ public void testSharedNames() throws IOException // And verify JsonParser p = MAPPER.reader() - .without(SmileParser.Feature.REQUIRE_HEADER) + .without(SmileReadFeature.REQUIRE_HEADER) .createParser(json); assertToken(JsonToken.START_ARRAY, p.nextToken()); rnd = new Random(COUNT); @@ -142,7 +142,7 @@ public void testSharedStringsInArrays() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = MAPPER.writer() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartArray(); for (String value : SHARED_SYMBOLS) { @@ -165,7 +165,7 @@ public void testSharedStringsInObject() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = MAPPER.writer() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartObject(); @@ -192,7 +192,7 @@ public void testSharedStringsMixed() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4000); JsonGenerator gen = MAPPER.writer() - .with(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .with(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .createGenerator(out); gen.writeStartObject(); @@ -311,7 +311,7 @@ public void testSharedStringsMixed() throws IOException public void testDataBindingAndShared() throws IOException { SmileFactory f = SmileFactory.builder() - .enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES) + .enable(SmileWriteFeature.CHECK_SHARED_STRING_VALUES) .build(); MediaItem item = new MediaItem(); Content c = new Content(); @@ -495,8 +495,8 @@ public void testCorruptName34() throws Exception private byte[] writeStringValues(boolean enableSharing, int COUNT) throws IOException { SmileFactory f = SmileFactory.builder() - .enable(SmileGenerator.Feature.WRITE_HEADER) - .configure(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES, enableSharing) + .enable(SmileWriteFeature.WRITE_HEADER) + .configure(SmileWriteFeature.CHECK_SHARED_STRING_VALUES, enableSharing) .build(); ByteArrayOutputStream out = new ByteArrayOutputStream(4000); diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingTest.java index 18f39c98b..7cef6bb9c 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingTest.java @@ -11,7 +11,8 @@ import tools.jackson.dataformat.smile.BaseTestForSmile; import tools.jackson.dataformat.smile.SmileFactory; import tools.jackson.dataformat.smile.SmileGenerator; -import tools.jackson.dataformat.smile.SmileParser; +import tools.jackson.dataformat.smile.SmileReadFeature; +import tools.jackson.dataformat.smile.SmileWriteFeature; import tools.jackson.dataformat.smile.databind.SmileMapper; public class SmileNumberParsingTest @@ -437,9 +438,9 @@ public void testVeryBigDecimalWithUnlimitedNumLength() throws IOException SmileFactory f = SmileFactory.builder() .streamReadConstraints(StreamReadConstraints.builder().maxNumberLength(Integer.MAX_VALUE).build()) - .configure(SmileParser.Feature.REQUIRE_HEADER, false) - .configure(SmileGenerator.Feature.WRITE_HEADER, false) - .configure(SmileGenerator.Feature.WRITE_END_MARKER, false) + .configure(SmileReadFeature.REQUIRE_HEADER, false) + .configure(SmileWriteFeature.WRITE_HEADER, false) + .configure(SmileWriteFeature.WRITE_END_MARKER, false) .build(); SmileMapper mapper = new SmileMapper(f); try (JsonParser p = mapper.createParser(data)) {