diff --git a/README.md b/README.md
index 20f20e71..c32d508b 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ project, add the following to the `dependencies` section in your `pom.xml` file:
com.upokecentercbor
- 4.1.1
+ 4.1.3
```
diff --git a/api/Home.md b/api/Home.md
index 7f75f95c..a6047b6c 100644
--- a/api/Home.md
+++ b/api/Home.md
@@ -8,7 +8,8 @@ Interface implemented by classes that convert objects of arbitrary types to
Classes that implement this interface can support conversions from CBOR
objects to a custom type and back.
-* [com.upokecenter.cbor.CBORDataUtilities](com.upokecenter.cbor.CBORDataUtilities.md) -
+* [com.upokecenter.cbor.CBORDataUtilities](com.upokecenter.cbor.CBORDataUtilities.md) -
+Contains methods useful for reading and writing data, with a focus on CBOR.
* [com.upokecenter.cbor.CBOREncodeOptions](com.upokecenter.cbor.CBOREncodeOptions.md) -
Specifies options for encoding and decoding CBOR objects.
@@ -41,7 +42,8 @@ Represents a type that a CBOR object can have.
* [com.upokecenter.cbor.JSONOptions.ConversionMode](com.upokecenter.cbor.JSONOptions.ConversionMode.md) -
Specifies how JSON numbers are converted to CBOR when decoding JSON.
-* [com.upokecenter.cbor.CBORException](com.upokecenter.cbor.CBORException.md) -
+* [com.upokecenter.cbor.CBORException](com.upokecenter.cbor.CBORException.md) -
+Exception thrown for errors involving CBOR data.
* [com.upokecenter.util.DataUtilities](com.upokecenter.util.DataUtilities.md) -
Contains methods useful for reading and writing text strings.
diff --git a/api/com.upokecenter.cbor.CBORDataUtilities.md b/api/com.upokecenter.cbor.CBORDataUtilities.md
index e63bec27..a0c9e61f 100644
--- a/api/com.upokecenter.cbor.CBORDataUtilities.md
+++ b/api/com.upokecenter.cbor.CBORDataUtilities.md
@@ -2,9 +2,12 @@
public final class CBORDataUtilities extends java.lang.Object
+Contains methods useful for reading and writing data, with a focus on CBOR.
+
## Methods
* `static CBORObject ParseJSONNumber(java.lang.String str)`
+ Parses a number whose format follows the JSON specification.
* `static CBORObject ParseJSONNumber(java.lang.String str,
boolean integersOnly,
boolean positiveOnly)`
@@ -25,17 +28,39 @@ Instead, call ParseJSONNumber(str, jsonoptions) with a JSONOptions that
* `static CBORObject ParseJSONNumber(java.lang.String str,
int offset,
int count)`
+ Parses a number whose format follows the JSON specification (RFC 8259) from
+ a portion of a text string, and converts that number to a CBOR
+ object.
* `static CBORObject ParseJSONNumber(java.lang.String str,
int offset,
int count,
JSONOptions options)`
+ Parses a number whose format follows the JSON specification (RFC 8259) and
+ converts that number to a CBOR object.
* `static CBORObject ParseJSONNumber(java.lang.String str,
JSONOptions options)`
+ Parses a number whose format follows the JSON specification (RFC 8259) and
+ converts that number to a CBOR object.
## Method Details
### ParseJSONNumber
public static CBORObject ParseJSONNumber(java.lang.String str)
+Parses a number whose format follows the JSON specification. The method uses
+ a JSONOptions with all default properties except for a
+ PreserveNegativeZero property of false.
+
+**Parameters:**
+
+* str - A text string to parse as a JSON string.
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns positive
+ zero if the number is a zero that starts with a minus sign (such as
+ "-0" or "-0.0"). Returns null if the parsing fails, including if the
+ string is null or empty.
+
### ParseJSONNumber
@Deprecated public static CBORObject ParseJSONNumber(java.lang.String str, boolean integersOnly, boolean positiveOnly)
Deprecated.
@@ -45,6 +70,23 @@ Call the one-argument version of this method instead. If this method
call used integersOnly = true, check that the String does not
contain '.', 'E', or 'e' before calling that version.
+**Parameters:**
+
+* str - A text string to parse as a JSON number.
+
+* integersOnly - If true, no decimal points or exponents are allowed in
+ the string. The default is false.
+
+* positiveOnly - If true, only positive numbers are allowed (the leading
+ minus is disallowed). The default is false.
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns positive
+ zero if the number is a zero that starts with a minus sign (such as
+ "-0" or "-0.0"). Returns null if the parsing fails, including if the
+ string is null or empty.
+
### ParseJSONNumber
@Deprecated public static CBORObject ParseJSONNumber(java.lang.String str, boolean integersOnly, boolean positiveOnly, boolean preserveNegativeZero)
Deprecated.
@@ -56,9 +98,120 @@ Instead, call ParseJSONNumber(str, jsonoptions) with a JSONOptions that
that the String does not contain '.', 'E',
or 'e' before calling that version.
+**Parameters:**
+
+* str - A text string to parse as a JSON number.
+
+* integersOnly - If true, no decimal points or exponents are allowed in
+ the string. The default is false.
+
+* positiveOnly - If true, the leading minus is disallowed in the string.
+ The default is false.
+
+* preserveNegativeZero - If true, returns positive zero if the number is
+ a zero that starts with a minus sign (such as "-0" or "-0.0").
+ Otherwise, returns negative zero in this case. The default is false.
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns null if the
+ parsing fails, including if the string is null or empty.
+
### ParseJSONNumber
public static CBORObject ParseJSONNumber(java.lang.String str, JSONOptions options)
+Parses a number whose format follows the JSON specification (RFC 8259) and
+ converts that number to a CBOR object.
Roughly speaking, a valid
+ JSON number consists of an optional minus sign, one or more basic
+ digits (starting with 1 to 9 unless there is only one digit and that
+ digit is 0), an optional decimal point (".", full stop) with one or
+ more basic digits, and an optional letter E or e with an optional
+ plus or minus sign and one or more basic digits (the exponent). A
+ string representing a valid JSON number is not allowed to contain
+ white space characters, including spaces.
+
+**Parameters:**
+
+* str - A text string to parse as a JSON number.
+
+* options - An object containing options to control how JSON numbers are
+ decoded to CBOR objects. Can be null, in which case a JSONOptions
+ object with all default properties is used instead.
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns null if the
+ parsing fails, including if the string is null or empty.
+
### ParseJSONNumber
public static CBORObject ParseJSONNumber(java.lang.String str, int offset, int count)
+Parses a number whose format follows the JSON specification (RFC 8259) from
+ a portion of a text string, and converts that number to a CBOR
+ object.
Roughly speaking, a valid JSON number consists of an
+ optional minus sign, one or more basic digits (starting with 1 to 9
+ unless there is only one digit and that digit is 0), an optional
+ decimal point (".", full stop) with one or more basic digits, and an
+ optional letter E or e with an optional plus or minus sign and one
+ or more basic digits (the exponent). A string representing a valid
+ JSON number is not allowed to contain white space characters,
+ including spaces.
+
+**Parameters:**
+
+* str - A text string containing the portion to parse as a JSON number.
+
+* offset - An index, starting at 0, showing where the desired portion of
+ str begins.
+
+* count - The length, in code units, of the desired portion of
+ str (but not more than str 's length).
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns null if the
+ parsing fails, including if the string is null or empty.
+
+**Throws:**
+
+* java.lang.IllegalArgumentException - Either offset or count is less
+ than 0 or greater than str 's length, or str 's
+ length minus offset is less than count.
+
+* java.lang.NullPointerException - The parameter str is null.
+
### ParseJSONNumber
public static CBORObject ParseJSONNumber(java.lang.String str, int offset, int count, JSONOptions options)
+Parses a number whose format follows the JSON specification (RFC 8259) and
+ converts that number to a CBOR object.
Roughly speaking, a valid
+ JSON number consists of an optional minus sign, one or more basic
+ digits (starting with 1 to 9 unless there is only one digit and that
+ digit is 0), an optional decimal point (".", full stop) with one or
+ more basic digits, and an optional letter E or e with an optional
+ plus or minus sign and one or more basic digits (the exponent). A
+ string representing a valid JSON number is not allowed to contain
+ white space characters, including spaces.
+
+**Parameters:**
+
+* str - A text string to parse as a JSON number.
+
+* offset - An index, starting at 0, showing where the desired portion of
+ str begins.
+
+* count - The length, in code units, of the desired portion of
+ str (but not more than str 's length).
+
+* options - An object containing options to control how JSON numbers are
+ decoded to CBOR objects. Can be null, in which case a JSONOptions
+ object with all default properties is used instead.
+
+**Returns:**
+
+* A CBOR object that represents the parsed number. Returns null if the
+ parsing fails, including if the string is null or empty or
+ count is 0 or less.
+
+**Throws:**
+
+* java.lang.NullPointerException - The parameter str is null.
+
+* java.lang.IllegalArgumentException - Unsupported conversion kind.
diff --git a/api/com.upokecenter.cbor.CBORException.md b/api/com.upokecenter.cbor.CBORException.md
index 5084c10e..2e35162f 100644
--- a/api/com.upokecenter.cbor.CBORException.md
+++ b/api/com.upokecenter.cbor.CBORException.md
@@ -2,16 +2,38 @@
public final class CBORException extends java.lang.RuntimeException
+Exception thrown for errors involving CBOR data.
This library may throw
+ exceptions of this type in certain cases, notably when errors occur,
+ and may supply messages to those exceptions (the message can be
+ accessed through the Message property in.NET or the
+ getMessage() method in Java). These messages are intended to be
+ read by humans to help diagnose the error (or other cause of the
+ exception); they are not intended to be parsed by computer programs,
+ and the exact text of the messages may change at any time between
+ versions of this library.
+
## Methods
-* `CBORException()`
-* `CBORException(java.lang.String message)`
+* `CBORException() CBORException`
+ Initializes a new instance of the CBORException
+ class.
+* `CBORException(java.lang.String message) CBORException`
+ Initializes a new instance of the CBORException
+ class.
* `CBORException(java.lang.String message,
- java.lang.Throwable innerException)`
+ java.lang.Throwable innerException) CBORException`
+ Initializes a new instance of the CBORException
+ class.
## Constructors
-* `CBORException()`
-* `CBORException(java.lang.String message)`
+* `CBORException() CBORException`
+ Initializes a new instance of the CBORException
+ class.
+* `CBORException(java.lang.String message) CBORException`
+ Initializes a new instance of the CBORException
+ class.
* `CBORException(java.lang.String message,
- java.lang.Throwable innerException)`
+ java.lang.Throwable innerException) CBORException`
+ Initializes a new instance of the CBORException
+ class.
diff --git a/api/com.upokecenter.cbor.CBORObject.md b/api/com.upokecenter.cbor.CBORObject.md
index f2db24a3..d3fa37ca 100644
--- a/api/com.upokecenter.cbor.CBORObject.md
+++ b/api/com.upokecenter.cbor.CBORObject.md
@@ -143,10 +143,10 @@ Instead, use.getToObject()<PeterO.Numbers.EDecimal>()
in Java.
* `com.upokecenter.numbers.EFloat AsEFloat()`
Deprecated.
-Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.getNET()
+Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.NET
or .getToObject()(com.upokecenter.numbers.EFloat.class)
in Java.
- Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.getNET()
+ Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.NET
or .getToObject()(com.upokecenter.numbers.EFloat.class)
in Java.
* `com.upokecenter.numbers.EInteger AsEInteger()`
@@ -172,10 +172,10 @@ Instead, use.getToObject()<PeterO.Numbers.ERational>() in
in Java.
* `short AsInt16()`
Deprecated.
-Instead, use the following: (cbor.AsNumber().ToInt16Checked()),
- or .getToObject()<short>() in .getNET().
- Instead, use the following: (cbor.AsNumber().ToInt16Checked()),
- or .getToObject()<short>() in .getNET().
+Instead, use the following: (cbor.AsNumber().ToInt16Checked()), or
+.ToObject<short>() in .NET.
+ Instead, use the following: (cbor.AsNumber().ToInt16Checked()), or
+.ToObject<short>() in .NET.
* `int AsInt32()`
Converts this object to a 32-bit signed integer.
* `int AsInt32Value()`
@@ -184,9 +184,9 @@ Instead, use the following: (cbor.AsNumber().ToInt16Checked()),
* `long AsInt64()`
Deprecated.
Instead, use the following: (cbor.AsNumber().ToInt64Checked()), or
-.ToObject<long>() in.getNET().
+.ToObject<long>() in.NET.
Instead, use the following: (cbor.AsNumber().ToInt64Checked()), or
-.ToObject<long>() in.getNET().
+.ToObject<long>() in.NET.
* `long AsInt64Value()`
Converts this object to a 64-bit signed integer if this CBOR object's type
is Integer.
@@ -982,8 +982,8 @@ Gets the outermost tag for this CBOR data item, or -1 if the item is
@Deprecated public final int signum()
Deprecated.
Instead, convert this object to a number with.AsNumber(), and use the
- Sign property in.NET or the signum method in Java. Either will
- treat not-a-number (NaN) values differently than here.
+ Sign property in.NET or the signum method in Java. Either will treat
+ not-a-number (NaN) values differently than here.
**Returns:**
@@ -1411,7 +1411,7 @@ Generates a list of CBOR objects from an array of bytes in JavaScript object
public static CBORObject DecodeFromBytes(byte[] data, CBOREncodeOptions options)
Generates a CBOR object from an array of CBOR-encoded bytes, using the given
CBOREncodeOptions object to control the decoding process.
-
The following example (originally written in C# for the.getNET()
+
The following example (originally written in C# for the.NET
version) implements a method that decodes a text string from a CBOR
byte array. It's successful only if the CBOR object contains an
untagged text string.
private static string DecodeTextString(byte[] bytes) { if (bytes == null) { throw new NullPointerException("mapObj");} if (bytes.length == 0 || bytes[0]<0x60 || bytes[0]>0x7f) {throw new CBORException();} return CBORObject.DecodeFromBytes(bytes, CBOREncodeOptions.Default).AsString(); }
.
@@ -1781,7 +1781,7 @@ Converts this CBOR object to an object of an arbitrary type. See the
the same rules as for long are used, but the range is from 0
through 2^63-1 and the return type is ulong .
If the
type is int or a primitive floating-point type (float
- , double , as well as decimal in.getNET()), returns the
+ , double , as well as decimal in.NET), returns the
result of the corresponding As* method.
If the type is
string , returns the result of AsString.
If the type
is EFloat , EDecimal , EInteger , or
@@ -1965,11 +1965,10 @@ Generates a CBOR object from a CBOR object.
public long CalcEncodedSize()
Calculates the number of bytes this CBOR object takes when serialized as a
byte array using the EncodeToBytes() method. This calculation
- assumes that integers, lengths of maps and arrays, lengths of text
- and byte strings, and tag numbers are encoded in their shortest
- form; that floating-point numbers are encoded in their shortest
- value-preserving form; and that no indefinite-length encodings are
- used.
+ assumes that integers, lengths of maps and arrays, lengths of text and
+ byte strings, and tag numbers are encoded in their shortest form; that
+ floating-point numbers are encoded in their shortest value-preserving
+ form; and that no indefinite-length encodings are used.
**Returns:**
@@ -1979,8 +1978,8 @@ Calculates the number of bytes this CBOR object takes when serialized as a
**Throws:**
* CBORException - The CBOR object has an extremely
- deep level of nesting, including if the CBOR object is or has an
- array or map that includes itself.
+ deep level of nesting, including if the CBOR object is or has an array
+ or map that includes itself.
### FromObject
public static CBORObject FromObject(com.upokecenter.numbers.EInteger bigintValue)
@@ -2311,9 +2310,9 @@ Generates a CBORObject from an arbitrary object. See the overload of this
byte is converted to a CBOR integer from 0 through 255.
A primitive integer type (int, short,
long, as well as sbyte, ushort, uint ,
- and ulong in.getNET()) is converted to the corresponding CBOR
+ and ulong in.NET) is converted to the corresponding CBOR
integer.
A primitive floating-point type (float,
- double, as well as decimal in.getNET()) is converted to the
+ double, as well as decimal in.NET) is converted to the
corresponding CBOR number.
A string is converted to
a CBOR text string. To create a CBOR byte string object from
string, see the example given in .
@@ -3571,7 +3570,7 @@ Instead, use.getToObject()<PeterO.Numbers.EDecimal>()
### AsEFloat
@Deprecated public com.upokecenter.numbers.EFloat AsEFloat()
Deprecated.
-Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.getNET()
+Instead, use.getToObject()<PeterO.Numbers.EFloat>() in.NET
or .getToObject()(com.upokecenter.numbers.EFloat.class)
in Java.
@@ -3606,8 +3605,8 @@ Instead, use.getToObject()<PeterO.Numbers.ERational>() in
### AsInt16
@Deprecated public short AsInt16()
Deprecated.
-Instead, use the following: (cbor.AsNumber().ToInt16Checked()),
- or .getToObject()<short>() in .getNET().
+Instead, use the following: (cbor.AsNumber().ToInt16Checked()), or
+.ToObject<short>() in .NET.
**Returns:**
@@ -3785,7 +3784,7 @@ Converts this object to a 32-bit signed integer. Non-integer number values
@Deprecated public long AsInt64()
Deprecated.
Instead, use the following: (cbor.AsNumber().ToInt64Checked()), or
-.ToObject<long>() in.getNET().
+.ToObject<long>() in.NET.
**Returns:**
diff --git a/api/com.upokecenter.cbor.JSONOptions.ConversionMode.md b/api/com.upokecenter.cbor.JSONOptions.ConversionMode.md
index 0042f1cc..ce505a65 100644
--- a/api/com.upokecenter.cbor.JSONOptions.ConversionMode.md
+++ b/api/com.upokecenter.cbor.JSONOptions.ConversionMode.md
@@ -57,15 +57,9 @@ the order they are declared.
### Full
public static final JSONOptions.ConversionMode Full
JSON numbers are decoded to CBOR using the full precision given in the JSON
- text. The number will be converted to a CBOR object as follows:
- If the number's exponent is 0 (after shifting the decimal point
- to the end of the number without changing its value), using the
- rules given in the CBORObject.FromObject(EInteger) method;
- otherwise, using the rules given in the
- CBORObject.FromObject(EDecimal) method. An exception in
- version 4.x involves negative zeros; if the negative zero's
- exponent is 0, it's written as a CBOR floating-point number;
- otherwise the negative zero is written as an EDecimal.
+ text. This may involve numbers being converted to
+ arbitrary-precision integers or decimal numbers, where
+ appropriate.
### Double
public static final JSONOptions.ConversionMode Double
JSON numbers are decoded to CBOR as their closest-rounded approximation as
diff --git a/api/com.upokecenter.util.DataUtilities.md b/api/com.upokecenter.util.DataUtilities.md
index 466a912f..c65ea6d8 100644
--- a/api/com.upokecenter.util.DataUtilities.md
+++ b/api/com.upokecenter.util.DataUtilities.md
@@ -181,7 +181,7 @@ Generates a text string from a portion of a UTF-8 byte array.
Encodes a string in UTF-8 as a byte array. This method does not insert a
byte-order mark (U+FEFF) at the beginning of the encoded byte
array.
REMARK: It is not recommended to use
- Encoding.UTF8.GetBytes in.getNET(), or the getBytes()
+ Encoding.UTF8.GetBytes in.NET, or the getBytes()
method in Java to do this. For instance, getBytes() encodes
text strings in a default (so not fixed) character encoding, which
can be undesirable.
@@ -210,7 +210,7 @@ Generates a text string from a portion of a UTF-8 byte array.
Encodes a string in UTF-8 as a byte array. This method does not insert a
byte-order mark (U+FEFF) at the beginning of the encoded byte
array.
REMARK: It is not recommended to use
- Encoding.UTF8.GetBytes in.getNET(), or the getBytes()
+ Encoding.UTF8.GetBytes in.NET, or the getBytes()
method in Java to do this. For instance, getBytes() encodes
text strings in a default (so not fixed) character encoding, which
can be undesirable.
diff --git a/pom.xml b/pom.xml
index dc427523..b68b2d7a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,10 +4,66 @@
com.upokecentercborjar
- 4.1.0-SNAPSHOT
+ 4.1.3CBOR (Concise Binary Object Representation)
- A Java implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049.
+ A Java implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049.https://github.com/peteroupc/CBOR-Java
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.5
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.0.1
+
+ CBOR for Java documentation, generated in {currentYear}.
+
+ -html5
+
+
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+
+ scm:git:https://github.com/peteroupc/CBOR-Javascm:git:https://github.com/peteroupc/CBOR-Java.git
@@ -26,8 +82,8 @@
UTF-8
- 8
- 1.8
+ 6
+ 1.6
@@ -44,15 +100,21 @@
3.7.0
- -Xlint:deprecation
+ -Xlint:all
-
- edu.berkeley.cs.jqf
- jqf-maven-plugin
- 1.4
-
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ true
+ 1.6.1
+
+ ossrh
+ true
+ https://oss.sonatype.org/
+
+
@@ -62,16 +124,6 @@
-
- edu.berkeley.cs.jqf
- jqf-fuzz
- 1.4
-
-
- com.alibaba
- fastjson
- 1.2.25
- junitjunit
diff --git a/src/main/java/com/upokecenter/cbor/CBORDataUtilities.java b/src/main/java/com/upokecenter/cbor/CBORDataUtilities.java
index b9c9676a..044c33a8 100644
--- a/src/main/java/com/upokecenter/cbor/CBORDataUtilities.java
+++ b/src/main/java/com/upokecenter/cbor/CBORDataUtilities.java
@@ -12,6 +12,9 @@
import com.upokecenter.util.*;
import com.upokecenter.numbers.*;
+ /**
+ * Contains methods useful for reading and writing data, with a focus on CBOR.
+ */
public final class CBORDataUtilities {
private CBORDataUtilities() {
}
@@ -176,13 +179,42 @@ static String ToStringHelper(CBORObject obj, int depth) {
private static final JSONOptions PreserveNegZeroYes =
new JSONOptions("preservenegativezero=1");
+ /**
+ * Parses a number whose format follows the JSON specification. The method uses
+ * a JSONOptions with all default properties except for a
+ * PreserveNegativeZero property of false.
+ * @param str A text string to parse as a JSON string.
+ * @return A CBOR object that represents the parsed number. Returns positive
+ * zero if the number is a zero that starts with a minus sign (such as
+ * "-0" or "-0.0"). Returns null if the parsing fails, including if the
+ * string is null or empty.
+ */
public static CBORObject ParseJSONNumber(String str) {
// TODO: Preserve negative zeros in next major version
return ParseJSONNumber(str, PreserveNegZeroNo);
}
-/**
- * @deprecated Call the one-argument version of this method instead. If this\u0020method
+ /**
+ * Parses a number whose format follows the JSON specification (RFC 8259). The
+ * method uses a JSONOptions with all default properties except for a
+ * PreserveNegativeZero property of false.
Roughly speaking, a valid
+ * JSON number consists of an optional minus sign, one or more basic
+ * digits (starting with 1 to 9 unless there is only one digit and that
+ * digit is 0), an optional decimal point (".", full stop) with one or
+ * more basic digits, and an optional letter E or e with an optional
+ * plus or minus sign and one or more basic digits (the exponent). A
+ * string representing a valid JSON number is not allowed to contain
+ * white space characters, including spaces.
+ * @param str A text string to parse as a JSON number.
+ * @param integersOnly If true, no decimal points or exponents are allowed in
+ * the string. The default is false.
+ * @param positiveOnly If true, only positive numbers are allowed (the leading
+ * minus is disallowed). The default is false.
+ * @return A CBOR object that represents the parsed number. Returns positive
+ * zero if the number is a zero that starts with a minus sign (such as
+ * "-0" or "-0.0"). Returns null if the parsing fails, including if the
+ * string is null or empty.
+ * @deprecated Call the one-argument version of this method instead. If this\u0020method
* call used positiveOnly = true, check that the String\u0020does
* not\u0020begin\u0020with '-' before calling that version. If this method
* call used\u0020integersOnly\u0020 = true, check that the String does not
@@ -211,8 +243,27 @@ public static CBORObject ParseJSONNumber(
PreserveNegZeroNo);
}
-/**
- * @deprecated Instead, call ParseJSONNumber(str, jsonoptions) with\u0020a JSONOptions that
+ /**
+ * Parses a number whose format follows the JSON specification (RFC
+ * 8259).
Roughly speaking, a valid JSON number consists of an
+ * optional minus sign, one or more basic digits (starting with 1 to 9
+ * unless there is only one digit and that digit is 0), an optional
+ * decimal point (".", full stop) with one or more basic digits, and an
+ * optional letter E or e with an optional plus or minus sign and one
+ * or more basic digits (the exponent). A string representing a valid
+ * JSON number is not allowed to contain white space characters,
+ * including spaces.
+ * @param str A text string to parse as a JSON number.
+ * @param integersOnly If true, no decimal points or exponents are allowed in
+ * the string. The default is false.
+ * @param positiveOnly If true, the leading minus is disallowed in the string.
+ * The default is false.
+ * @param preserveNegativeZero If true, returns positive zero if the number is
+ * a zero that starts with a minus sign (such as "-0" or "-0.0").
+ * Otherwise, returns negative zero in this case. The default is false.
+ * @return A CBOR object that represents the parsed number. Returns null if the
+ * parsing fails, including if the string is null or empty.
+ * @deprecated Instead, call ParseJSONNumber(str, jsonoptions) with\u0020a JSONOptions that
* sets preserveNegativeZero to the\u0020desired value, either true or
* false. If this\u0020method call used positiveOnly = true, check that the
* String\u0020does not\u0020begin\u0020with '-' before calling that
@@ -245,6 +296,23 @@ public static CBORObject ParseJSONNumber(
jo);
}
+ /**
+ * Parses a number whose format follows the JSON specification (RFC 8259) and
+ * converts that number to a CBOR object.
Roughly speaking, a valid
+ * JSON number consists of an optional minus sign, one or more basic
+ * digits (starting with 1 to 9 unless there is only one digit and that
+ * digit is 0), an optional decimal point (".", full stop) with one or
+ * more basic digits, and an optional letter E or e with an optional
+ * plus or minus sign and one or more basic digits (the exponent). A
+ * string representing a valid JSON number is not allowed to contain
+ * white space characters, including spaces.
+ * @param str A text string to parse as a JSON number.
+ * @param options An object containing options to control how JSON numbers are
+ * decoded to CBOR objects. Can be null, in which case a JSONOptions
+ * object with all default properties is used instead.
+ * @return A CBOR object that represents the parsed number. Returns null if the
+ * parsing fails, including if the string is null or empty.
+ */
public static CBORObject ParseJSONNumber(
String str,
JSONOptions options) {
@@ -255,6 +323,29 @@ public static CBORObject ParseJSONNumber(
options);
}
+ /**
+ * Parses a number whose format follows the JSON specification (RFC 8259) from
+ * a portion of a text string, and converts that number to a CBOR
+ * object.
Roughly speaking, a valid JSON number consists of an
+ * optional minus sign, one or more basic digits (starting with 1 to 9
+ * unless there is only one digit and that digit is 0), an optional
+ * decimal point (".", full stop) with one or more basic digits, and an
+ * optional letter E or e with an optional plus or minus sign and one
+ * or more basic digits (the exponent). A string representing a valid
+ * JSON number is not allowed to contain white space characters,
+ * including spaces.
+ * @param str A text string containing the portion to parse as a JSON number.
+ * @param offset An index, starting at 0, showing where the desired portion of
+ * {@code str} begins.
+ * @param count The length, in code units, of the desired portion of {@code
+ * str} (but not more than {@code str} 's length).
+ * @return A CBOR object that represents the parsed number. Returns null if the
+ * parsing fails, including if the string is null or empty.
+ * @throws IllegalArgumentException Either {@code offset} or {@code count} is less
+ * than 0 or greater than {@code str} 's length, or {@code str} 's
+ * length minus {@code offset} is less than {@code count}.
+ * @throws NullPointerException The parameter {@code str} is null.
+ */
public static CBORObject ParseJSONNumber(
String str,
int offset,
@@ -272,6 +363,9 @@ static CBORObject ParseSmallNumberAsNegative(
if (options != null && options.getNumberConversion() ==
JSONOptions.ConversionMode.Double) {
return CBORObject.FromObject((double)(-digit));
+ } else if (options != null && options.getNumberConversion() ==
+ JSONOptions.ConversionMode.Decimal128) {
+ return CBORObject.FromObject(EDecimal.FromInt32(-digit));
} else {
// NOTE: Assumes digit is greater than zero, so PreserveNegativeZeros is
// irrelevant
@@ -284,12 +378,39 @@ static CBORObject ParseSmallNumber(int digit, JSONOptions
if (options != null && options.getNumberConversion() ==
JSONOptions.ConversionMode.Double) {
return CBORObject.FromObject((double)digit);
+ } else if (options != null && options.getNumberConversion() ==
+ JSONOptions.ConversionMode.Decimal128) {
+ return CBORObject.FromObject(EDecimal.FromInt32(digit));
} else {
// NOTE: Assumes digit is nonnegative, so PreserveNegativeZeros is irrelevant
return CBORObject.FromObject(digit);
}
}
+ /**
+ * Parses a number whose format follows the JSON specification (RFC 8259) and
+ * converts that number to a CBOR object.
Roughly speaking, a valid
+ * JSON number consists of an optional minus sign, one or more basic
+ * digits (starting with 1 to 9 unless there is only one digit and that
+ * digit is 0), an optional decimal point (".", full stop) with one or
+ * more basic digits, and an optional letter E or e with an optional
+ * plus or minus sign and one or more basic digits (the exponent). A
+ * string representing a valid JSON number is not allowed to contain
+ * white space characters, including spaces.
+ * @param str A text string to parse as a JSON number.
+ * @param offset An index, starting at 0, showing where the desired portion of
+ * {@code str} begins.
+ * @param count The length, in code units, of the desired portion of {@code
+ * str} (but not more than {@code str} 's length).
+ * @param options An object containing options to control how JSON numbers are
+ * decoded to CBOR objects. Can be null, in which case a JSONOptions
+ * object with all default properties is used instead.
+ * @return A CBOR object that represents the parsed number. Returns null if the
+ * parsing fails, including if the string is null or empty or {@code
+ * count} is 0 or less.
+ * @throws NullPointerException The parameter {@code str} is null.
+ * @throws IllegalArgumentException Unsupported conversion kind.
+ */
public static CBORObject ParseJSONNumber(
String str,
int offset,
diff --git a/src/main/java/com/upokecenter/cbor/CBORDateConverter.java b/src/main/java/com/upokecenter/cbor/CBORDateConverter.java
index 21f2369f..e645667a 100644
--- a/src/main/java/com/upokecenter/cbor/CBORDateConverter.java
+++ b/src/main/java/com/upokecenter/cbor/CBORDateConverter.java
@@ -17,13 +17,6 @@ private static String DateTimeToString(java.util.Date bi) {
return CBORUtilities.ToAtomDateTimeString(year[0], lesserFields);
}
- public CBORObject ValidateObject(CBORObject obj) {
- if (obj.getType() != CBORType.TextString) {
- throw new CBORException("Not a text String");
- }
- return obj;
- }
-
public java.util.Date FromCBORObject(CBORObject obj) {
if (obj.HasMostOuterTag(0)) {
try {
diff --git a/src/main/java/com/upokecenter/cbor/CBORException.java b/src/main/java/com/upokecenter/cbor/CBORException.java
index 7bd4c731..779fa09b 100644
--- a/src/main/java/com/upokecenter/cbor/CBORException.java
+++ b/src/main/java/com/upokecenter/cbor/CBORException.java
@@ -6,16 +6,43 @@
at: http://peteroupc.github.io/
*/
+ /**
+ * Exception thrown for errors involving CBOR data.
This library may throw
+ * exceptions of this type in certain cases, notably when errors occur,
+ * and may supply messages to those exceptions (the message can be
+ * accessed through the Message property in.NET or the
+ * getMessage() method in Java). These messages are intended to be
+ * read by humans to help diagnose the error (or other cause of the
+ * exception); they are not intended to be parsed by computer programs,
+ * and the exact text of the messages may change at any time between
+ * versions of this library.
+ */
+
public final class CBORException extends RuntimeException {
private static final long serialVersionUID = 1L;
-
+ /**
+ * Initializes a new instance of the {@link com.upokecenter.cbor.CBORException}
+ * class.
+ */
public CBORException() {
}
+ /**
+ * Initializes a new instance of the {@link com.upokecenter.cbor.CBORException}
+ * class.
+ * @param message The parameter {@code message} is a text string.
+ */
public CBORException(String message) {
super(message);
}
+ /**
+ * Initializes a new instance of the {@link com.upokecenter.cbor.CBORException}
+ * class. Uses the given message and inner exception.
+ * @param message The parameter {@code message} is a text string.
+ * @param innerException The parameter {@code innerException} is an Exception
+ * object.
+ */
public CBORException(String message, Throwable innerException) {
super(message);
initCause(innerException);;
diff --git a/src/main/java/com/upokecenter/cbor/CBORJson.java b/src/main/java/com/upokecenter/cbor/CBORJson.java
index 24b1c2c9..b1ba0124 100644
--- a/src/main/java/com/upokecenter/cbor/CBORJson.java
+++ b/src/main/java/com/upokecenter/cbor/CBORJson.java
@@ -565,7 +565,7 @@ private CBORObject ParseJSONObject(int depth) {
CBORObject obj;
int[] nextChar = new int[1];
boolean seenComma = false;
- TreeMap myHashMap = new TreeMap();
+ HashMap myHashMap = new HashMap();
while (true) {
c = this.SkipWhitespaceJSON();
switch (c) {
diff --git a/src/main/java/com/upokecenter/cbor/CBORJson2.java b/src/main/java/com/upokecenter/cbor/CBORJson2.java
index 3657a9e8..64f95db7 100644
--- a/src/main/java/com/upokecenter/cbor/CBORJson2.java
+++ b/src/main/java/com/upokecenter/cbor/CBORJson2.java
@@ -8,7 +8,6 @@
*/
import java.util.*;
-import java.io.*;
import com.upokecenter.util.*;
import com.upokecenter.numbers.*;
@@ -32,280 +31,166 @@ void RaiseError(String str) {
private final byte[] bytes;
private final JSONOptions options;
+ private StringBuilder sb;
private int index;
private int endPos;
- private static byte[] valueEmptyBytes = new byte[0];
- private byte[] NextJSONString() {
+ private String NextJSONString() {
int c;
- int startIndex = this.index;
- int batchIndex = startIndex;
- int batchEnd = startIndex;
- byte[] jbytes = this.bytes;
+ this.sb = (this.sb == null) ? (new StringBuilder()) : this.sb;
+ this.sb.delete(0, this.sb.length());
while (true) {
- if (this.index >= this.endPos) {
+ c = this.index < this.endPos ? ((int)this.bytes[this.index++]) &
+ 0xff : -1;
+ if (c == -1 || c < 0x20) {
this.RaiseError("Unterminated String");
}
- c = ((int)jbytes[this.index++]) & 0xff;
- if (c < 0x20) {
- this.RaiseError("Invalid character in String literal");
- }
- if (c == '\\') {
- batchEnd = this.index - 1;
- break;
- } else if (c == 0x22) {
- int isize = (this.index - startIndex) - 1;
- if (isize == 0) {
- return valueEmptyBytes;
- }
- byte[] buf = new byte[isize];
- System.arraycopy(jbytes, startIndex, buf, 0, isize);
- return buf;
- } else if (c < 0x80) {
- continue;
- } else if (c >= 0xc2 && c <= 0xdf) {
- int c1 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- if (c1 < 0x80 || c1 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else if (c >= 0xe0 && c <= 0xef) {
- int c1 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- int c2 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- int lower = (c == 0xe0) ? 0xa0 : 0x80;
- int upper = (c == 0xed) ? 0x9f : 0xbf;
- if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else if (c >= 0xf0 && c <= 0xf4) {
- int c1 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- int c2 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- int c3 = this.index < this.endPos ?
- ((int)this.bytes[this.index++]) & 0xff : -1;
- int lower = (c == 0xf0) ? 0x90 : 0x80;
- int upper = (c == 0xf4) ? 0x8f : 0xbf;
- if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf ||
- c3 < 0x80 || c3 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else {
- this.RaiseError("Invalid encoding");
- }
- }
- {
- java.io.ByteArrayOutputStream ms = null;
-try {
-ms = new java.io.ByteArrayOutputStream();
-
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- this.index = batchEnd;
- batchIndex = batchEnd;
- } else {
- this.index = startIndex;
- batchIndex = startIndex;
- }
- while (true) {
- batchEnd = this.index;
- c = this.index < this.endPos ? ((int)jbytes[this.index++]) &
- 0xff : -1;
- if (c == -1) {
- this.RaiseError("Unterminated String");
- }
- if (c < 0x20) {
- this.RaiseError("Invalid character in String literal");
- }
- switch (c) {
- case '\\':
- c = this.index < this.endPos ? ((int)jbytes[this.index++]) &
- 0xff : -1;
- switch (c) {
- case '\\':
- case '/':
- case '\"':
- // Slash is now allowed to be escaped under RFC 8259
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- ms.write((byte)c);
- break;
- case 'b':
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- ms.write((byte)'\b');
- break;
- case 'f':
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- ms.write((byte)'\f');
- break;
- case 'n':
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- ms.write((byte)'\n');
- break;
- case 'r':
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
+ switch (c) {
+ case '\\':
+ c = this.index < this.endPos ? ((int)this.bytes[this.index++]) &
+ 0xff : -1;
+ switch (c) {
+ case '\\':
+ case '/':
+ case '\"':
+ // Slash is now allowed to be escaped under RFC 8259
+ this.sb.append((char)c);
+ break;
+ case 'b':
+ this.sb.append('\b');
+ break;
+ case 'f':
+ this.sb.append('\f');
+ break;
+ case 'n':
+ this.sb.append('\n');
+ break;
+ case 'r':
+ this.sb.append('\r');
+ break;
+ case 't':
+ this.sb.append('\t');
+ break;
+ case 'u': { // Unicode escape
+ c = 0;
+ // Consists of 4 hex digits
+ for (int i = 0; i < 4; ++i) {
+ int ch = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ if (ch >= '0' && ch <= '9') {
+ c <<= 4;
+ c |= ch - '0';
+ } else if (ch >= 'A' && ch <= 'F') {
+ c <<= 4;
+ c |= ch + 10 - 'A';
+ } else if (ch >= 'a' && ch <= 'f') {
+ c <<= 4;
+ c |= ch + 10 - 'a';
+ } else {
+ this.RaiseError(
+ "Invalid Unicode escaped character");
}
- batchIndex = this.index;
- ms.write((byte)'\r');
- break;
- case 't':
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
+ }
+ if ((c & 0xf800) != 0xd800) {
+ // Non-surrogate
+ this.sb.append((char)c);
+ } else if ((c & 0xfc00) == 0xd800) {
+ int ch = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ if (ch != '\\' || (this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1) != 'u') {
+ this.RaiseError("Invalid escaped character");
}
- batchIndex = this.index;
- ms.write((byte)'\t');
- break;
- case 'u': { // Unicode escape
- c = 0;
- // Consists of 4 hex digits
+ int c2 = 0;
for (int i = 0; i < 4; ++i) {
- int ch = this.index < this.endPos ?
- (int)jbytes[this.index++] : -1;
+ ch = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
if (ch >= '0' && ch <= '9') {
- c <<= 4;
- c |= ch - '0';
+ c2 <<= 4;
+ c2 |= ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
- c <<= 4;
- c |= ch + 10 - 'A';
+ c2 <<= 4;
+ c2 |= ch + 10 - 'A';
} else if (ch >= 'a' && ch <= 'f') {
- c <<= 4;
- c |= ch + 10 - 'a';
+ c2 <<= 4;
+ c2 |= ch + 10 - 'a';
} else {
this.RaiseError(
"Invalid Unicode escaped character");
}
}
- if ((c & 0xf800) != 0xd800) {
- // Non-surrogate
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- int ic = c;
- if (c >= 0x800) {
- ms.write((byte)(0xe0 | ((ic >> 12) & 0x0f)));
- ms.write((byte)(0x80 | ((ic >> 6) & 0x3f)));
- ms.write((byte)(0x80 | (ic & 0x3f)));
- } else if (c >= 0x80) {
- ms.write((byte)(0xc0 | ((ic >> 6) & 0x1f)));
- ms.write((byte)(0x80 | (ic & 0x3f)));
- } else {
- ms.write((byte)ic);
- }
- } else if ((c & 0xfc00) == 0xd800) {
- int ch;
- if (this.index >= this.endPos - 1 ||
- jbytes[this.index] != (byte)'\\' ||
- jbytes[this.index + 1] != (byte)0x75) {
- this.RaiseError("Invalid escaped character");
- }
- this.index += 2;
- int c2 = 0;
- for (int i = 0; i < 4; ++i) {
- ch = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- if (ch >= '0' && ch <= '9') {
- c2 <<= 4;
- c2 |= ch - '0';
- } else if (ch >= 'A' && ch <= 'F') {
- c2 <<= 4;
- c2 |= ch + 10 - 'A';
- } else if (ch >= 'a' && ch <= 'f') {
- c2 <<= 4;
- c2 |= ch + 10 - 'a';
- } else {
- this.RaiseError(
- "Invalid Unicode escaped character");
- }
- }
- if ((c2 & 0xfc00) != 0xdc00) {
- this.RaiseError("Unpaired surrogate code point");
- } else {
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
- }
- batchIndex = this.index;
- int ic = 0x10000 + (((int)c & 0x3ff) << 10) +
- ((int)c2 & 0x3ff);
- ms.write((byte)(0xf0 | ((ic >> 18) & 0x07)));
- ms.write((byte)(0x80 | ((ic >> 12) & 0x3f)));
- ms.write((byte)(0x80 | ((ic >> 6) & 0x3f)));
- ms.write((byte)(0x80 | (ic & 0x3f)));
- }
- } else {
+ if ((c2 & 0xfc00) != 0xdc00) {
this.RaiseError("Unpaired surrogate code point");
+ } else {
+ this.sb.append((char)c);
+ this.sb.append((char)c2);
}
- break;
- }
- default: {
- this.RaiseError("Invalid escaped character");
- break;
+ } else {
+ this.RaiseError("Unpaired surrogate code point");
}
+ break;
}
- break;
- case 0x22: // double quote
- if (batchEnd > batchIndex) {
- ms.write(jbytes, batchIndex, batchEnd - batchIndex);
+ default: {
+ this.RaiseError("Invalid escaped character");
+ break;
}
- return ms.toByteArray();
- default: {
- if (c <= 0x7f) {
- // Deliberately empty
- } else if (c >= 0xc2 && c <= 0xdf) {
- int c1 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- if (c1 < 0x80 || c1 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else if (c >= 0xe0 && c <= 0xef) {
- int c1 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- int c2 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- int lower = (c == 0xe0) ? 0xa0 : 0x80;
- int upper = (c == 0xed) ? 0x9f : 0xbf;
- if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else if (c >= 0xf0 && c <= 0xf4) {
- int c1 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- int c2 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- int c3 = this.index < this.endPos ?
- ((int)jbytes[this.index++]) & 0xff : -1;
- int lower = (c == 0xf0) ? 0x90 : 0x80;
- int upper = (c == 0xf4) ? 0x8f : 0xbf;
- if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf ||
- c3 < 0x80 || c3 > 0xbf) {
- this.RaiseError("Invalid encoding");
- }
- } else {
+ }
+ break;
+ case 0x22: // double quote
+ return this.sb.toString();
+ default: {
+ if (c <= 0x7f) {
+ this.sb.append((char)c);
+ } else if (c >= 0xc2 && c <= 0xdf) {
+ int c1 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ if (c1 < 0x80 || c1 > 0xbf) {
this.RaiseError("Invalid encoding");
}
- break;
+ c = ((c - 0xc0) << 6) | (c1 - 0x80);
+ this.sb.append((char)c);
+ } else if (c >= 0xe0 && c <= 0xef) {
+ int c1 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ int c2 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ int lower = (c == 0xe0) ? 0xa0 : 0x80;
+ int upper = (c == 0xed) ? 0x9f : 0xbf;
+ if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf) {
+ this.RaiseError("Invalid encoding");
+ }
+ c = ((c - 0xe0) << 12) | ((c1 - 0x80) << 6) | (c2 - 0x80);
+ this.sb.append((char)c);
+ } else if (c >= 0xf0 && c <= 0xf4) {
+ int c1 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ int c2 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ int c3 = this.index < this.endPos ?
+ ((int)this.bytes[this.index++]) & 0xff : -1;
+ int lower = (c == 0xf0) ? 0x90 : 0x80;
+ int upper = (c == 0xf4) ? 0x8f : 0xbf;
+ if (c1 < lower || c1 > upper || c2 < 0x80 || c2 > 0xbf ||
+ c3 < 0x80 || c3 > 0xbf) {
+ this.RaiseError("Invalid encoding");
+ }
+ c = ((c - 0xf0) << 18) | ((c1 - 0x80) << 12) | ((c2 - 0x80) <<
+ 6) | (c3 - 0x80);
+ if (c <= 0xffff) {
+ { this.sb.append((char)c);
+ }
+ } else if (c <= 0x10ffff) {
+ this.sb.append((char)((((c - 0x10000) >> 10) & 0x3ff) |
+0xd800));
+ this.sb.append((char)(((c - 0x10000) & 0x3ff) | 0xdc00));
+ }
+ } else {
+ this.RaiseError("Invalid encoding");
}
+ break;
}
}
-}
-finally {
-try { if (ms != null) { ms.close(); } } catch (java.io.IOException ex) {}
-}
-}
+ }
}
private CBORObject NextJSONNegativeNumber(
@@ -452,7 +337,7 @@ private CBORObject NextJSONValue(
// The tokenizer already checked the String for invalid
// surrogate pairs, so just call the CBORObject
// constructor directly
- obj = CBORObject.FromRawUtf8(this.NextJSONString());
+ obj = CBORObject.FromRaw(this.NextJSONString());
nextChar[0] = this.SkipWhitespaceJSON();
return obj;
}
@@ -471,9 +356,9 @@ private CBORObject NextJSONValue(
case 't': {
// Parse true
if (this.endPos - this.index <= 2 ||
- this.bytes[this.index] != (byte)0x72 ||
- this.bytes[this.index + 1] != (byte)0x75 ||
- this.bytes[this.index + 2] != (byte)0x65) {
+ (((int)this.bytes[this.index]) & 0xFF) != 'r' ||
+ (((int)this.bytes[this.index + 1]) & 0xFF) != 'u' ||
+ (((int)this.bytes[this.index + 2]) & 0xFF) != 'e') {
this.RaiseError("Value can't be parsed.");
}
this.index += 3;
@@ -483,10 +368,10 @@ private CBORObject NextJSONValue(
case 'f': {
// Parse false
if (this.endPos - this.index <= 3 ||
- this.bytes[this.index] != (byte)0x61 ||
- this.bytes[this.index + 1] != (byte)0x6c ||
- this.bytes[this.index + 2] != (byte)0x73 ||
- this.bytes[this.index + 3] != (byte)0x65) {
+ (((int)this.bytes[this.index]) & 0xFF) != 'a' ||
+ (((int)this.bytes[this.index + 1]) & 0xFF) != 'l' ||
+ (((int)this.bytes[this.index + 2]) & 0xFF) != 's' ||
+ (((int)this.bytes[this.index + 3]) & 0xFF) != 'e') {
this.RaiseError("Value can't be parsed.");
}
this.index += 4;
@@ -496,9 +381,9 @@ private CBORObject NextJSONValue(
case 'n': {
// Parse null
if (this.endPos - this.index <= 2 ||
- this.bytes[this.index] != (byte)0x75 ||
- this.bytes[this.index + 1] != (byte)0x6c ||
- this.bytes[this.index + 2] != (byte)0x6c) {
+ (((int)this.bytes[this.index]) & 0xFF) != 'u' ||
+ (((int)this.bytes[this.index + 1]) & 0xFF) != 'l' ||
+ (((int)this.bytes[this.index + 2]) & 0xFF) != 'l') {
this.RaiseError("Value can't be parsed.");
}
this.index += 3;
@@ -530,7 +415,8 @@ private CBORObject NextJSONValue(
}
public CBORJson2(byte[] bytes, int index, int endPos, JSONOptions
- options) {
+options) {
+ this.sb = null;
this.bytes = bytes;
this.index = index;
this.endPos = endPos;
@@ -588,7 +474,7 @@ private CBORObject ParseJSONObject(int depth) {
CBORObject obj;
int[] nextchar = new int[1];
boolean seenComma = false;
- TreeMap myHashMap = new TreeMap();
+ HashMap myHashMap = new HashMap();
while (true) {
c = this.SkipWhitespaceJSON();
switch (c) {
@@ -616,7 +502,7 @@ private CBORObject ParseJSONObject(int depth) {
// The tokenizer already checked the String for invalid
// surrogate pairs, so just call the CBORObject
// constructor directly
- obj = CBORObject.FromRawUtf8(this.NextJSONString());
+ obj = CBORObject.FromRaw(this.NextJSONString());
key = obj;
if (!this.options.getAllowDuplicateKeys() &&
myHashMap.containsKey(obj)) {
diff --git a/src/main/java/com/upokecenter/cbor/CBORJson3.java b/src/main/java/com/upokecenter/cbor/CBORJson3.java
index 430b81b7..157a71be 100644
--- a/src/main/java/com/upokecenter/cbor/CBORJson3.java
+++ b/src/main/java/com/upokecenter/cbor/CBORJson3.java
@@ -40,41 +40,17 @@ void RaiseError(String str) {
private String NextJSONString() {
int c;
- int startIndex = this.index;
- int endIndex = -1;
- int ep = this.endPos;
- String js = this.jstring;
- int idx = this.index;
- while (true) {
- c = idx < ep ? ((int)js.charAt(idx++)) & 0xffff : -1;
- if (c == -1 || c < 0x20) {
- this.index = idx;
- this.RaiseError("Unterminated String");
- } else if (c == '"') {
- int iend = idx - 1;
- this.index = idx;
- return js.substring(
- startIndex, (
- startIndex)+(iend - startIndex));
- } else if (c == '\\' || (c & 0xf800) == 0xd800) {
- this.index = idx - 1;
- endIndex = this.index;
- break;
- }
- }
this.sb = (this.sb == null) ? (new StringBuilder()) : this.sb;
this.sb.delete(0, this.sb.length());
- this.sb.append(js, startIndex, (startIndex)+(endIndex - startIndex));
while (true) {
- c = this.index < ep ? ((int)js.charAt(this.index++)) &
+ c = this.index < this.endPos ? ((int)this.jstring.charAt(this.index++)) &
0xffff : -1;
if (c == -1 || c < 0x20) {
this.RaiseError("Unterminated String");
}
switch (c) {
case '\\':
- endIndex = this.index - 1;
- c = this.index < ep ? ((int)js.charAt(this.index++)) &
+ c = this.index < this.endPos ? ((int)this.jstring.charAt(this.index++)) &
0xffff : -1;
switch (c) {
case '\\':
@@ -102,8 +78,8 @@ private String NextJSONString() {
c = 0;
// Consists of 4 hex digits
for (int i = 0; i < 4; ++i) {
- int ch = this.index < ep ?
- ((int)js.charAt(this.index++)) : -1;
+ int ch = this.index < this.endPos ?
+ ((int)this.jstring.charAt(this.index++)) : -1;
if (ch >= '0' && ch <= '9') {
c <<= 4;
c |= ch - '0';
@@ -122,15 +98,16 @@ private String NextJSONString() {
// Non-surrogate
this.sb.append((char)c);
} else if ((c & 0xfc00) == 0xd800) {
- int ch = this.index < ep ? ((int)js.charAt(this.index++)) : -1;
- if (ch != '\\' || (this.index < ep ?
- ((int)js.charAt(this.index++)) : -1) != 'u') {
+ int ch = this.index < this.endPos ?
+ ((int)this.jstring.charAt(this.index++)) : -1;
+ if (ch != '\\' || (this.index < this.endPos ?
+ ((int)this.jstring.charAt(this.index++)) : -1) != 'u') {
this.RaiseError("Invalid escaped character");
}
int c2 = 0;
for (int i = 0; i < 4; ++i) {
- ch = this.index < ep ?
- ((int)js.charAt(this.index++)) : -1;
+ ch = this.index < this.endPos ?
+ ((int)this.jstring.charAt(this.index++)) : -1;
if (ch >= '0' && ch <= '9') {
c2 <<= 4;
c2 |= ch - '0';
@@ -169,11 +146,11 @@ private String NextJSONString() {
if ((c & 0xf800) != 0xd800) {
// Non-surrogate
this.sb.append((char)c);
- } else if ((c & 0xfc00) == 0xd800 && this.index < ep &&
- (js.charAt(this.index) & 0xfc00) == 0xdc00) {
+ } else if ((c & 0xfc00) == 0xd800 && this.index < this.endPos &&
+ (this.jstring.charAt(this.index) & 0xfc00) == 0xdc00) {
// Surrogate pair
this.sb.append((char)c);
- this.sb.append(js.charAt(this.index));
+ this.sb.append(this.jstring.charAt(this.index));
++this.index;
} else {
this.RaiseError("Unpaired surrogate code point");
@@ -201,15 +178,15 @@ private CBORObject NextJSONNegativeNumber(
if (c2 == ',' || c2 == ']' || c2 == '}') {
++this.index;
obj = CBORDataUtilities.ParseSmallNumberAsNegative(
- c - '0',
- this.options);
+ c - '0',
+ this.options);
nextChar[0] = c2;
return obj;
} else if (c2 == 0x20 || c2 == 0x0a || c2 == 0x0d || c2 == 0x09) {
++this.index;
obj = CBORDataUtilities.ParseSmallNumberAsNegative(
- c - '0',
- this.options);
+ c - '0',
+ this.options);
nextChar[0] = this.SkipWhitespaceJSON();
return obj;
}
@@ -220,14 +197,14 @@ private CBORObject NextJSONNegativeNumber(
int[] endIndex = new int[1];
endIndex[0] = numberStartIndex;
obj = CBORDataUtilities.ParseJSONNumber(
- this.jstring,
- numberStartIndex,
- this.endPos - numberStartIndex,
- this.options,
- endIndex);
+ this.jstring,
+ numberStartIndex,
+ this.endPos - numberStartIndex,
+ this.options,
+ endIndex);
int numberEndIndex = endIndex[0];
this.index = numberEndIndex >= this.endPos ? this.endPos :
- (numberEndIndex + 1);
+ (numberEndIndex + 1);
if (obj == null) {
int strlen = numberEndIndex - numberStartIndex;
String errstr = this.jstring.substring(numberStartIndex, (numberStartIndex)+(Math.min(100, strlen)));
@@ -237,10 +214,11 @@ private CBORObject NextJSONNegativeNumber(
this.RaiseError("JSON number can't be parsed. " + errstr);
}
- c = numberEndIndex >= this.endPos ? -1 : this.jstring.charAt(numberEndIndex);
+ c = numberEndIndex >= this.endPos ? -1 :
+this.jstring.charAt(numberEndIndex);
// check if character can validly appear after a JSON number
if (c != ',' && c != ']' && c != '}' && c != -1 &&
- c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) {
+ c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) {
this.RaiseError("Invalid character after JSON number");
}
// System.out.println("endIndex="+endIndex[0]+", "+
@@ -307,14 +285,14 @@ private CBORObject NextJSONNonnegativeNumber(int c, int[] nextChar) {
int[] endIndex = new int[1];
endIndex[0] = numberStartIndex;
obj = CBORDataUtilities.ParseJSONNumber(
- this.jstring,
- numberStartIndex,
- this.endPos - numberStartIndex,
- this.options,
- endIndex);
+ this.jstring,
+ numberStartIndex,
+ this.endPos - numberStartIndex,
+ this.options,
+ endIndex);
int numberEndIndex = endIndex[0];
this.index = numberEndIndex >= this.endPos ? this.endPos :
- (numberEndIndex + 1);
+ (numberEndIndex + 1);
if (obj == null) {
int strlen = numberEndIndex - numberStartIndex;
String errstr = this.jstring.substring(numberStartIndex, (numberStartIndex)+(Math.min(100, strlen)));
@@ -324,7 +302,8 @@ private CBORObject NextJSONNonnegativeNumber(int c, int[] nextChar) {
this.RaiseError("JSON number can't be parsed. " + errstr);
}
- c = numberEndIndex >= this.endPos ? -1 : this.jstring.charAt(numberEndIndex);
+ c = numberEndIndex >= this.endPos ? -1 :
+this.jstring.charAt(numberEndIndex);
// check if character can validly appear after a JSON number
if (c != ',' && c != ']' && c != '}' && c != -1 &&
c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) {
@@ -493,7 +472,7 @@ private CBORObject ParseJSONObject(int depth) {
CBORObject obj;
int[] nextchar = new int[1];
boolean seenComma = false;
- TreeMap myHashMap = new TreeMap();
+ HashMap myHashMap = new HashMap();
while (true) {
c = this.SkipWhitespaceJSON();
switch (c) {
diff --git a/src/main/java/com/upokecenter/cbor/CBORJsonWriter.java b/src/main/java/com/upokecenter/cbor/CBORJsonWriter.java
index ffab4138..79d2b8b1 100644
--- a/src/main/java/com/upokecenter/cbor/CBORJsonWriter.java
+++ b/src/main/java/com/upokecenter/cbor/CBORJsonWriter.java
@@ -13,21 +13,14 @@ static void WriteJSONStringUnquoted(
String str,
StringOutput sb,
JSONOptions options) throws java.io.IOException {
- int i = 0;
- for (; i < str.length(); ++i) {
- char c = str.charAt(i);
- if (c < 0x20 || c >= 0x7f || c == '\\' || c == '"') {
- sb.WriteString(str, 0, i);
- break;
- }
- }
- if (i == str.length()) {
- sb.WriteString(str, 0, i);
- return;
- }
- for (; i < str.length(); ++i) {
+ boolean first = true;
+ for (int i = 0; i < str.length(); ++i) {
char c = str.charAt(i);
if (c == '\\' || c == '"') {
+ if (first) {
+ first = false;
+ sb.WriteString(str, 0, i);
+ }
sb.WriteCodePoint((int)'\\');
sb.WriteCodePoint((int)c);
} else if (c < 0x20 || (c >= 0x7f && (c == 0x2028 || c == 0x2029 ||
@@ -36,6 +29,10 @@ static void WriteJSONStringUnquoted(
// Control characters, and also the line and paragraph separators
// which apparently can't appear in JavaScript (as opposed to
// JSON) strings
+ if (first) {
+ first = false;
+ sb.WriteString(str, 0, i);
+ }
if (c == 0x0d) {
sb.WriteString("\\r");
} else if (c == 0x0a) {
@@ -59,25 +56,37 @@ static void WriteJSONStringUnquoted(
sb.WriteCodePoint((int)Hex16.charAt((int)(c >> 4)));
sb.WriteCodePoint((int)Hex16.charAt((int)(c & 15)));
}
- } else if ((c & 0xfc00) == 0xd800) {
+ } else {
+ if ((c & 0xfc00) == 0xd800) {
if (i >= str.length() - 1 || (str.charAt(i + 1) & 0xfc00) != 0xdc00) {
// NOTE: RFC 8259 doesn't prohibit any particular
// error-handling behavior when a writer of JSON
// receives a String with an unpaired surrogate.
if (options.getReplaceSurrogates()) {
+ if (first) {
+ first = false;
+ sb.WriteString(str, 0, i);
+ }
// Replace unpaired surrogate with U+FFFD
- sb.WriteCodePoint(0xfffd);
+ c = (char)0xfffd;
} else {
throw new CBORException("Unpaired surrogate in String");
}
- } else {
+ }
+ }
+ if (!first) {
+ if ((c & 0xfc00) == 0xd800) {
sb.WriteString(str, i, 2);
++i;
+ } else {
+ sb.WriteCodePoint((int)c);
}
- } else {
- sb.WriteCodePoint((int)c);
+ }
}
}
+ if (first) {
+ sb.WriteString(str);
+ }
}
static void WriteJSONToInternal(
diff --git a/src/main/java/com/upokecenter/cbor/CBORObject.java b/src/main/java/com/upokecenter/cbor/CBORObject.java
index 67077e51..61ffdc0a 100644
--- a/src/main/java/com/upokecenter/cbor/CBORObject.java
+++ b/src/main/java/com/upokecenter/cbor/CBORObject.java
@@ -105,7 +105,8 @@ private static CBORObject ConstructIntegerValue(int v) {
/**
* A not-a-number value.
*/
- public static final CBORObject NaN = CBORObject.FromObject(Double.NaN);
+ public static final CBORObject NaN =
+CBORObject.FromObject(Double.NaN);
/**
* The value negative infinity.
@@ -155,7 +156,6 @@ private static CBORObject ConstructIntegerValue(int v) {
private static final int CBORObjectTypeTagged = 6;
private static final int CBORObjectTypeSimpleValue = 7;
private static final int CBORObjectTypeDouble = 8;
- private static final int CBORObjectTypeTextStringUtf8 = 9;
private static final int StreamedStringBufferLength = 4096;
@@ -249,8 +249,8 @@ public final EInteger getMostInnerTag() {
return EInteger.FromInt64(previtem.tagLow);
}
return LowHighToEInteger(
- previtem.tagLow,
- previtem.tagHigh);
+ previtem.tagLow,
+ previtem.tagHigh);
}
/**
@@ -397,8 +397,8 @@ public final EInteger getMostOuterTag() {
return EInteger.FromInt32(this.tagLow);
}
return LowHighToEInteger(
- this.tagLow,
- this.tagHigh);
+ this.tagLow,
+ this.tagHigh);
}
/**
@@ -408,8 +408,8 @@ public final EInteger getMostOuterTag() {
* @throws IllegalStateException This object does not represent a number, or
* this object is a not-a-number (NaN) value.
* @deprecated Instead, convert this object to a number with.AsNumber(), \u0020 and use the
- * Sign property in.NET or the signum method in\u0020Java. Either will
- * treat not-a-number (NaN) values differently than here.
+ * Sign property in.NET or the signum method in Java. Either will treat
+ * not-a-number (NaN) values differently than here.
*/
@Deprecated
public final int signum() {
@@ -467,9 +467,9 @@ public final CBORType getType() {
case CBORObjectTypeByteString:
return CBORType.ByteString;
case CBORObjectTypeTextString:
- case CBORObjectTypeTextStringUtf8:
return CBORType.TextString;
- default: throw new IllegalStateException("Unexpected data type");
+ default:
+ throw new IllegalStateException("Unexpected data type");
}
}
@@ -1001,7 +1001,7 @@ public static CBORObject[] FromJSONSequenceBytes(byte[] data,
/**
* Generates a CBOR object from an array of CBOR-encoded bytes, using the given
* CBOREncodeOptions object to control the decoding process.
- *
The following example (originally written in C# for the.getNET()
+ *
The following example (originally written in C# for the.NET
* version) implements a method that decodes a text string from a CBOR
* byte array. It's successful only if the CBOR object contains an
* untagged text string.
private static string DecodeTextString(byte[] bytes) { if (bytes == null) { throw new NullPointerException("mapObj");} if (bytes.length == 0 || bytes[0]<0x60 || bytes[0]>0x7f) {throw new CBORException();} return CBORObject.DecodeFromBytes(bytes, CBOREncodeOptions.Default).AsString(); }
Generates a CBOR object from a text string in JavaScript object Notation
@@ -1414,7 +1414,7 @@ public T ToObject(java.lang.reflect.Type t, PODOptions options) {
* the same rules as for long are used, but the range is from 0
* through 2^63-1 and the return type is ulong .
If the
* type is int or a primitive floating-point type (float
- * , double , as well as decimal in.getNET()), returns the
+ * , double , as well as decimal in.NET), returns the
* result of the corresponding As* method.
If the type is
* string , returns the result of AsString.
If the type
* is EFloat , EDecimal , EInteger , or
@@ -1643,11 +1643,11 @@ T ToObject(java.lang.reflect.Type t,
* @return A CBOR object.
*/
public static CBORObject FromObject(long value) {
- if (value >= 0L && value < 24L) {
- return FixedObjects[(int)value];
- } else {
- return (value >= -24L && value < 0L) ? FixedObjects[0x20 - (int)(value +
- 1L)] : new CBORObject(CBORObjectTypeInteger, value);
+if (value >= 0L && value < 24L) {
+ return FixedObjects[(int)value];
+} else {
+ return (value >= -24L && value < 0L) ? FixedObjects[0x20 - (int)(value +
+1L)] : new CBORObject(CBORObjectTypeInteger, value);
}
}
@@ -1689,22 +1689,21 @@ private static int IntegerByteLength(long longValue) {
}
}
- /**
- * Calculates the number of bytes this CBOR object takes when serialized as a
- * byte array using the EncodeToBytes() method. This calculation
- * assumes that integers, lengths of maps and arrays, lengths of text
- * and byte strings, and tag numbers are encoded in their shortest
- * form; that floating-point numbers are encoded in their shortest
- * value-preserving form; and that no indefinite-length encodings are
- * used.
- * @return The number of bytes this CBOR object takes when serialized as a byte
- * array using the {@code EncodeToBytes()} method.
- * @throws com.upokecenter.cbor.CBORException The CBOR object has an extremely
- * deep level of nesting, including if the CBOR object is or has an
- * array or map that includes itself.
- */
+ /**
+ * Calculates the number of bytes this CBOR object takes when serialized as a
+ * byte array using the EncodeToBytes() method. This calculation
+ * assumes that integers, lengths of maps and arrays, lengths of text and
+ * byte strings, and tag numbers are encoded in their shortest form; that
+ * floating-point numbers are encoded in their shortest value-preserving
+ * form; and that no indefinite-length encodings are used.
+ * @return The number of bytes this CBOR object takes when serialized as a byte
+ * array using the {@code EncodeToBytes()} method.
+ * @throws com.upokecenter.cbor.CBORException The CBOR object has an extremely
+ * deep level of nesting, including if the CBOR object is or has an array
+ * or map that includes itself.
+ */
public long CalcEncodedSize() {
- return this.CalcEncodedSize(0);
+ return this.CalcEncodedSize(0);
}
private long CalcEncodedSize(int depth) {
@@ -1723,11 +1722,6 @@ private long CalcEncodedSize(int depth) {
}
cbor = cbor.UntagOne();
}
- if (cbor.getItemType() == CBORObjectTypeTextStringUtf8) {
- byte[] bytes = (byte[])this.getThisItem();
- size = (size + IntegerByteLength(bytes.length));
- return size + bytes.length;
- }
switch (cbor.getType()) {
case Integer: {
if (cbor.CanValueFitInInt64()) {
@@ -1745,7 +1739,7 @@ private long CalcEncodedSize(int depth) {
return size + 3;
}
return CBORUtilities.DoubleRetainsSameValueInSingle(valueBits) ?
- (size + 5) : (size + 9);
+(size + 5) : (size + 9);
}
case Array:
size = (size + IntegerByteLength(cbor.size()));
@@ -1756,7 +1750,7 @@ private long CalcEncodedSize(int depth) {
return size;
case Map: {
Collection> entries =
- this.getEntries();
+ this.getEntries();
size = (size + IntegerByteLength(entries.size()));
for (Map.Entry entry : entries) {
CBORObject key = entry.getKey();
@@ -1850,27 +1844,23 @@ public static CBORObject FromObject(EFloat bigValue) {
if (bigValue.IsSignalingNaN()) {
options += 6;
}
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(bigValue.getExponent()),
- CBORObject.FromObject(bigValue.getUnsignedMantissa()),
- CBORObject.FromObject(options));
+ cbor = CBORObject.NewArray().Add(bigValue.getExponent())
+ .Add(bigValue.getUnsignedMantissa()).Add(options);
tag = 269;
} else {
EInteger exponent = bigValue.getExponent();
if (exponent.CanFitInInt64()) {
tag = 5;
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(exponent.ToInt64Checked()),
- CBORObject.FromObject(bigValue.getMantissa()));
- } else {
- tag = (exponent.GetSignedBitLengthAsInt64() > 64) ?
+ cbor = CBORObject.NewArray()
+ .Add(exponent.ToInt64Checked()).Add(bigValue.getMantissa());
+ } else {
+ tag = (exponent.GetSignedBitLengthAsEInteger().compareTo(64) > 0) ?
265 : 5;
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(exponent),
- CBORObject.FromObject(bigValue.getMantissa()));
+ cbor = CBORObject.NewArray()
+ .Add(exponent).Add(bigValue.getMantissa());
}
}
- return cbor.WithTag(tag);
+ return CBORObject.FromObjectAndTag(cbor, tag);
}
/**
@@ -1904,18 +1894,15 @@ public static CBORObject FromObject(ERational bigValue) {
options += 6;
}
- cbor = CBORObject.NewArray(
- FromObject(bigValue.getUnsignedNumerator()),
- FromObject(bigValue.getDenominator()),
- FromObject(options));
+ cbor = CBORObject.NewArray().Add(bigValue.getUnsignedNumerator())
+ .Add(bigValue.getDenominator()).Add(options);
tag = 270;
} else {
tag = 30;
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(bigValue.getNumerator()),
- CBORObject.FromObject(bigValue.getDenominator()));
+ cbor = CBORObject.NewArray()
+ .Add(bigValue.getNumerator()).Add(bigValue.getDenominator());
}
- return cbor.WithTag(tag);
+ return CBORObject.FromObjectAndTag(cbor, tag);
}
/**
@@ -1950,27 +1937,23 @@ public static CBORObject FromObject(EDecimal bigValue) {
if (bigValue.IsSignalingNaN()) {
options += 6;
}
- cbor = CBORObject.NewArray(
- FromObject(bigValue.getExponent()),
- FromObject(bigValue.getUnsignedMantissa()),
- FromObject(options));
+ cbor = CBORObject.NewArray().Add(bigValue.getExponent())
+ .Add(bigValue.getUnsignedMantissa()).Add(options);
tag = 268;
} else {
EInteger exponent = bigValue.getExponent();
if (exponent.CanFitInInt64()) {
tag = 4;
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(exponent.ToInt64Checked()),
- CBORObject.FromObject(bigValue.getMantissa()));
- } else {
- tag = (exponent.GetSignedBitLengthAsInt64() > 64) ?
+ cbor = CBORObject.NewArray()
+ .Add(exponent.ToInt64Checked()).Add(bigValue.getMantissa());
+ } else {
+ tag = (exponent.GetSignedBitLengthAsEInteger().compareTo(64) > 0) ?
264 : 4;
- cbor = CBORObject.NewArray(
- CBORObject.FromObject(exponent),
- CBORObject.FromObject(bigValue.getMantissa()));
+ cbor = CBORObject.NewArray()
+ .Add(exponent).Add(bigValue.getMantissa());
}
}
- return cbor.WithTag(tag);
+ return CBORObject.FromObjectAndTag(cbor, tag);
}
/**
@@ -1985,9 +1968,6 @@ public static CBORObject FromObject(String strValue) {
if (strValue == null) {
return CBORObject.Null;
}
- if (strValue.length() == 0) {
- return GetFixedObject(0x60);
- }
if (DataUtilities.GetUtf8Length(strValue, false) < 0) {
throw new IllegalArgumentException("String contains an unpaired " +
"surrogate code point.");
@@ -2001,12 +1981,12 @@ public static CBORObject FromObject(String strValue) {
* @return A CBOR object.
*/
public static CBORObject FromObject(int value) {
- if (value >= 0 && value < 24) {
- return FixedObjects[value];
- } else {
- return (value >= -24 && value < 0) ? FixedObjects[0x20 - (value + 1)] :
- FromObject((long)value);
- }
+if (value >= 0 && value < 24) {
+ return FixedObjects[value];
+} else {
+ return (value >= -24 && value < 0) ? FixedObjects[0x20 - (value + 1)] :
+FromObject((long)value);
+}
}
/**
@@ -2015,12 +1995,12 @@ public static CBORObject FromObject(int value) {
* @return A CBOR object generated from the given integer.
*/
public static CBORObject FromObject(short value) {
- if (value >= 0 && value < 24) {
- return FixedObjects[value];
- } else {
- return (value >= -24 && value < 0) ? FixedObjects[0x20 - (value + 1)] :
- FromObject((long)value);
- }
+if (value >= 0 && value < 24) {
+ return FixedObjects[value];
+} else {
+ return (value >= -24 && value < 0) ? FixedObjects[0x20 - (value + 1)] :
+FromObject((long)value);
+}
}
/**
@@ -2090,12 +2070,11 @@ public static CBORObject FromObject(CBORObject[] array) {
if (array == null) {
return CBORObject.Null;
}
- List list = new ArrayList(array.length ==
- Integer.MAX_VALUE ? array.length : (array.length + 1));
- for (CBORObject cbor : array) {
- list.add(cbor);
+ CBORObject cbor = CBORObject.NewArray();
+ for (CBORObject i : array) {
+ cbor.Add(i);
}
- return new CBORObject(CBORObjectTypeArray, list);
+ return cbor;
}
/**
@@ -2108,8 +2087,7 @@ public static CBORObject FromObject(int[] array) {
if (array == null) {
return CBORObject.Null;
}
- List list = new ArrayList(array.length ==
- Integer.MAX_VALUE ? array.length : (array.length + 1));
+ List list = new ArrayList();
for (int i : array) {
list.add(FromObject(i));
}
@@ -2126,8 +2104,7 @@ public static CBORObject FromObject(long[] array) {
if (array == null) {
return CBORObject.Null;
}
- List list = new ArrayList(array.length ==
- Integer.MAX_VALUE ? array.length : (array.length + 1));
+ List list = new ArrayList();
for (long i : array) {
list.add(FromObject(i));
}
@@ -2225,9 +2202,9 @@ public static CBORObject FromObject(
* byte is converted to a CBOR integer from 0 through 255.
*
A primitive integer type (int, short,
* long, as well as sbyte, ushort, uint ,
- * and ulong in.getNET()) is converted to the corresponding CBOR
+ * and ulong in.NET) is converted to the corresponding CBOR
* integer.
A primitive floating-point type (float,
- * double, as well as decimal in.getNET()) is converted to the
+ * double, as well as decimal in.NET) is converted to the
* corresponding CBOR number.
A string is converted to
* a CBOR text string. To create a CBOR byte string object from
* string, see the example given in
kvp = (Map.Entry, ?>)keyPair;
CBORObject objKey = CBORObject.FromObject(
- kvp.getKey(),
- options,
- mapper,
- depth + 1);
+ kvp.getKey(),
+ options,
+ mapper,
+ depth + 1);
objret.set(objKey, CBORObject.FromObject(
- kvp.getValue(),
- options,
- mapper,
- depth + 1));
+ kvp.getValue(),
+ options,
+ mapper,
+ depth + 1));
}
return objret;
}
@@ -2450,10 +2427,10 @@ static CBORObject FromObject(
obj,
options.getUseCamelCase())) {
objret.set(key.getKey(), CBORObject.FromObject(
- key.getValue(),
- options,
- mapper,
- depth + 1));
+ key.getValue(),
+ options,
+ mapper,
+ depth + 1));
}
return objret;
}
@@ -2475,34 +2452,7 @@ static CBORObject FromObject(
* @throws NullPointerException The parameter {@code bigintTag} is null.
*/
public CBORObject WithTag(EInteger bigintTag) {
- if (bigintTag == null) {
- throw new NullPointerException("bigintTag");
- }
- if (bigintTag.signum() < 0) {
- throw new IllegalArgumentException("tagEInt's sign(" + bigintTag.signum() +
- ") is less than 0");
- }
- if (bigintTag.CanFitInInt32()) {
- // Low-numbered, commonly used tags
- return this.WithTag(bigintTag.ToInt32Checked());
- } else {
- if (bigintTag.compareTo(UInt64MaxValue) > 0) {
- throw new IllegalArgumentException(
- "tag more than 18446744073709551615 (" + bigintTag + ")");
- }
- int tagLow = 0;
- int tagHigh = 0;
- byte[] bytes = bigintTag.ToBytes(true);
- for (int i = 0; i < Math.min(4, bytes.length); ++i) {
- int b = ((int)bytes[i]) & 0xff;
- tagLow = (tagLow | (((int)b) << (i * 8)));
- }
- for (int i = 4; i < Math.min(8, bytes.length); ++i) {
- int b = ((int)bytes[i]) & 0xff;
- tagHigh = (tagHigh | (((int)b) << (i * 8)));
- }
- return new CBORObject(this, tagLow, tagHigh);
- }
+ return FromObjectAndTag(this, bigintTag);
}
/**
@@ -2544,7 +2494,25 @@ public static CBORObject FromObjectAndTag(
throw new IllegalArgumentException(
"tag more than 18446744073709551615 (" + bigintTag + ")");
}
- return FromObject(valueOb).WithTag(bigintTag);
+ CBORObject c = FromObject(valueOb);
+ if (bigintTag.CanFitInInt32()) {
+ // Low-numbered, commonly used tags
+ return FromObjectAndTag(c, bigintTag.ToInt32Checked());
+ } else {
+ int tagLow = 0;
+ int tagHigh = 0;
+ byte[] bytes = bigintTag.ToBytes(true);
+ for (int i = 0; i < Math.min(4, bytes.length); ++i) {
+ int b = ((int)bytes[i]) & 0xff;
+ tagLow = (tagLow | (((int)b) << (i * 8)));
+ }
+ for (int i = 4; i < Math.min(8, bytes.length); ++i) {
+ int b = ((int)bytes[i]) & 0xff;
+ tagHigh = (tagHigh | (((int)b) << (i * 8)));
+ }
+ CBORObject c2 = new CBORObject(c, tagLow, tagHigh);
+ return c2;
+ }
}
/**
@@ -2563,11 +2531,7 @@ public static CBORObject FromObjectAndTag(
* @throws IllegalArgumentException The parameter {@code smallTag} is less than 0.
*/
public CBORObject WithTag(int smallTag) {
- if (smallTag < 0) {
- throw new IllegalArgumentException("smallTag(" + smallTag +
- ") is less than 0");
- }
- return new CBORObject(this, smallTag, 0);
+ return FromObjectAndTag(this, smallTag);
}
/**
@@ -2601,7 +2565,9 @@ public static CBORObject FromObjectAndTag(
throw new IllegalArgumentException("smallTag(" + smallTag +
") is less than 0");
}
- return FromObject(valueObValue).WithTag(smallTag);
+ CBORObject c = FromObject(valueObValue);
+ c = new CBORObject(c, smallTag, 0);
+ return c;
}
/**
@@ -2629,8 +2595,8 @@ public static CBORObject FromSimpleValue(int simpleValue) {
return FixedObjects[0xe0 + simpleValue];
}
return new CBORObject(
- CBORObjectTypeSimpleValue,
- simpleValue);
+ CBORObjectTypeSimpleValue,
+ simpleValue);
}
/**
@@ -2674,24 +2640,6 @@ public static CBORObject NewArray() {
return new CBORObject(CBORObjectTypeArray, new ArrayList());
}
- static CBORObject NewArray(CBORObject o1, CBORObject o2) {
- ArrayList list = new ArrayList(2);
- list.add(o1);
- list.add(o2);
- return new CBORObject(CBORObjectTypeArray, list);
- }
-
- static CBORObject NewArray(
- CBORObject o1,
- CBORObject o2,
- CBORObject o3) {
- ArrayList list = new ArrayList(2);
- list.add(o1);
- list.add(o2);
- list.add(o3);
- return new CBORObject(CBORObjectTypeArray, list);
- }
-
/**
* Creates a new empty CBOR map.
* @return A new CBOR map.
@@ -2699,7 +2647,7 @@ static CBORObject NewArray(
public static CBORObject NewMap() {
return new CBORObject(
CBORObjectTypeMap,
- new TreeMap());
+ new HashMap());
}
/**
@@ -2927,7 +2875,7 @@ public static CBORObject ReadJSON(
* does not begin with a record separator byte (0x1e).
*/
public static CBORObject[] ReadJSONSequence(InputStream stream, JSONOptions
- jsonoptions) throws java.io.IOException {
+jsonoptions) throws java.io.IOException {
if (stream == null) {
throw new NullPointerException("stream");
}
@@ -2940,9 +2888,9 @@ public static CBORObject[] ReadJSONSequence(InputStream stream, JSONOptions
try {
int[] nextchar = new int[1];
CBORObject[] objlist = CBORJson.ParseJSONSequence(
- reader,
- jsonoptions,
- nextchar);
+ reader,
+ jsonoptions,
+ nextchar);
if (nextchar[0] != -1) {
reader.RaiseError("End of data stream not reached");
}
@@ -2991,9 +2939,9 @@ public static CBORObject ReadJSON(
try {
int[] nextchar = new int[1];
CBORObject obj = CBORJson.ParseJSONValue(
- reader,
- jsonoptions,
- nextchar);
+ reader,
+ jsonoptions,
+ nextchar);
if (nextchar[0] != -1) {
reader.RaiseError("End of data stream not reached");
}
@@ -3097,7 +3045,7 @@ public static CBORObject FromJSONBytes(
* length minus {@code offset} is less than {@code count}.
*/
public static CBORObject FromJSONBytes(byte[] bytes, int offset, int
- count) {
+count) {
return FromJSONBytes(bytes, offset, count, JSONOptions.Default);
}
@@ -3147,35 +3095,35 @@ public static CBORObject FromJSONBytes(
}
if (offset < 0) {
throw new IllegalArgumentException("offset (" + offset + ") is not greater" +
- "\u0020or equal to 0");
+"\u0020or equal to 0");
}
if (offset > bytes.length) {
throw new IllegalArgumentException("offset (" + offset + ") is not less or" +
- "\u0020equal to " + bytes.length);
+"\u0020equal to " + bytes.length);
}
if (count < 0) {
throw new IllegalArgumentException("count (" + count + ") is not greater or" +
- "\u0020equal to 0");
+"\u0020equal to 0");
}
if (count > bytes.length) {
throw new IllegalArgumentException("count (" + count + ") is not less or" +
- "\u0020equal to " + bytes.length);
+"\u0020equal to " + bytes.length);
}
if (bytes.length - offset < count) {
throw new IllegalArgumentException("bytes's length minus " + offset + " (" +
- (bytes.length - offset) + ") is not greater or equal to " + count);
+(bytes.length - offset) + ") is not greater or equal to " + count);
}
if (count == 0) {
throw new CBORException("Byte array is empty");
}
if (bytes[offset] >= 0x01 && bytes[offset] <= 0x7f && count >= 2 &&
- bytes[offset + 1] != 0) {
+bytes[offset + 1] != 0) {
// UTF-8 JSON bytes
return CBORJson2.ParseJSONValue(
- bytes,
- offset,
- offset + count,
- jsonoptions);
+ bytes,
+ offset,
+ offset + count,
+ jsonoptions);
} else {
// Other than UTF-8 without byte order mark
try {
@@ -3334,7 +3282,7 @@ public static void Write(EFloat bignum, OutputStream stream) throws java.io.IOEx
if (exponent.CanFitInInt64()) {
stream.write(0xc5); // tag 5
stream.write(0x82); // array, length 2
- } else if (exponent.GetSignedBitLengthAsInt64() > 64) {
+ } else if (exponent.GetSignedBitLengthAsEInteger().compareTo(64) > 0) {
stream.write(0xd9); // tag 265
stream.write(0x01);
stream.write(0x09);
@@ -3404,7 +3352,7 @@ public static void Write(EDecimal bignum, OutputStream stream) throws java.io.IO
if (exponent.CanFitInInt64()) {
stream.write(0xc4); // tag 4
stream.write(0x82); // array, length 2
- } else if (exponent.GetSignedBitLengthAsInt64() > 64) {
+ } else if (exponent.GetSignedBitLengthAsEInteger().compareTo(64) > 0) {
stream.write(0xd9); // tag 264
stream.write(0x01);
stream.write(0x08);
@@ -4037,7 +3985,7 @@ public EDecimal AsEDecimal() {
* @throws IllegalStateException This object does not represent a number (for
* the purposes of this method, infinity and not-a-number values, but
* not {@code CBORObject.Null}, are considered numbers).
- * @deprecated Instead, use.getToObject()<PeterO.Numbers.EFloat>\u0028) in.getNET()
+ * @deprecated Instead, use.getToObject()<PeterO.Numbers.EFloat>\u0028) in.NET
* or \u0020.getToObject()\u0028com.upokecenter.numbers.EFloat.class)
* in\u0020Java.
*/
@@ -4071,8 +4019,8 @@ public ERational AsERational() {
* CBORObject.Null, are considered numbers).
* @throws ArithmeticException This object's value exceeds the range of a 16-bit
* signed integer.
- * @deprecated Instead, use the following:\u0020\u0028cbor.AsNumber().ToInt16Checked()),
- * or\u0020.getToObject()<short>() in\u0020.getNET().
+ * @deprecated Instead, use the following:\u0020\u0028cbor.AsNumber().ToInt16Checked()), or
+ *.ToObject<short>() in\u0020.NET.
*/
@Deprecated
public short AsInt16() {
@@ -4291,7 +4239,7 @@ public int AsInt32() {
* @throws ArithmeticException This object's value exceeds the range of a 64-bit
* signed integer.
* @deprecated Instead, use the following:\u0020\u0028cbor.AsNumber().ToInt64Checked()), or
- *.ToObject<long>()\u0020in.getNET().
+ *.ToObject<long>() in.NET.
*/
@Deprecated
public long AsInt64() {
@@ -4329,11 +4277,7 @@ public String AsString() {
case CBORObjectTypeTextString: {
return (String)this.getThisItem();
}
- case CBORObjectTypeTextStringUtf8: {
- return DataUtilities.GetUtf8String((byte[])this.getThisItem(), false);
- }
- default:
- throw new IllegalStateException("Not a text String type");
+ default: throw new IllegalStateException("Not a text String type");
}
}
@@ -4419,7 +4363,7 @@ public boolean CanFitInSingle() {
* discarding its fractional part, would be -(2^31) or greater, and
* less than 2^31; otherwise, {@code false}.
* @deprecated Instead, use the following: \u0028cbor.CanValueFitInInt32()\u0020if only
- * integers of any tag are allowed, or\u0020\u0028cbor.isNumber()
+ * integers of any tag are allowed, or \u0028cbor.isNumber()
* &&\u0020cbor.AsNumber().CanTruncatedIntFitInInt32()).
*/
@Deprecated
@@ -4437,7 +4381,7 @@ public boolean CanTruncatedIntFitInInt32() {
* discarding its fractional part, would be -(2^63) or greater, and
* less than 2^63; otherwise, {@code false}.
* @deprecated Instead, use the following: \u0028cbor.CanValueFitInInt64()\u0020if only
- * integers of any tag are allowed, or\u0020\u0028cbor.isNumber()
+ * integers of any tag are allowed, or \u0028cbor.isNumber()
* &&\u0020cbor.AsNumber().CanTruncatedIntFitInInt64()).
*/
@Deprecated
@@ -4517,8 +4461,7 @@ public int compareTo(CBORObject other) {
other.EncodeToBytes());
break;
}
- case CBORObjectTypeByteString:
- case CBORObjectTypeTextStringUtf8: {
+ case CBORObjectTypeByteString: {
cmp = CBORUtilities.ByteArrayCompareLengthFirst((byte[])objA,
(byte[])objB);
break;
@@ -4529,6 +4472,11 @@ public int compareTo(CBORObject other) {
cmp = CBORUtilities.CompareStringsAsUtf8LengthFirst(
strA,
strB);
+ if (cmp < -1) {
+ cmp = CBORUtilities.ByteArrayCompare(
+ this.EncodeToBytes(),
+ other.EncodeToBytes());
+ }
break;
}
case CBORObjectTypeArray: {
@@ -4569,21 +4517,10 @@ public int compareTo(CBORObject other) {
cmp = CBORUtilities.ByteArrayCompare(
this.EncodeToBytes(),
other.EncodeToBytes());
- } else if (typeB == CBORObjectTypeTextString && typeA ==
- CBORObjectTypeTextStringUtf8) {
- cmp = -CBORUtilities.CompareUtf16Utf8LengthFirst(
- (String)objB,
- (byte[])objA);
- } else if (typeA == CBORObjectTypeTextString && typeB ==
- CBORObjectTypeTextStringUtf8) {
- cmp = CBORUtilities.CompareUtf16Utf8LengthFirst(
- (String)objA,
- (byte[])objB);
} else {
/* NOTE: itemtypeValue numbers are ordered such that they
// correspond to the lexicographical order of their CBOR encodings
- // (with the exception of Integer and EInteger together,
- // and TextString and TextStringUtf8 together which
+ // (with the exception of Integer and EInteger together, which
// are handled above) */
cmp = (typeA < typeB) ? -1 : 1;
}
@@ -4762,13 +4699,6 @@ public byte[] EncodeToBytes(CBOREncodeOptions options) {
}
break;
}
- case CBORObjectTypeTextStringUtf8: {
- if (!tagged && !options.getUseIndefLengthStrings()) {
- byte[] bytes = (byte[])this.getThisItem();
- return SerializeUtf8(bytes);
- }
- break;
- }
case CBORObjectTypeSimpleValue: {
if (tagged) {
byte[] simpleBytes = new byte[] { tagbyte, (byte)0xf4 };
@@ -4877,24 +4807,11 @@ public boolean equals(CBORObject other) {
if (this == otherValue) {
return true;
}
- if (this.itemtypeValue == CBORObjectTypeTextString &&
- otherValue.itemtypeValue == CBORObjectTypeTextStringUtf8) {
- return CBORUtilities.StringEqualsUtf8(
- (String)this.itemValue,
- (byte[])otherValue.itemValue);
- }
- if (otherValue.itemtypeValue == CBORObjectTypeTextString &&
- this.itemtypeValue == CBORObjectTypeTextStringUtf8) {
- return CBORUtilities.StringEqualsUtf8(
- (String)otherValue.itemValue,
- (byte[])this.itemValue);
- }
if (this.itemtypeValue != otherValue.itemtypeValue) {
return false;
}
switch (this.itemtypeValue) {
case CBORObjectTypeByteString:
- case CBORObjectTypeTextStringUtf8:
return CBORUtilities.ByteArrayEquals(
(byte[])this.itemValue,
((otherValue.itemValue instanceof byte[]) ? (byte[])otherValue.itemValue : null));
@@ -4950,10 +4867,6 @@ public byte[] GetByteString() {
itemHashCode =
CBORUtilities.ByteArrayHashCode(this.GetByteString());
break;
- case CBORObjectTypeTextStringUtf8:
- itemHashCode = CBORUtilities.Utf8HashCode(
- (byte[])this.itemValue);
- break;
case CBORObjectTypeMap:
itemHashCode = CBORMapHashCode(this.AsMap());
break;
@@ -4961,8 +4874,7 @@ public byte[] GetByteString() {
itemHashCode = CBORArrayHashCode(this.AsList());
break;
case CBORObjectTypeTextString:
- itemHashCode = CBORUtilities.StringHashCode(
- (String)this.itemValue);
+ itemHashCode = StringHashCode((String)this.itemValue);
break;
case CBORObjectTypeSimpleValue:
itemHashCode = ((Integer)this.itemValue).intValue();
@@ -5097,7 +5009,8 @@ public boolean HasMostInnerTag(EInteger bigTagValue) {
throw new IllegalArgumentException("bigTagValue(" + bigTagValue +
") is less than 0");
}
- return (!this.isTagged()) ? false : this.getMostInnerTag().equals(bigTagValue);
+ return (!this.isTagged()) ? false :
+this.getMostInnerTag().equals(bigTagValue);
}
/**
@@ -5133,7 +5046,8 @@ public boolean HasMostOuterTag(EInteger bigTagValue) {
throw new IllegalArgumentException("bigTagValue(" + bigTagValue +
") is less than 0");
}
- return (!this.isTagged()) ? false : this.getMostOuterTag().equals(bigTagValue);
+ return (!this.isTagged()) ? false :
+this.getMostOuterTag().equals(bigTagValue);
}
/**
@@ -6008,7 +5922,8 @@ public static int WriteValue(
return 1;
} else if (value < 32) {
throw new IllegalArgumentException("value is from 24 to 31 and major" +
- "\u0020type" + "\u0020is 7");
+"\u0020type" +
+ "\u0020is 7");
} else {
outputStream.write((byte)0xf8);
outputStream.write((byte)value);
@@ -6192,9 +6107,8 @@ public void WriteTo(OutputStream stream, CBOREncodeOptions options) throws java.
Write((EInteger)this.getThisItem(), stream);
break;
}
- case CBORObjectTypeByteString:
- case CBORObjectTypeTextStringUtf8: {
- byte[] arr = (byte[])this.getThisItem();
+ case CBORObjectTypeByteString: {
+ byte[] arr = this.GetByteString();
WritePositiveInt(
(this.getType() == CBORType.ByteString) ? 2 : 3,
arr.length,
@@ -6240,10 +6154,6 @@ static CBORObject FromRaw(byte[] bytes) {
return new CBORObject(CBORObjectTypeByteString, bytes);
}
- static CBORObject FromRawUtf8(byte[] bytes) {
- return new CBORObject(CBORObjectTypeTextStringUtf8, bytes);
- }
-
static CBORObject FromRaw(String str) {
return new CBORObject(CBORObjectTypeTextString, str);
}
@@ -6272,6 +6182,13 @@ static CBORObject GetFixedLengthObject(
return fixedObj;
}
int majortype = firstbyte >> 5;
+ if (firstbyte >= 0x61 && firstbyte < 0x78) {
+ // text String length 1 to 23
+ String s = GetOptimizedStringIfShortAscii(data, 0);
+ if (s != null) {
+ return new CBORObject(CBORObjectTypeTextString, s);
+ }
+ }
if ((firstbyte & 0x1c) == 0x18) {
// contains 1 to 8 extra bytes of additional information
long uadditional = 0;
@@ -6339,8 +6256,8 @@ static CBORObject GetFixedLengthObject(
((int)uadditional));
}
return new CBORObject(
- CBORObjectTypeDouble,
- dblbits);
+ CBORObjectTypeDouble,
+ dblbits);
}
if (firstbyte == 0xf8) {
if ((int)uadditional < 32) {
@@ -6360,12 +6277,14 @@ static CBORObject GetFixedLengthObject(
return new CBORObject(CBORObjectTypeByteString, ret);
}
if (majortype == 3) { // short text String
- byte[] ret = new byte[firstbyte - 0x60];
- System.arraycopy(data, 1, ret, 0, firstbyte - 0x60);
- if (!CBORUtilities.CheckUtf8(ret)) {
- throw new CBORException("Invalid encoding");
- }
- return new CBORObject(CBORObjectTypeTextStringUtf8, ret);
+ StringBuilder ret = new StringBuilder(firstbyte - 0x60);
+ DataUtilities.ReadUtf8FromBytes(
+ data,
+ 1,
+ firstbyte - 0x60,
+ ret,
+ false);
+ return new CBORObject(CBORObjectTypeTextString, ret.toString());
}
if (firstbyte == 0x80) {
// empty array
@@ -6431,6 +6350,21 @@ private static int CBORArrayHashCode(List list) {
return ret;
}
+ private static int StringHashCode(String str) {
+ if (str == null) {
+ return 0;
+ }
+ int ret = 19;
+ int count = str.length();
+ {
+ ret = (ret * 31) + count;
+ for (int i = 0; i < count; ++i) {
+ ret = (ret * 31) + (int)str.charAt(i);
+ }
+ }
+ return ret;
+ }
+
private static boolean StringEquals(String str, String str2) {
if (str == str2) {
return true;
@@ -6480,11 +6414,10 @@ private static int CBORMapHashCode(Map
a) {
// To simplify matters, we use just the count of
// the map as the basis for the hash code. More complicated
- // hash code calculation would involve the sum of the hash codes of
- // the map's key-value pairs (an approach that works regardless of the order
- // in which map keys are iterated, because wraparound addition
- // is commutative and associative), but this could take much more time
- // to calculate, especially if the keys and values are very big.
+ // hash code calculation would generally involve defining
+ // how CBORObjects ought to be compared (since a stable
+ // sort order is necessary for two equal maps to have the
+ // same hash code), which is much too difficult to do.
return a.size() * 19;
}
@@ -6593,36 +6526,6 @@ private static String GetOptimizedStringIfShortAscii(
return null;
}
- private static byte[] SerializeUtf8(byte[] utf8) {
- byte[] bytes;
- if (utf8.length < 24) {
- bytes = new byte[utf8.length + 1];
- bytes[0] = (byte)(utf8.length | 0x60);
- System.arraycopy(utf8, 0, bytes, 1, utf8.length);
- return bytes;
- }
- if (utf8.length <= 0xffL) {
- bytes = new byte[utf8.length + 2];
- bytes[0] = (byte)0x78;
- bytes[1] = (byte)utf8.length;
- System.arraycopy(utf8, 0, bytes, 2, utf8.length);
- return bytes;
- }
- if (utf8.length <= 0xffffL) {
- bytes = new byte[utf8.length + 3];
- bytes[0] = (byte)0x79;
- bytes[1] = (byte)((utf8.length >> 8) & 0xff);
- bytes[2] = (byte)(utf8.length & 0xff);
- System.arraycopy(utf8, 0, bytes, 3, utf8.length);
- return bytes;
- }
- byte[] posbytes = GetPositiveInt64Bytes(3, utf8.length);
- bytes = new byte[utf8.length + posbytes.length];
- System.arraycopy(posbytes, 0, bytes, 0, posbytes.length);
- System.arraycopy(utf8, 0, bytes, posbytes.length, utf8.length);
- return bytes;
- }
-
private static byte[] GetPositiveInt64Bytes(int type, long value) {
if (value < 0) {
throw new IllegalArgumentException("value(" + value + ") is less than " +
@@ -6815,13 +6718,13 @@ private static List