diff -Nru jackson-dataformat-cbor-2.4.3/debian/changelog jackson-dataformat-cbor-2.7.3/debian/changelog --- jackson-dataformat-cbor-2.4.3/debian/changelog 2014-10-08 19:32:54.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/changelog 2016-04-11 12:23:27.000000000 +0000 @@ -1,3 +1,14 @@ +jackson-dataformat-cbor (2.7.3-1) unstable; urgency=medium + + * Team upload. + * New upstream release + - Refreshed the patches + - New dependency on libjackson2-annotations-java + * Standards-Version updated to 3.9.8 (no changes) + * Use secure Vcs-* fields + + -- Emmanuel Bourg Mon, 11 Apr 2016 14:23:26 +0200 + jackson-dataformat-cbor (2.4.3-1) unstable; urgency=low * Initial release (Closes: #764439) diff -Nru jackson-dataformat-cbor-2.4.3/debian/control jackson-dataformat-cbor-2.7.3/debian/control --- jackson-dataformat-cbor-2.4.3/debian/control 2014-10-08 19:57:48.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/control 2016-04-11 11:50:54.000000000 +0000 @@ -7,17 +7,18 @@ default-jdk, javahelper (>= 0.32), junit4, - libjackson2-core-java (>= 2.4.2), libmaven-bundle-plugin-java, maven-debian-helper (>= 1.6.5), xmlstarlet Build-Depends-Indep: default-jdk-doc, + libjackson2-core-java (>= 2.4.2), libjackson2-core-java-doc, + libjackson2-annotations-java (>= 2.4.2), libjackson2-databind-java (>= 2.4.2), libmaven-javadoc-plugin-java -Standards-Version: 3.9.6 -Vcs-Git: git://anonscm.debian.org/pkg-java/jackson-dataformat-cbor.git -Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-java/jackson-dataformat-cbor.git +Standards-Version: 3.9.8 +Vcs-Git: https://anonscm.debian.org/git/pkg-java/jackson-dataformat-cbor.git +Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/jackson-dataformat-cbor.git Homepage: https://github.com/FasterXML/jackson-dataformat-cbor Package: libjackson2-dataformat-cbor diff -Nru jackson-dataformat-cbor-2.4.3/debian/copyright jackson-dataformat-cbor-2.7.3/debian/copyright --- jackson-dataformat-cbor-2.4.3/debian/copyright 2014-10-08 19:55:50.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/copyright 2016-04-11 12:23:34.000000000 +0000 @@ -3,7 +3,7 @@ Source: https://github.com/FasterXML/jackson-dataformat-cbor Files: * -Copyright: 2014, FasterXML, LLC, Seattle, USA +Copyright: 2014-2016, FasterXML, LLC, Seattle, USA License: Apache-2.0 Files: debian/* diff -Nru jackson-dataformat-cbor-2.4.3/debian/maven.rules jackson-dataformat-cbor-2.7.3/debian/maven.rules --- jackson-dataformat-cbor-2.4.3/debian/maven.rules 2014-10-08 19:55:49.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/maven.rules 2016-04-11 11:51:30.000000000 +0000 @@ -1,7 +1,6 @@ -com.fasterxml.jackson.core jackson-core bundle s/2\..*/2.x/ * * -com.fasterxml.jackson.core jackson-core jar s/2\..*/2.x/ * * -com.fasterxml.jackson.core jackson-databind bundle s/2\..*/2.x/ * * -com.fasterxml.jackson.core jackson-databind jar s/2\..*/2.x/ * * -com.fasterxml.jackson.dataformat jackson-dataformat-cbor bundle s/2\..*/2.x/ * * +com.fasterxml.jackson.core jackson-annotations * s/.*/2.x/ * * +com.fasterxml.jackson.core jackson-core * s/.*/2.x/ * * +com.fasterxml.jackson.core jackson-databind * s/.*/2.x/ * * +com.fasterxml.jackson.dataformat jackson-dataformat-cbor * s/.*/2.x/ * * junit junit jar s/4\..*/4.x/ * * diff -Nru jackson-dataformat-cbor-2.4.3/debian/patches/depend-on-junit.diff jackson-dataformat-cbor-2.7.3/debian/patches/depend-on-junit.diff --- jackson-dataformat-cbor-2.4.3/debian/patches/depend-on-junit.diff 2014-10-08 19:55:49.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/patches/depend-on-junit.diff 2016-04-11 11:42:56.000000000 +0000 @@ -1,9 +1,7 @@ -Index: jackson-dataformat-cbor/pom.xml -=================================================================== ---- jackson-dataformat-cbor.orig/pom.xml -+++ jackson-dataformat-cbor/pom.xml -@@ -59,6 +59,13 @@ encoded data using Jackson abstractions - ${version.jackson.core} +--- a/pom.xml ++++ b/pom.xml +@@ -59,6 +59,13 @@ + jackson-annotations test + diff -Nru jackson-dataformat-cbor-2.4.3/debian/README.source jackson-dataformat-cbor-2.7.3/debian/README.source --- jackson-dataformat-cbor-2.4.3/debian/README.source 2014-10-08 19:29:07.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/README.source 2016-04-11 12:23:45.000000000 +0000 @@ -1,5 +1,5 @@ Information about jackson-dataformat-cbor ------------------------------- +----------------------------------------- This package was debianized using the mh_make command from the maven-debian-helper package. diff -Nru jackson-dataformat-cbor-2.4.3/debian/rules jackson-dataformat-cbor-2.7.3/debian/rules --- jackson-dataformat-cbor-2.4.3/debian/rules 2014-10-08 19:29:56.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/debian/rules 2016-04-11 12:23:38.000000000 +0000 @@ -1,7 +1,5 @@ #!/usr/bin/make -f -export DH_VERBOSE=1 - VERSION_FILE=src/main/java/com/fasterxml/jackson/dataformat/cbor/PackageVersion.java %: diff -Nru jackson-dataformat-cbor-2.4.3/pom.xml jackson-dataformat-cbor-2.7.3/pom.xml --- jackson-dataformat-cbor-2.4.3/pom.xml 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/pom.xml 2016-03-16 03:47:39.000000000 +0000 @@ -4,44 +4,39 @@ com.fasterxml.jackson jackson-parent - 2.4 + 2.7 com.fasterxml.jackson.dataformat jackson-dataformat-cbor - 2.4.3 + 2.7.3 Jackson-dataformat-CBOR bundle Support for reading and writing Concise Binary Object Representation ([CBOR](https://www.rfc-editor.org/info/rfc7049) encoded data using Jackson abstractions (streaming API, data binding, tree model) - http://wiki.fasterxml.com/JacksonForCbor + http://github.com/FasterXML/jackson-dataformat-cbor scm:git:git@github.com:FasterXML/jackson-dataformat-cbor.git scm:git:git@github.com:FasterXML/jackson-dataformat-cbor.git http://github.com/FasterXML/jackson-dataformat-cbor - jackson-dataformat-cbor-2.4.3 + jackson-dataformat-cbor-2.7.3 - 2.4.3 + 2.7.3 + + + 1.6 + 1.6 + com/fasterxml/jackson/dataformat/cbor ${project.groupId}.cbor - ${project.groupId}.cbor.*;version=${project.version} - - com.fasterxml.jackson.core -,com.fasterxml.jackson.core.base -,com.fasterxml.jackson.core.format -,com.fasterxml.jackson.core.io -,com.fasterxml.jackson.core.json -,com.fasterxml.jackson.core.sym -,com.fasterxml.jackson.core.util - @@ -59,6 +54,11 @@ ${version.jackson.core} test + + com.fasterxml.jackson.core + jackson-annotations + test + diff -Nru jackson-dataformat-cbor-2.4.3/README.md jackson-dataformat-cbor-2.7.3/README.md --- jackson-dataformat-cbor-2.4.3/README.md 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/README.md 2016-03-16 03:47:39.000000000 +0000 @@ -10,7 +10,9 @@ As of version 2.4.0, this module is considered stable and production quality. Similar to JSON- and other JSON-like backends, it implementsfull support for all levels (streaming, data-binding, tree model). -[![Build Status](https://fasterxml.ci.cloudbees.com/job/jackson-dataformat-cbor-master/badge/icon)](https://fasterxml.ci.cloudbees.com/job/jackson-dataformat-cbor-master/) +[![Build Status](https://travis-ci.org/FasterXML/jackson-dataformat-cbor.svg?branch=master)](https://travis-ci.org/FasterXML/jackson-dataformat-cbor) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor/) +[![Javadoc](https://javadoc-emblem.rhcloud.com/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor/badge.svg)](http://www.javadoc.io/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor) ### Limitations diff -Nru jackson-dataformat-cbor-2.4.3/release-notes/CREDITS jackson-dataformat-cbor-2.7.3/release-notes/CREDITS --- jackson-dataformat-cbor-2.4.3/release-notes/CREDITS 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/release-notes/CREDITS 2016-03-16 03:47:39.000000000 +0000 @@ -3,9 +3,33 @@ Tatu Saloranta, tatu.saloranta@iki.fi: author -Clinton Gormley clintongormley +Clinton Gormley (clintongormley@github) * Suggested [#5]: Support binary (byte[]) Object keys (assuming UTF-8 encoding) (2.4.3) * Suggested [#6]: Support 'self-describe' CBOR tag (2.4.3) + +mbaril@github) + +* Reported #9, suggested fix, contributed unit test: Infinite loop when trying + to write binary data using CBORGenerator + (2.5.1) + +Steve Gury (stevegury@github) + +* Reported #13, suggested fix: Bug in boundary checking in the CBORParser + (2.6.2) + +Adrien Grand (jpountz@github) + +* Reported #15: CBORParser.getNumberType returns DOUBLE even if the generator + has been fed with a float + (2.6.5) + +philipa@githubL + +* Requested #20: Add a public `finishToken()` + (2.7.2) +* Requested #22: CBORGenerator.copyCurrentStructure() and copyCurrentEvent() do not copy tags + (2.7.2) diff -Nru jackson-dataformat-cbor-2.4.3/release-notes/VERSION jackson-dataformat-cbor-2.7.3/release-notes/VERSION --- jackson-dataformat-cbor-2.4.3/release-notes/VERSION 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/release-notes/VERSION 2016-03-16 03:47:39.000000000 +0000 @@ -1,12 +1,79 @@ Project: jackson-dataformat-cbor -Version: 2.4.3 (04-Oct-2014) - -No changes. ------------------------------------------------------------------------ -=== History: === +=== Releases === ------------------------------------------------------------------------ +2.7.3 (16-Mar-2016) + +No changes since 2.7.2 + +2.7.2 (27-Feb-2016) + +#20: Add a public `finishToken()` + (requested by philipa@github) +#22: CBORGenerator.copyCurrentStructure() and copyCurrentEvent() do not copy tags + (requested by philipa@github) +- Change build to produce JDK6-compatible jar, to allow use on JDK6 runtime + +2.7.1 (02-Feb-2016) + +#19: Fix reported location after non-stream input has been parsed. + (contributed by philipa@github) + +2.7.0 (10-Jan-2016) + +#14: Add support for dynamically changing `CBORGenerator.Feature`s + +2.6.6 (not yet released) + +#18: Correct parsing of zero length byte strings + (reported, fix suggested by philipa@github) + +2.6.5 (19-Jan-2016) + +#15: CBORParser.getNumberType returns DOUBLE even if the generator has been fed with a float + (reported by Adrien G) + +2.6.4 (07-Dec-2015) +2.6.3 (12-Oct-2015) + +No changes since 2.6.2 + +2.6.2 (15-Sep-2015) + +#13: Bug in boundary checking in the CBORParser + (reported by Steve G) + +2.6.1 (09-Aug-2015) +2.6.0 (19-Jul-2015) + +No changes since 2.5 + +2.5.5 (07-Dec-2015) +2.5.4 (09-Jun-2015) +2.5.3 (24-Apr-2015) +2.5.2 (29-Mar-2015) + +No changes since 2.5.1. + +2.5.1 (06-Feb-2015) + +#9: Infinite loop when trying to write binary data using CBORGenerator + (reported by mbaril@github) + +2.5.0 (01-Jan-2015) + +#4: Implement `nextFieldName()` efficiently + +2.4.6 (not yet released) + +2.4.5 (13-Jan-2015) +2.4.4 (24-Nov-2014) +2.4.3 (04-Oct-2014) + +No changes. + 2.4.2 (15-Aug-2014) #5: Support binary (byte[]) Object keys (assuming UTF-8 encoding) diff -Nru jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORFactory.java jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORFactory.java --- jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORFactory.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORFactory.java 2016-03-16 03:47:39.000000000 +0000 @@ -25,8 +25,7 @@ */ public class CBORFactory extends JsonFactory { - // 2.4.1: - private static final long serialVersionUID = 9090274766235983048L; + private static final long serialVersionUID = 1; // 2.6 /* /********************************************************** @@ -146,10 +145,7 @@ // Defaults work fine for this: // public boolean canUseSchema(FormatSchema schema) { } - - /** - * Sub-classes need to override this method (as of 1.8) - */ + @Override public MatchStrength hasFormat(InputAccessor acc) throws IOException { return CBORParserBootstrapper.hasCBORFormat(acc); @@ -160,12 +156,22 @@ /* Capability introspection /********************************************************** */ - + @Override public boolean canHandleBinaryNatively() { return true; } + @Override // since 2.6 + public Class getFormatReadFeatureType() { + return CBORParser.Feature.class; + } + + @Override // since 2.6 + public Class getFormatWriteFeatureType() { + return CBORGenerator.Feature.class; + } + /* /********************************************************** /* Configuration, parser settings @@ -220,8 +226,6 @@ /** * Method for enabling or disabling specified generator feature * (check {@link CBORGenerator.Feature} for list of features) - * - * @since 1.2 */ public final CBORFactory configure(CBORGenerator.Feature f, boolean state) { if (state) { @@ -257,7 +261,7 @@ public final boolean isEnabled(CBORGenerator.Feature f) { return (_formatGeneratorFeatures & f.getMask()) != 0; } - + /* /********************************************************** /* Overridden parser factory methods, new (2.1) @@ -340,9 +344,9 @@ @Override protected CBORParser _createParser(InputStream in, IOContext ctxt) throws IOException { - return new CBORParserBootstrapper(ctxt, in).constructParser(_parserFeatures, - _formatParserFeatures, isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES), - _objectCodec, _rootByteSymbols); + return new CBORParserBootstrapper(ctxt, in).constructParser(_factoryFeatures, + _parserFeatures, _formatParserFeatures, + _objectCodec, _byteSymbolCanonicalizer); } /** @@ -368,9 +372,8 @@ protected CBORParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException { return new CBORParserBootstrapper(ctxt, data, offset, len).constructParser( - _parserFeatures, _formatParserFeatures, - isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES), - _objectCodec, _rootByteSymbols); + _factoryFeatures, _parserFeatures, _formatParserFeatures, + _objectCodec, _byteSymbolCanonicalizer); } @Override diff -Nru jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java --- jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java 2016-03-16 03:47:39.000000000 +0000 @@ -22,7 +22,7 @@ * Let's ensure that we have big enough output buffer because of * safety margins we need for UTF-8 encoding. */ - private final static int BYTE_BUFFER_FOR_OUTPUT = 16000; + final static int BYTE_BUFFER_FOR_OUTPUT = 16000; /** * Longest char chunk we will output is chosen so that it is guaranteed to fit @@ -35,11 +35,12 @@ * This is the worst case length (in bytes) of maximum chunk we ever write. */ private final static int MAX_LONG_STRING_BYTES = (MAX_LONG_STRING_CHARS * 3) + 3; - + /** * Enumeration that defines all togglable features for CBOR generator. */ - public enum Feature { + public enum Feature implements FormatFeature + { /** * Feature that determines whether generator should try to use smallest (size-wise) * integer representation: if true, will use smallest representation that is enough @@ -51,7 +52,7 @@ /** * Feature that determines whether CBOR "Self-Describe Tag" (value 55799, * encoded as 3-byte sequence of 0xD9, 0xD9, 0xF7) should be written - * at the beginnig of document or not. + * at the beginning of document or not. *

* Default value is false meaning that type tag will not be written * at the beginning of a new document. @@ -82,10 +83,10 @@ _defaultState = defaultState; _mask = (1 << ordinal()); } - - public boolean enabledByDefault() { return _defaultState; } - public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } - public int getMask() { return _mask; } + + @Override public boolean enabledByDefault() { return _defaultState; } + @Override public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } + @Override public int getMask() { return _mask; } } /** @@ -99,11 +100,6 @@ * be for encoding 64-character Strings. */ private final static int MIN_BUFFER_LENGTH = (3 * 256) + 2; - - private final static int SURR1_FIRST = 0xD800; - private final static int SURR1_LAST = 0xDBFF; - private final static int SURR2_FIRST = 0xDC00; - private final static int SURR2_LAST = 0xDFFF; private final static long MIN_INT_AS_LONG = (long) Integer.MIN_VALUE; private final static long MAX_INT_AS_LONG = (long) Integer.MAX_VALUE; @@ -120,7 +116,7 @@ /** * Bit flag composed of bits that indicate which - * {@link com.fasterxml.jackson.dataformat.CBORGenerator.Feature}s + * {@link CBORGenerator.Feature}s * are enabled. */ protected int _formatFeatures; @@ -184,10 +180,10 @@ /********************************************************** */ - public CBORGenerator(IOContext ctxt, int jsonFeatures, int formatFeatures, + public CBORGenerator(IOContext ctxt, int stdFeatures, int formatFeatures, ObjectCodec codec, OutputStream out) { - super(jsonFeatures, codec); + super(stdFeatures, codec); _formatFeatures = formatFeatures; _cfgMinimalInts = Feature.WRITE_MINIMAL_INTS.enabledIn(formatFeatures); _ioContext = ctxt; @@ -204,10 +200,17 @@ } } - public CBORGenerator(IOContext ctxt, int jsonFeatures, int formatFeatures, + /** + * Alternative constructor that may be used to feed partially initialized content. + * + * @param outputBuffer Buffer to use for output before flushing to the underlying stream + * @param offset Offset pointing past already buffered content; that is, number of bytes of valid content + * to output, within buffer. + */ + public CBORGenerator(IOContext ctxt, int stdFeatures, int formatFeatures, ObjectCodec codec, OutputStream out, byte[] outputBuffer, int offset, boolean bufferRecyclable) { - super(jsonFeatures, codec); + super(stdFeatures, codec); _formatFeatures = formatFeatures; _cfgMinimalInts = Feature.WRITE_MINIMAL_INTS.enabledIn(formatFeatures); _ioContext = ctxt; @@ -275,7 +278,40 @@ public Object getOutputTarget() { return _out; } + + @Override + public int getOutputBuffered() { + return _outputTail; + } + +// public JsonParser overrideStdFeatures(int values, int mask) + + @Override + public int getFormatFeatures() { + return _formatFeatures; + } + + @Override + public JsonGenerator overrideStdFeatures(int values, int mask) { + int oldState = _features; + int newState = (oldState & ~mask) | (values & mask); + if (oldState != newState) { + _features = newState; + } + return this; + } + @Override + public JsonGenerator overrideFormatFeatures(int values, int mask) { + int oldState = _formatFeatures; + int newState = (_formatFeatures & ~mask) | (values & mask); + if (oldState != newState) { + _formatFeatures = newState; + _cfgMinimalInts = Feature.WRITE_MINIMAL_INTS.enabledIn(newState); + } + return this; + } + /* /********************************************************** /* Overridden methods, write methods @@ -327,7 +363,44 @@ _verifyValueWrite("write String value"); _writeString(value); } + + /* + /********************************************************** + /* Overridden methods, copying with tag-awareness + /********************************************************** + */ + + /** + * Specialize {@link JsonGenerator#copyCurrentEvent} to handle tags. + */ + @Override + public void copyCurrentEvent(JsonParser p) throws IOException { + maybeCopyTag(p); + super.copyCurrentEvent(p); + } + + /** + * Specialize {@link JsonGenerator#copyCurrentStructure} to handle tags. + */ + @Override + public void copyCurrentStructure(JsonParser p) throws IOException { + maybeCopyTag(p); + super.copyCurrentStructure(p); + } + + protected void maybeCopyTag(JsonParser p) throws IOException + { + if (p instanceof CBORParser) { + if (p.hasCurrentToken()) { + final int currentTag = ((CBORParser)p).getCurrentTag(); + if (currentTag != -1) { + writeTag(currentTag); + } + } + } + } + /* /********************************************************** /* Extended API, configuration @@ -409,7 +482,7 @@ public void writeBytes(byte[] data, int offset, int len) throws IOException { _writeBytes(data, offset, len); } - + /* /********************************************************** /* Output method implementations, structural @@ -424,6 +497,27 @@ _writeByte(BYTE_ARRAY_INDEFINITE); } + // TODO: implement this for CBOR + /* + * Unlike with JSON, this method can use slightly optimized version + * since CBOR has a variant that allows embedding length in array + * start marker. But it mostly (or only?) makes sense for small + * arrays, cases where length marker fits within type marker byte; + * otherwise we might as well just use "indefinite" notation. + */ + @Override + public void writeStartArray(int size) throws IOException { + _verifyValueWrite("start an array"); + _writeContext = _writeContext.createChildArrayContext(); + /* + if (size >= 31 || size < 0) { + _writeByte(BYTE_ARRAY_INDEFINITE); + } else { + } + */ + _writeByte(BYTE_ARRAY_INDEFINITE); + } + @Override public final void writeEndArray() throws IOException { @@ -855,7 +949,7 @@ public void close() throws IOException { // First: let's see that we still have buffers... - if (_outputBuffer != null + if ((_outputBuffer != null) && isEnabled(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT)) { while (true) { JsonStreamContext ctxt = getOutputContext(); @@ -1090,21 +1184,23 @@ private final int _encode(int outputPtr, String str, int len) { final byte[] outBuf = _outputBuffer; - int i = 0; final int outputStart = outputPtr; - while (true) { + for (int i = 0; i < len; ++i) { int c = str.charAt(i); if (c > 0x7F) { - break; + return _encode2(i, outputPtr, str, len, outputStart); } outBuf[outputPtr++] = (byte) c; - if (++i >= len) { // done! - return (outputPtr - outputStart); - } } + return (outputPtr - outputStart); + } - // no; non-aSCII stuff, slower loop + private final int _encode2(int i, int outputPtr, String str, int len, + int outputStart) + { + final byte[] outBuf = _outputBuffer; + // no; non-ASCII stuff, slower loop while (i < len) { int c = str.charAt(i++); if (c <= 0x7F) { @@ -1283,7 +1379,7 @@ { while (bytesLeft > 0) { int room = _outputEnd - _outputTail; - if (room < 0) { + if (room <= 0) { _flushBuffer(); room = _outputEnd - _outputTail; } @@ -1352,5 +1448,5 @@ protected UnsupportedOperationException _notSupported() { return new UnsupportedOperationException(); - } + } } diff -Nru jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParserBootstrapper.java jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParserBootstrapper.java --- jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParserBootstrapper.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParserBootstrapper.java 2016-03-16 03:47:39.000000000 +0000 @@ -6,7 +6,7 @@ import com.fasterxml.jackson.core.format.InputAccessor; import com.fasterxml.jackson.core.format.MatchStrength; import com.fasterxml.jackson.core.io.IOContext; -import com.fasterxml.jackson.core.sym.BytesToNameCanonicalizer; +import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer; /** * Simple bootstrapper version used with CBOR format parser. @@ -80,14 +80,12 @@ _bufferRecyclable = false; } - public CBORParser constructParser(int generalParserFeatures, int formatFeatures, - boolean internNames, - ObjectCodec codec, BytesToNameCanonicalizer rootByteSymbols) + public CBORParser constructParser(int factoryFeatures, + int generalParserFeatures, int formatFeatures, + ObjectCodec codec, ByteQuadsCanonicalizer rootByteSymbols) throws IOException, JsonParseException { - // Replace with non-deprecated method in 2.5; leave this for 2.4 for improved - // backwards compatibility - BytesToNameCanonicalizer can = rootByteSymbols.makeChild(true, internNames); + ByteQuadsCanonicalizer can = rootByteSymbols.makeChild(factoryFeatures); // We just need a single byte to recognize possible "empty" document. ensureLoaded(1); CBORParser p = new CBORParser(_context, generalParserFeatures, formatFeatures, diff -Nru jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java --- jackson-dataformat-cbor-2.4.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java 2016-03-16 03:47:39.000000000 +0000 @@ -11,21 +11,20 @@ import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.io.NumberInput; import com.fasterxml.jackson.core.json.DupDetector; -import com.fasterxml.jackson.core.sym.BytesToNameCanonicalizer; -import com.fasterxml.jackson.core.sym.Name; +import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer; import com.fasterxml.jackson.core.util.ByteArrayBuilder; import com.fasterxml.jackson.core.util.TextBuffer; public final class CBORParser extends ParserMinimalBase { + private final static byte[] NO_BYTES = new byte[0]; + /** * Enumeration that defines all togglable features for CBOR generators. */ - public enum Feature { - /** - * Placeholder before any format-specific features are added. - */ - BOGUS(false) + public enum Feature implements FormatFeature + { +// BOGUS(false) ; final boolean _defaultState; @@ -51,8 +50,9 @@ _mask = (1 << ordinal()); } - public boolean enabledByDefault() { return _defaultState; } - public int getMask() { return _mask; } + @Override public boolean enabledByDefault() { return _defaultState; } + @Override public int getMask() { return _mask; } + @Override public boolean enabledIn(int flags) { return (flags & _mask) != 0; } } private final static Charset UTF8 = Charset.forName("UTF-8"); @@ -75,7 +75,7 @@ * Codec used for data binding when (if) requested. */ protected ObjectCodec _objectCodec; - + /* /********************************************************** /* Generic I/O state @@ -268,7 +268,7 @@ * Helper variables used when dealing with chunked content. */ private int _chunkLeft, _chunkEnd; - + /* /********************************************************** /* Symbol handling, decoding @@ -278,8 +278,8 @@ /** * Symbol table that contains field names encountered so far */ - final protected BytesToNameCanonicalizer _symbols; - + final protected ByteQuadsCanonicalizer _symbols; + /** * Temporary buffer used for name parsing. */ @@ -288,7 +288,7 @@ /** * Quads used for hash calculation */ - protected int _quad1, _quad2; + protected int _quad1, _quad2, _quad3; /* /********************************************************** @@ -306,8 +306,9 @@ // And then floating point types - final protected static int NR_DOUBLE = 0x008; - final protected static int NR_BIGDECIMAL = 0x0010; + final protected static int NR_FLOAT = 0x008; + final protected static int NR_DOUBLE = 0x010; + final protected static int NR_BIGDECIMAL = 0x0020; // Also, we need some numeric constants @@ -356,13 +357,14 @@ protected int _numberInt; protected long _numberLong; + protected float _numberFloat; protected double _numberDouble; // And then object types protected BigInteger _numberBigInt; protected BigDecimal _numberBigDecimal; - + /* /********************************************************** /* Life-cycle @@ -370,8 +372,7 @@ */ public CBORParser(IOContext ctxt, int parserFeatures, int cborFeatures, - ObjectCodec codec, - BytesToNameCanonicalizer sym, + ObjectCodec codec, ByteQuadsCanonicalizer sym, InputStream in, byte[] inputBuffer, int start, int end, boolean bufferRecyclable) { @@ -417,6 +418,22 @@ /* /********************************************************** + /* Configuration + /********************************************************** + */ + +// public JsonParser overrideStdFeatures(int values, int mask) + + @Override + public int getFormatFeatures() { + // No parser features, yet + return 0; + } + + //public JsonParser overrideFormatFeatures(int values, int mask) { + + /* + /********************************************************** /* Extended API /********************************************************** */ @@ -432,7 +449,7 @@ public int getCurrentTag() { return _tagValue; } - + /* /********************************************************** /* Abstract impls @@ -490,7 +507,6 @@ @Override public String getCurrentName() throws IOException { - // [JACKSON-395]: start markers require information from parent if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { CBORReadContext parent = _parsingContext.getParent(); return parent.getCurrentName(); @@ -733,16 +749,14 @@ case 25: // 16-bit float... // As per [http://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript] { - float f = (float) _decodeHalfSizeFloat(); - _numberDouble = (double) f; - _numTypesValid = NR_DOUBLE; + _numberFloat = (float) _decodeHalfSizeFloat(); + _numTypesValid = NR_FLOAT; } return (_currToken = JsonToken.VALUE_NUMBER_FLOAT); case 26: // Float32 { - float f = Float.intBitsToFloat(_decode32Bits()); - _numberDouble = (double) f; - _numTypesValid = NR_DOUBLE; + _numberFloat = Float.intBitsToFloat(_decode32Bits()); + _numTypesValid = NR_FLOAT; } return (_currToken = JsonToken.VALUE_NUMBER_FLOAT); case 27: // Float64 @@ -808,6 +822,19 @@ } return String.valueOf(1); } + + // @since 2.7.2 -- will be added in `JsonParser` in 2.8 + // see [dataformat-cbor#20] + /** + * Method for forcing full read of current token, even if it might otherwise + * only be read if data is accessed via {@link #getText} and similar methods. + */ + public void finishToken() throws IOException + { + if (_tokenIncomplete) { + _finishToken(); + } + } // base impl is fine: //public String getCurrentName() throws IOException @@ -826,30 +853,316 @@ /********************************************************** */ - /* @Override public boolean nextFieldName(SerializableString str) throws IOException { // Two parsing modes; can only succeed if expecting field name, so handle that first: if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - // ... + _numTypesValid = NR_UNKNOWN; + if (_tokenIncomplete) { + _skipIncomplete(); + } + _tokenInputTotal = _currInputProcessed + _inputPtr; + _binaryValue = null; + _tagValue = -1; + // completed the whole Object? + if (!_parsingContext.expectMoreValues()) { + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_OBJECT; + return false; + } + byte[] nameBytes = str.asQuotedUTF8(); + final int byteLen = nameBytes.length; + // fine; require room for up to 2-byte marker, data itself + int ptr = _inputPtr; + if ((ptr + byteLen + 1) < _inputEnd) { + final int ch = _inputBuffer[ptr++]; + // only handle usual textual type + if (((ch >> 5) & 0x7) == CBORConstants.MAJOR_TYPE_TEXT) { + int lenMarker = ch & 0x1F; + if (lenMarker <= 24) { + if (lenMarker == 23) { + lenMarker = _inputBuffer[ptr++] & 0xFF; + } + if (lenMarker == byteLen) { + int i = 0; + while (true) { + if (i == lenMarker) { + _inputPtr = ptr+i; + _parsingContext.setCurrentName(str.getValue()); + _currToken = JsonToken.FIELD_NAME; + return true; + } + if (nameBytes[i] != _inputBuffer[ptr+i]) { + break; + } + ++i; + } + } + } + } + } + } // otherwise just fall back to default handling; should occur rarely return (nextToken() == JsonToken.FIELD_NAME) && str.getValue().equals(getCurrentName()); } - */ - /* + @Override + public String nextFieldName() throws IOException + { + if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { + _numTypesValid = NR_UNKNOWN; + if (_tokenIncomplete) { + _skipIncomplete(); + } + _tokenInputTotal = _currInputProcessed + _inputPtr; + _binaryValue = null; + _tagValue = -1; + // completed the whole Object? + if (!_parsingContext.expectMoreValues()) { + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_OBJECT; + return null; + } + // inlined "_decodeFieldName()" + + if (_inputPtr >= _inputEnd) { + loadMoreGuaranteed(); + } + final int ch = _inputBuffer[_inputPtr++]; + final int type = ((ch >> 5) & 0x7); + + // offline non-String cases, as they are expected to be rare + if (type != CBORConstants.MAJOR_TYPE_TEXT) { + if (ch == -1) { // end-of-object, common + if (!_parsingContext.hasExpectedLength()) { + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_OBJECT; + return null; + } + _reportUnexpectedBreak(); + } + _decodeNonStringName(ch); + _currToken = JsonToken.FIELD_NAME; + return getText(); + } + final int lenMarker = ch & 0x1F; + String name; + if (lenMarker <= 23) { + if (lenMarker == 0) { + name = ""; + } else { + name = _findDecodedFromSymbols(lenMarker); + if (name != null) { + _inputPtr += lenMarker; + } else { + name = _decodeShortName(lenMarker); + name = _addDecodedToSymbols(lenMarker, name); + } + } + } else { + final int actualLen = _decodeExplicitLength(lenMarker); + if (actualLen < 0) { + name = _decodeChunkedName(); + } else { + name = _decodeLongerName(actualLen); + } + } + _parsingContext.setCurrentName(name); + _currToken = JsonToken.FIELD_NAME; + return name; + } + // otherwise just fall back to default handling; should occur rarely + return (nextToken() == JsonToken.FIELD_NAME) ? getCurrentName() : null; + } + @Override public String nextTextValue() throws IOException { - // can't get text value if expecting name, so - if (!_parsingContext.inObject() || _currToken == JsonToken.FIELD_NAME) { + _numTypesValid = NR_UNKNOWN; + if (_tokenIncomplete) { + _skipIncomplete(); + } + _tokenInputTotal = _currInputProcessed + _inputPtr; + _binaryValue = null; + _tagValue = -1; + + if (_parsingContext.inObject()) { + if (_currToken != JsonToken.FIELD_NAME) { + _tagValue = -1; + // completed the whole Object? + if (!_parsingContext.expectMoreValues()) { + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_OBJECT; + return null; + } + _currToken = _decodeFieldName(); + return null; + } + } else { + if (!_parsingContext.expectMoreValues()) { + _tagValue = -1; + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_ARRAY; + return null; + } + } + if (_inputPtr >= _inputEnd) { + if (!loadMore()) { + _handleCBOREOF(); + return null; + } + } + int ch = _inputBuffer[_inputPtr++]; + int type = (ch >> 5) & 0x7; + + // One special case: need to consider tag as prefix first: + if (type == 6) { + _tagValue = Integer.valueOf(_decodeTag(ch & 0x1F)); + if (_inputPtr >= _inputEnd) { + if (!loadMore()) { + _handleCBOREOF(); + return null; + } + } + ch = _inputBuffer[_inputPtr++]; + type = (ch >> 5) & 0x7; + } else { + _tagValue = -1; + } + + final int lowBits = ch & 0x1F; + switch (type) { + case 0: // positive int + _numTypesValid = NR_INT; + if (lowBits <= 23) { + _numberInt = lowBits; + } else { + switch (lowBits - 24) { + case 0: + _numberInt = _decode8Bits(); + break; + case 1: + _numberInt = _decode16Bits(); + break; + case 2: + _numberInt = _decode32Bits(); + break; + case 3: + _numberLong = _decode64Bits(); + _numTypesValid = NR_LONG; + break; + default: + _invalidToken(ch); + } + } + _currToken = JsonToken.VALUE_NUMBER_INT; + return null; + case 1: // negative int + _numTypesValid = NR_INT; + if (lowBits <= 23) { + _numberInt = -lowBits - 1; + } else { + switch (lowBits - 24) { + case 0: + _numberInt = -_decode8Bits() - 1; + break; + case 1: + _numberInt = -_decode16Bits() - 1; + break; + case 2: + _numberInt = -_decode32Bits() - 1; + break; + case 3: + _numberLong = -_decode64Bits() - 1L; + _numTypesValid = NR_LONG; + break; + default: + _invalidToken(ch); + } + } + _currToken = JsonToken.VALUE_NUMBER_INT; + return null; + + case 2: // byte[] + _typeByte = ch; + _tokenIncomplete = true; + _currToken = JsonToken.VALUE_EMBEDDED_OBJECT; + return null; + + case 3: // String + _typeByte = ch; + _tokenIncomplete = true; + _currToken = JsonToken.VALUE_STRING; + return _finishTextToken(ch); + + case 4: // Array + _currToken = JsonToken.START_ARRAY; + { + int len = _decodeExplicitLength(lowBits); + _parsingContext = _parsingContext.createChildArrayContext(len); + } + return null; + + case 5: // Object + _currToken = JsonToken.START_OBJECT; + { + int len = _decodeExplicitLength(lowBits); + _parsingContext = _parsingContext.createChildObjectContext(len); + } + return null; + + case 6: // another tag; not allowed + _reportError("Multiple tags not allowed per value (first tag: "+_tagValue+")"); + + default: // misc: tokens, floats + switch (lowBits) { + case 20: + _currToken = JsonToken.VALUE_FALSE; + return null; + case 21: + _currToken = JsonToken.VALUE_TRUE; + return null; + case 22: + _currToken = JsonToken.VALUE_NULL; + return null; + case 25: // 16-bit float... + // As per [http://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript] + { + _numberFloat = _decodeHalfSizeFloat(); + _numTypesValid = NR_FLOAT; + } + _currToken = JsonToken.VALUE_NUMBER_FLOAT; + return null; + case 26: // Float32 + { + _numberFloat = Float.intBitsToFloat(_decode32Bits()); + _numTypesValid = NR_FLOAT; + } + _currToken = JsonToken.VALUE_NUMBER_FLOAT; + return null; + case 27: // Float64 + _numberDouble = Double.longBitsToDouble(_decode64Bits()); + _numTypesValid = NR_DOUBLE; + _currToken = JsonToken.VALUE_NUMBER_FLOAT; + return null; + case 31: // Break + if (_parsingContext.inArray()) { + if (!_parsingContext.hasExpectedLength()) { + _parsingContext = _parsingContext.getParent(); + _currToken = JsonToken.END_ARRAY; + return null; + } + } + // Object end-marker can't occur here + _reportUnexpectedBreak(); + } + _invalidToken(ch); } // otherwise fall back to generic handling: return (nextToken() == JsonToken.VALUE_STRING) ? getText() : null; } - */ @Override public int nextIntValue(int defaultValue) throws IOException @@ -881,7 +1194,7 @@ return null; } } - + /* /********************************************************** /* Public API, access to token information, text @@ -897,13 +1210,15 @@ @Override public String getText() throws IOException { + JsonToken t = _currToken; if (_tokenIncomplete) { - _finishToken(); + if (t == JsonToken.VALUE_STRING) { + return _finishTextToken(_typeByte); + } } - if (_currToken == JsonToken.VALUE_STRING) { + if (t == JsonToken.VALUE_STRING) { return _textBuffer.contentsAsString(); } - JsonToken t = _currToken; if (t == null) { // null only before/after document return null; } @@ -972,11 +1287,18 @@ @Override public String getValueAsString() throws IOException { - if (_currToken != JsonToken.VALUE_STRING) { - if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { - return null; + // inlined 'getText()' for common case of having String + if (_tokenIncomplete) { + if (_currToken == JsonToken.VALUE_STRING) { + return _finishTextToken(_typeByte); } } + if (_currToken == JsonToken.VALUE_STRING) { + return _textBuffer.contentsAsString(); + } + if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { + return null; + } return getText(); } @@ -990,7 +1312,7 @@ } return getText(); } - + /* /********************************************************** /* Public API, access to token information, binary @@ -1005,7 +1327,7 @@ } 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"); + _reportError("Current token ("+getCurrentToken()+") not VALUE_EMBEDDED_OBJECT, can not access as binary"); } return _binaryValue; } @@ -1027,7 +1349,7 @@ { 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"); + _reportError("Current token ("+getCurrentToken()+") not VALUE_EMBEDDED_OBJECT, can not access as binary"); } if (!_tokenIncomplete) { // someone already decoded or read if (_binaryValue == null) { // if this method called twice in a row @@ -1071,7 +1393,7 @@ _tokenIncomplete = false; return total; } - + /* /********************************************************** /* Numeric accessors of public API @@ -1105,10 +1427,13 @@ if ((_numTypesValid & NR_BIGDECIMAL) != 0) { return _numberBigDecimal; } - if ((_numTypesValid & NR_DOUBLE) == 0) { // sanity check + if ((_numTypesValid & NR_DOUBLE) != 0) { + return _numberDouble; + } + if ((_numTypesValid & NR_FLOAT) == 0) { // sanity check _throwInternal(); } - return _numberDouble; + return _numberFloat; } @Override @@ -1136,7 +1461,10 @@ if ((_numTypesValid & NR_BIGDECIMAL) != 0) { return NumberType.BIG_DECIMAL; } - return NumberType.DOUBLE; + if ((_numTypesValid & NR_DOUBLE) != 0) { + return NumberType.DOUBLE; + } + return NumberType.FLOAT; } @Override @@ -1184,18 +1512,23 @@ @Override public float getFloatValue() throws IOException { - double value = getDoubleValue(); - /* 22-Jan-2009, tatu: Bounds/range checks would be tricky - * here, so let's not bother even trying... - */ + if ((_numTypesValid & NR_FLOAT) == 0) { + if (_numTypesValid == NR_UNKNOWN) { + _checkNumericValue(NR_FLOAT); + } + if ((_numTypesValid & NR_FLOAT) == 0) { + convertNumberToFloat(); + } + } + // Bounds/range checks would be tricky here, so let's not bother even trying... /* if (value < -Float.MAX_VALUE || value > MAX_FLOAT_D) { _reportError("Numeric value ("+getText()+") out of range of Java float"); } */ - return (float) value; + return _numberFloat; } - + @Override public double getDoubleValue() throws IOException { @@ -1236,7 +1569,7 @@ if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) { return; } - _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); + _reportError("Current token ("+getCurrentToken()+") not numeric, can not use numeric value accessors"); } protected void convertNumberToInt() throws IOException @@ -1261,6 +1594,11 @@ reportOverflowInt(); } _numberInt = (int) _numberDouble; + } else if ((_numTypesValid & NR_FLOAT) != 0) { + if (_numberFloat < MIN_INT_D || _numberFloat > MAX_INT_D) { + reportOverflowInt(); + } + _numberInt = (int) _numberFloat; } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { if (BD_MIN_INT.compareTo(_numberBigDecimal) > 0 || BD_MAX_INT.compareTo(_numberBigDecimal) < 0) { @@ -1284,11 +1622,15 @@ } _numberLong = _numberBigInt.longValue(); } else if ((_numTypesValid & NR_DOUBLE) != 0) { - // Need to check boundaries if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) { reportOverflowLong(); } _numberLong = (long) _numberDouble; + } else if ((_numTypesValid & NR_FLOAT) != 0) { + if (_numberFloat < MIN_LONG_D || _numberFloat > MAX_LONG_D) { + reportOverflowInt(); + } + _numberLong = (long) _numberFloat; } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { if (BD_MIN_LONG.compareTo(_numberBigDecimal) > 0 || BD_MAX_LONG.compareTo(_numberBigDecimal) < 0) { @@ -1312,11 +1654,33 @@ _numberBigInt = BigInteger.valueOf(_numberInt); } else if ((_numTypesValid & NR_DOUBLE) != 0) { _numberBigInt = BigDecimal.valueOf(_numberDouble).toBigInteger(); + } else if ((_numTypesValid & NR_FLOAT) != 0) { + _numberBigInt = BigDecimal.valueOf(_numberFloat).toBigInteger(); } else { _throwInternal(); } _numTypesValid |= NR_BIGINT; } + + protected void convertNumberToFloat() throws IOException + { + // Note: this MUST start with more accurate representations, since we don't know which + // value is the original one (others get generated when requested) + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + _numberFloat = _numberBigDecimal.floatValue(); + } else if ((_numTypesValid & NR_BIGINT) != 0) { + _numberFloat = _numberBigInt.floatValue(); + } else if ((_numTypesValid & NR_DOUBLE) != 0) { + _numberFloat = (float) _numberDouble; + } else if ((_numTypesValid & NR_LONG) != 0) { + _numberFloat = (float) _numberLong; + } else if ((_numTypesValid & NR_INT) != 0) { + _numberFloat = (float) _numberInt; + } else { + _throwInternal(); + } + _numTypesValid |= NR_FLOAT; + } protected void convertNumberToDouble() throws IOException { @@ -1324,6 +1688,8 @@ // value is the original one (others get generated when requested) if ((_numTypesValid & NR_BIGDECIMAL) != 0) { _numberDouble = _numberBigDecimal.doubleValue(); + } else if ((_numTypesValid & NR_FLOAT) != 0) { + _numberDouble = (double) _numberFloat; } else if ((_numTypesValid & NR_BIGINT) != 0) { _numberDouble = _numberBigInt.doubleValue(); } else if ((_numTypesValid & NR_LONG) != 0) { @@ -1340,7 +1706,7 @@ { // Note: this MUST start with more accurate representations, since we don't know which // value is the original one (others get generated when requested) - if ((_numTypesValid & NR_DOUBLE) != 0) { + if ((_numTypesValid & (NR_DOUBLE | NR_FLOAT)) != 0) { // Let's parse from String representation, to avoid rounding errors that //non-decimal floating operations would incur _numberBigDecimal = NumberInput.parseBigDecimal(getText()); @@ -1415,7 +1781,46 @@ _finishShortText(len); } - private final void _finishShortText(int len) throws IOException + /** + * @since 2.6 + */ + protected String _finishTextToken(int ch) throws IOException + { + _tokenIncomplete = false; + final int type = ((ch >> 5) & 0x7); + ch &= 0x1F; + + // sanity check + if (type != CBORConstants.MAJOR_TYPE_TEXT) { + // should never happen so + _throwInternal(); + } + + // String value, decode + final int len = _decodeExplicitLength(ch); + + if (len <= 0) { + if (len == 0) { + _textBuffer.resetWithEmpty(); + return ""; + } + _finishChunkedText(); + return _textBuffer.contentsAsString(); + } + if (len > (_inputEnd - _inputPtr)) { + // or if not, could we read? + if (len >= _inputBuffer.length) { + // If not enough space, need handling similar to chunked + _finishLongText(len); + return _textBuffer.contentsAsString(); + } + _loadToHaveAtLeast(len); + } + // offline for better optimization + return _finishShortText(len); + } + + private final String _finishShortText(int len) throws IOException { char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); if (outBuf.length < len) { // one minor complication @@ -1425,26 +1830,22 @@ int outPtr = 0; int inPtr = _inputPtr; _inputPtr += len; - final int[] codes = UTF8_UNIT_CODES; final byte[] inputBuf = _inputBuffer; // Let's actually do a tight loop for ASCII first: final int end = inPtr + len; - while (true) { - int i = inputBuf[inPtr] & 0xFF; - // tight(er) loop for ASCII - if (codes[i] != 0) { - break; - } + int i; + while ((i = inputBuf[inPtr]) >= 0) { outBuf[outPtr++] = (char) i; if (++inPtr == end) { - _textBuffer.setCurrentLength(outPtr); - return; + return _textBuffer.setCurrentAndReturn(outPtr); } } + + final int[] codes = UTF8_UNIT_CODES; do { - int i = inputBuf[inPtr++] & 0xFF; + i = inputBuf[inPtr++] & 0xFF; switch (codes[i]) { case 0: break; @@ -1471,7 +1872,7 @@ } outBuf[outPtr++] = (char) i; } while (inPtr < end); - _textBuffer.setCurrentLength(outPtr); + return _textBuffer.setCurrentAndReturn(outPtr); } private final void _finishLongText(int len) throws IOException @@ -1692,6 +2093,9 @@ { // First, simple: non-chunked if (len >= 0) { + if (len == 0) { + return NO_BYTES; + } byte[] b = new byte[len]; if (_inputPtr >= _inputEnd) { loadMoreGuaranteed(); @@ -1772,9 +2176,8 @@ if (lenMarker == 0) { name = ""; } else { - Name n = _findDecodedFromSymbols(lenMarker); - if (n != null) { - name = n.getName(); + name = _findDecodedFromSymbols(lenMarker); + if (name != null) { _inputPtr += lenMarker; } else { name = _decodeShortName(lenMarker); @@ -1816,8 +2219,7 @@ } outBuf[outPtr++] = (char) i; if (++inPtr == end) { - _textBuffer.setCurrentLength(outPtr); - return _textBuffer.contentsAsString(); + return _textBuffer.setCurrentAndReturn(outPtr); } } @@ -1852,8 +2254,7 @@ } outBuf[outPtr++] = (char) i; } - _textBuffer.setCurrentLength(outPtr); - return _textBuffer.contentsAsString(); + return _textBuffer.setCurrentAndReturn(outPtr); } private final String _decodeLongerName(int len) throws IOException @@ -1868,12 +2269,12 @@ } _loadToHaveAtLeast(len); } - Name n = _findDecodedFromSymbols(len); - if (n != null) { + String name = _findDecodedFromSymbols(len); + if (name != null) { _inputPtr += len; - return n.getName(); + return name; } - String name = _decodeShortName(len); + name = _decodeShortName(len); return _addDecodedToSymbols(len, name); } @@ -1913,7 +2314,7 @@ _parsingContext.setCurrentName(name); } - private final Name _findDecodedFromSymbols(int len) throws IOException + private final String _findDecodedFromSymbols(final int len) throws IOException { if ((_inputEnd - _inputPtr) < len) { _loadToHaveAtLeast(len); @@ -1923,11 +2324,11 @@ int inPtr = _inputPtr; final byte[] inBuf = _inputBuffer; int q = inBuf[inPtr] & 0xFF; - if (--len > 0) { + if (len > 1) { q = (q << 8) + (inBuf[++inPtr] & 0xFF); - if (--len > 0) { + if (len > 2) { q = (q << 8) + (inBuf[++inPtr] & 0xFF); - if (--len > 0) { + if (len > 3) { q = (q << 8) + (inBuf[++inPtr] & 0xFF); } } @@ -1935,24 +2336,25 @@ _quad1 = q; return _symbols.findName(q); } + + final byte[] inBuf = _inputBuffer; + int inPtr = _inputPtr; + + // First quadbyte is easy + int q1 = (inBuf[inPtr++] & 0xFF); + q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF); + q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF); + q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF); + 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); + int q2 = (inBuf[inPtr++] & 0xFF); + int left = len - 5; + if (left > 0) { + q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF); + if (left > 1) { + q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF); + if (left > 2) { + q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF); } } } @@ -1960,13 +2362,36 @@ _quad2 = q2; return _symbols.findName(q1, q2); } - return _findDecodedMedium(len); + + int q2 = (inBuf[inPtr++] & 0xFF); + q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF); + q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF); + q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF); + + if (len < 13) { + int q3 = (inBuf[inPtr++] & 0xFF); + int left = len - 9; + if (left > 0) { + q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF); + if (left > 1) { + q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF); + if (left > 2) { + q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF); + } + } + } + _quad1 = q1; + _quad2 = q2; + _quad3 = q3; + return _symbols.findName(q1, q2, q3); + } + return _findDecodedLong(len, q1, q2); } /** * Method for locating names longer than 8 bytes (in UTF-8) */ - private final Name _findDecodedMedium(int len) throws IOException + private final String _findDecodedLong(int len, int q1, int q2) throws IOException { // first, need enough buffer to store bytes as ints: { @@ -1975,42 +2400,48 @@ _quadBuffer = _growArrayTo(_quadBuffer, bufLen); } } + _quadBuffer[0] = q1; + _quadBuffer[1] = q2; + // then decode, full quads first - int offset = 0; - int inPtr = _inputPtr; + int offset = 2; + int inPtr = _inputPtr+8; + len -= 8; + 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) { + do { + int q = (inBuf[inPtr++] & 0xFF); + q = (q << 8) | inBuf[inPtr++] & 0xFF; + q = (q << 8) | inBuf[inPtr++] & 0xFF; + q = (q << 8) | inBuf[inPtr++] & 0xFF; + _quadBuffer[offset++] = q; + } while ((len -= 4) > 3); + // and then leftovers + if (len > 0) { + int q = inBuf[inPtr] & 0xFF; + if (len > 1) { + q = (q << 8) + (inBuf[++inPtr] & 0xFF); + if (len > 2) { q = (q << 8) + (inBuf[++inPtr] & 0xFF); - if (--len > 0) { - q = (q << 8) + (inBuf[++inPtr] & 0xFF); - } } - _quadBuffer[offset++] = q; + } + _quadBuffer[offset++] = q; } return _symbols.findName(_quadBuffer, offset); } private final String _addDecodedToSymbols(int len, String name) { if (len < 5) { - return _symbols.addName(name, _quad1, 0).getName(); + return _symbols.addName(name, _quad1); } if (len < 9) { - return _symbols.addName(name, _quad1, _quad2).getName(); + return _symbols.addName(name, _quad1, _quad2); + } + if (len < 13) { + return _symbols.addName(name, _quad1, _quad2, _quad3); } int qlen = (len + 3) >> 2; - return _symbols.addName(name, _quadBuffer, qlen).getName(); + return _symbols.addName(name, _quadBuffer, qlen); } private static int[] _growArrayTo(int[] arr, int minSize) { @@ -2154,9 +2585,8 @@ case 2: return _decode32Bits(); case 3: - /* 16-Jan-2014, tatu: Technically legal, but nothing defined, so let's - * only allow for cases where encoder is being wasteful... - */ + // 16-Jan-2014, tatu: Technically legal, but nothing defined, so let's + // only allow for cases where encoder is being wasteful... long l = _decode64Bits(); if (l < MIN_INT_L || l > MAX_INT_L) { _reportError("Illegal Tag value: "+l); @@ -2192,11 +2622,11 @@ case 3: long l = _decode64Bits(); if (l < 0 || l > MAX_INT_L) { - throw _constructError("Illegal length for "+_currToken+": "+l); + throw _constructError("Illegal length for "+getCurrentToken()+": "+l); } return (int) l; } - throw _constructError("Invalid length for "+_currToken+": 0x"+Integer.toHexString(lowBits)); + throw _constructError("Invalid length for "+getCurrentToken()+": 0x"+Integer.toHexString(lowBits)); } private int _decodeChunkLength(int expType) throws IOException @@ -2220,7 +2650,7 @@ return len; } - private double _decodeHalfSizeFloat() throws IOException + private float _decodeHalfSizeFloat() throws IOException { int i16 = _decode16Bits() & 0xFFFF; @@ -2229,17 +2659,17 @@ int f = i16 & 0x03FF; if (e == 0) { - double d = MATH_POW_2_NEG14 * (f / MATH_POW_2_10); - return neg ? -d : d; + float result = (float) (MATH_POW_2_NEG14 * (f / MATH_POW_2_10)); + return neg ? -result : result; } if (e == 0x1F) { - if (f != 0) return Double.NaN; + if (f != 0) return Float.NaN; return neg ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; } - double d = Math.pow(2, e - 15) * (1 + f / MATH_POW_2_10); - return neg ? -d : d; + float result = (float) (Math.pow(2, e - 15) * (1 + f / MATH_POW_2_10)); + return neg ? -result : result; } - + private final int _decode8Bits() throws IOException { if (_inputPtr >= _inputEnd) { loadMoreGuaranteed(); @@ -2415,7 +2845,7 @@ } return ((c << 6) | (d & 0x3F)) - 0x10000; } - + /* /********************************************************** /* Low-level reading, other @@ -2424,9 +2854,9 @@ protected final boolean loadMore() throws IOException { - _currInputProcessed += _inputEnd; - if (_inputStream != null) { + _currInputProcessed += _inputEnd; + int count = _inputStream.read(_inputBuffer, 0, _inputBuffer.length); if (count > 0) { _inputPtr = 0; @@ -2491,7 +2921,7 @@ } return _byteArrayBuilder; } - + protected void _closeInput() throws IOException { if (_inputStream != null) { if (_ioContext.isResourceManaged() || isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) { @@ -2522,7 +2952,7 @@ +_parsingContext.getExpectedLength()+") " +(_parsingContext.inObject() ? "Object" : "Array" )); } - + protected void _reportInvalidChar(int c) throws JsonParseException { // Either invalid WS or illegal UTF-8 start char if (c < ' ') { @@ -2530,15 +2960,15 @@ } _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 -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorBinaryTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorBinaryTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorBinaryTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorBinaryTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -0,0 +1,110 @@ +package com.fasterxml.jackson.dataformat.cbor; + +import java.io.*; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import org.junit.*; +import org.junit.rules.TemporaryFolder; + +import com.fasterxml.jackson.core.JsonGenerator; + +public class GeneratorBinaryTest //extends CBORTestBase +{ + final static int SMALL_LENGTH = 100; + final static int LARGE_LENGTH = CBORGenerator.BYTE_BUFFER_FOR_OUTPUT + 500; + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + private File binaryInputFile; + private File cborFile; + private File binaryOutputFile; + + @Before + public void before() throws IOException + { + binaryInputFile = tempFolder.newFile("sourceData.bin"); + cborFile = tempFolder.newFile("cbor.bin"); + binaryOutputFile = tempFolder.newFile("outputData.bin"); + } + + @Test + public void testSmallByteArray() throws Exception + { + testEncodeAndDecodeBytes(SMALL_LENGTH); + } + + @Test + public void testLargeByteArray() throws Exception + { + testEncodeAndDecodeBytes(LARGE_LENGTH); + } + + private void generateInputFile(File input, int fileSize) throws NoSuchAlgorithmException, IOException + { + OutputStream os = new BufferedOutputStream(new FileOutputStream(input)); + SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); + byte[] temp = new byte[1024]; + int remaining = fileSize; + while (remaining > 0) { + sr.nextBytes(temp); + os.write(temp, 0, Math.min(temp.length, remaining)); + remaining -= temp.length; + } + os.close(); + } + + private void testEncodeAndDecodeBytes(int length) throws NoSuchAlgorithmException, IOException + { + generateInputFile(binaryInputFile, length); + encodeInCBOR(binaryInputFile, cborFile); + decodeFromCborInFile(this.cborFile, this.binaryOutputFile); + assertFileEquals(this.binaryInputFile, this.binaryOutputFile); + } + + private void encodeInCBOR(File inputFile, File outputFile) throws NoSuchAlgorithmException, IOException + { + CBORFactory f = new CBORFactory(); + OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile)); + InputStream is = new BufferedInputStream(new FileInputStream(inputFile)); + + JsonGenerator gen = f.createGenerator(os); + gen.writeBinary(is, (int) inputFile.length()); + + gen.close(); + is.close(); + os.close(); + } + + private void decodeFromCborInFile(File input, File output) throws NoSuchAlgorithmException, IOException + { + CBORFactory f = new CBORFactory(); + OutputStream os = new FileOutputStream(output); + + InputStream is = new FileInputStream(input); + CBORParser parser = f.createParser(is); + parser.nextToken(); + parser.readBinaryValue(null, os); + + parser.close(); + is.close(); + os.close(); + } + + private void assertFileEquals(File file1, File file2) throws IOException + { + FileInputStream fis1 = new FileInputStream(file1); + FileInputStream fis2 = new FileInputStream(file2); + + Assert.assertEquals(file1.length(), file2.length()); + + int ch; + + while ((ch = fis1.read()) >= 0) { + Assert.assertEquals(ch, fis2.read()); + } + fis1.close(); + fis2.close(); + } +} diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorSimpleTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorSimpleTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorSimpleTest.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/GeneratorSimpleTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -1,8 +1,12 @@ package com.fasterxml.jackson.dataformat.cbor; import java.io.*; +import java.math.BigDecimal; import java.util.*; +import org.junit.Assert; + +import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.ObjectMapper; public class GeneratorSimpleTest extends CBORTestBase @@ -16,8 +20,13 @@ { ByteArrayOutputStream out = new ByteArrayOutputStream(); CBORGenerator gen = cborGenerator(out); + + assertEquals(0, gen.getOutputBuffered()); gen.writeBoolean(true); + assertEquals(1, gen.getOutputBuffered()); + gen.close(); + assertEquals(0, gen.getOutputBuffered()); _verifyBytes(out.toByteArray(), CBORConstants.BYTE_TRUE); out = new ByteArrayOutputStream(); @@ -328,4 +337,82 @@ b); } + public void testInvalidWrites() throws Exception + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + CBORGenerator gen = cborGenerator(out); + gen.writeStartObject(); + // this should NOT succeed: + try { + gen.writeString("test"); + fail("Should NOT allow write of anything but FIELD_NAME or END_OBJECT at this point"); + } catch (JsonGenerationException e) { + verifyException(e, "expecting field name"); + } + gen.close(); + + // and as per [dataformat-cbor#21] this also + out = new ByteArrayOutputStream(); + gen = cborGenerator(out); + gen.writeStartArray(); + gen.writeStartObject(); + try { + gen.writeString("BAR"); + fail("Should NOT allow write of anything but FIELD_NAME or END_OBJECT at this point"); + } catch (JsonGenerationException e) { + verifyException(e, "expecting field name"); + } + gen.close(); + } + + public void testCopyCurrentEventWithTag() throws Exception { + final ByteArrayOutputStream sourceBytes = new ByteArrayOutputStream(); + final CBORGenerator sourceGen = cborGenerator(sourceBytes); + sourceGen.writeNumber(BigDecimal.ONE); + sourceGen.close(); + + final ByteArrayOutputStream targetBytes = new ByteArrayOutputStream(); + final CBORGenerator gen = cborGenerator(targetBytes); + final CBORParser cborParser = cborParser(sourceBytes); + while (cborParser.nextToken() != null) { + gen.copyCurrentEvent(cborParser); + } + gen.close(); + + // copyCurrentEvent doesn't preserve fixed arrays, so we can't + // compare with the source bytes. + Assert.assertArrayEquals(new byte[] { + CBORConstants.BYTE_TAG_BIGFLOAT, + CBORConstants.BYTE_ARRAY_INDEFINITE, + 0, + 1, + CBORConstants.BYTE_BREAK + }, + targetBytes.toByteArray()); + } + + public void testCopyCurrentSturctureWithTag() throws Exception { + final ByteArrayOutputStream sourceBytes = new ByteArrayOutputStream(); + final CBORGenerator sourceGen = cborGenerator(sourceBytes); + sourceGen.writeNumber(BigDecimal.ONE); + sourceGen.close(); + + final ByteArrayOutputStream targetBytes = new ByteArrayOutputStream(); + final CBORGenerator gen = cborGenerator(targetBytes); + final CBORParser cborParser = cborParser(sourceBytes); + cborParser.nextToken(); + gen.copyCurrentStructure(cborParser); + gen.close(); + + // copyCurrentEvent doesn't preserve fixed arrays, so we can't + // compare with the source bytes. + Assert.assertArrayEquals(new byte[] { + CBORConstants.BYTE_TAG_BIGFLOAT, + CBORConstants.BYTE_ARRAY_INDEFINITE, + 0, + 1, + CBORConstants.BYTE_BREAK + }, + targetBytes.toByteArray()); + } } diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserBinaryTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserBinaryTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserBinaryTest.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserBinaryTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -20,6 +20,7 @@ private final ObjectMapper MAPPER = cborMapper(); public void testSmallBinaryValues() throws Exception { + _testBinary(0); _testBinary(1); _testBinary(20); _testBinary(100); diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserInputStreamTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserInputStreamTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserInputStreamTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserInputStreamTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -0,0 +1,50 @@ +package com.fasterxml.jackson.dataformat.cbor; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.SequenceInputStream; + +// for [dataformat-cbor#13] +public class ParserInputStreamTest extends CBORTestBase +{ + @Test + public void testInpuStream() throws Exception { + CBORFactory f = new CBORFactory(); + ObjectMapper cborMapper = new ObjectMapper(new CBORFactory()); + byte[] buffer = generateHugeCBOR(f); + + // split the buffer in two smaller buffer + int len = 160; + byte[] buf1 = new byte[len]; + byte[] buf2 = new byte[buffer.length - len]; + System.arraycopy(buffer, 0, buf1, 0, len); + System.arraycopy(buffer, len, buf2, 0, buffer.length - len); + + // aggregate the two buffers via a SequenceInputStream + ByteArrayInputStream in1 = new ByteArrayInputStream(buf1); + ByteArrayInputStream in2 = new ByteArrayInputStream(buf2); + SequenceInputStream inputStream = new SequenceInputStream(in1, in2); + + JsonNode jsonNode = cborMapper.readTree(inputStream); + assertNotNull(jsonNode); + } + + private byte[] generateHugeCBOR(CBORFactory f) throws IOException { + String hugeJson = "{"; + for (char c='a'; c <= 'z'; c++) { + for (char cc='a'; cc <= 'z'; cc++) { + hugeJson += "\"" + c + cc + "\":0,"; + } + for (int i = 0; i < 50; i++) { + hugeJson += "\"" + c + i + "\":" + i + ","; + } + } + hugeJson += "\"name\":123"; + hugeJson += "}"; + return cborDoc(f, hugeJson); + } +} diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserNextXxxTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserNextXxxTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserNextXxxTest.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserNextXxxTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.io.SerializedString; +// note: copied from test of same name from jackson-dataformat-smile public class ParserNextXxxTest extends CBORTestBase { public void testIsNextTokenName() throws Exception diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserSimpleTest.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserSimpleTest.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserSimpleTest.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/ParserSimpleTest.java 2016-03-16 03:47:39.000000000 +0000 @@ -129,11 +129,13 @@ { ByteArrayOutputStream out = new ByteArrayOutputStream(); JsonGenerator gen = cborGenerator(f, out); - gen.writeNumber(value); + gen.writeNumber((float) value); gen.close(); JsonParser p = cborParser(f, out.toByteArray()); assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); - assertEquals(NumberType.DOUBLE, p.getNumberType()); + if (NumberType.FLOAT != p.getNumberType()) { + fail("Expected `NumberType.FLOAT`, got "+p.getNumberType()+": "+p.getText()); + } assertEquals(value, p.getDoubleValue()); assertNull(p.nextToken()); p.close(); @@ -146,7 +148,7 @@ (byte) (i16 >> 8), (byte) i16 }); assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); - assertEquals(NumberType.DOUBLE, p.getNumberType()); + assertEquals(NumberType.FLOAT, p.getNumberType()); assertEquals(value, p.getDoubleValue()); assertNull(p.nextToken()); p.close(); @@ -238,6 +240,34 @@ p.close(); } + public void testCurrentLocationByteOffset() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + CBORGenerator gen = cborGenerator(out); + gen.writeString("1234567890"); + gen.writeString("1234567890"); + gen.close(); + + final byte[] b = out.toByteArray(); + + JsonParser p = cborParser(b); + + assertToken(JsonToken.VALUE_STRING, p.nextToken()); + assertEquals(1, p.getCurrentLocation().getByteOffset()); + p.getText(); // fully read token. + assertEquals(11, p.getCurrentLocation().getByteOffset()); + + assertToken(JsonToken.VALUE_STRING, p.nextToken()); + assertEquals(12, p.getCurrentLocation().getByteOffset()); + p.getText(); + assertEquals(22, p.getCurrentLocation().getByteOffset()); + + assertNull(p.nextToken()); + assertEquals(22, p.getCurrentLocation().getByteOffset()); + + p.close(); + assertEquals(22, p.getCurrentLocation().getByteOffset()); + } + public void testLongNonChunkedText() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -346,4 +376,22 @@ assertEquals(input, actual); p.close(); } + + public void testFloatNumberType() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + CBORGenerator generator = cborGenerator(out); + generator.writeStartObject(); + generator.writeFieldName("foo"); + generator.writeNumber(3f); + generator.writeEndObject(); + generator.close(); + + CBORParser parser = cborParser(out.toByteArray()); + assertEquals(JsonToken.START_OBJECT, parser.nextToken()); + assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); + assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken()); + assertEquals(NumberType.FLOAT, parser.getNumberType()); // fails with expected but was + assertEquals(JsonToken.END_OBJECT, parser.nextToken()); + parser.close(); + } } diff -Nru jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/TestBiggerData.java jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/TestBiggerData.java --- jackson-dataformat-cbor-2.4.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/TestBiggerData.java 2014-10-04 17:10:47.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/src/test/java/com/fasterxml/jackson/dataformat/cbor/TestBiggerData.java 2016-03-16 03:47:39.000000000 +0000 @@ -77,11 +77,11 @@ /********************************************************** */ - final ObjectMapper JSON_MAPPER = new ObjectMapper(); + final ObjectMapper MAPPER = new ObjectMapper(); public void testReading() throws Exception { - Citm citm0 = JSON_MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), + Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), Citm.class); ObjectMapper mapper = cborMapper(); @@ -111,7 +111,7 @@ public void testRoundTrip() throws Exception { - Citm citm0 = JSON_MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), + Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), Citm.class); ObjectMapper mapper = cborMapper(); byte[] cbor = mapper.writeValueAsBytes(citm0); diff -Nru jackson-dataformat-cbor-2.4.3/.travis.yml jackson-dataformat-cbor-2.7.3/.travis.yml --- jackson-dataformat-cbor-2.4.3/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ jackson-dataformat-cbor-2.7.3/.travis.yml 2016-03-16 03:47:39.000000000 +0000 @@ -0,0 +1,5 @@ +language: java + +jdk: + - oraclejdk7 + - oraclejdk8