Skip to content

Commit e1363f4

Browse files
committed
update project
1 parent 9dcb6c8 commit e1363f4

File tree

3 files changed

+177
-42
lines changed

3 files changed

+177
-42
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.upokecenter.cbor;
2+
3+
/**
4+
* Specifies options for encoding CBOR objects to bytes.
5+
*/
6+
public final class CBOREncodeOptions {
7+
/**
8+
* No special options for encoding. Value: 0.
9+
*/
10+
public static final CBOREncodeOptions None =
11+
new CBOREncodeOptions(0);
12+
13+
/**
14+
* Always encode strings with a definite-length encoding. Value: 1.
15+
*/
16+
public static final CBOREncodeOptions NoIndefLengthStrings =
17+
new CBOREncodeOptions(1);
18+
19+
private int value;
20+
21+
/**
22+
* Gets this options object's value.
23+
* @return This options object's value.
24+
*/
25+
public final int getValue() {
26+
return this.value;
27+
}
28+
29+
private CBOREncodeOptions(int value) {
30+
this.value = value;
31+
}
32+
33+
/**
34+
* Combines the flags of this options object with another options object.
35+
* @param o A CBOREncodeOptions object. (2).
36+
* @return A CBOREncodeOptions object.
37+
*/
38+
public CBOREncodeOptions Or(CBOREncodeOptions o) {
39+
return new CBOREncodeOptions(this.value | o.value);
40+
}
41+
42+
/**
43+
* Returns an options object whose flags are shared by this and another options
44+
* object.
45+
* @param o A CBOREncodeOptions object. (2).
46+
* @return A CBOREncodeOptions object.
47+
*/
48+
public CBOREncodeOptions And(CBOREncodeOptions o) {
49+
return new CBOREncodeOptions(this.value & o.value);
50+
}
51+
}

src/main/java/com/upokecenter/cbor/CBORObject.java

Lines changed: 105 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,14 +2182,16 @@ public static CBORObject Read(InputStream stream) {
21822182

21832183
private static void WriteObjectArray(
21842184
List<CBORObject> list,
2185-
OutputStream outputStream) throws java.io.IOException {
2186-
WriteObjectArray(list, outputStream, null);
2185+
OutputStream outputStream,
2186+
CBOREncodeOptions options) throws java.io.IOException {
2187+
WriteObjectArray(list, outputStream, null, options);
21872188
}
21882189

21892190
private static void WriteObjectMap(
21902191
Map<CBORObject, CBORObject> map,
2191-
OutputStream outputStream) throws java.io.IOException {
2192-
WriteObjectMap(map, outputStream, null);
2192+
OutputStream outputStream,
2193+
CBOREncodeOptions options) throws java.io.IOException {
2194+
WriteObjectMap(map, outputStream, null, options);
21932195
}
21942196

21952197
private static List<Object> PushObject(
@@ -2213,20 +2215,21 @@ private static List<Object> WriteChildObject(
22132215
Object parentThisItem,
22142216
CBORObject child,
22152217
OutputStream outputStream,
2216-
List<Object> stack) throws java.io.IOException {
2218+
List<Object> stack,
2219+
CBOREncodeOptions options) throws java.io.IOException {
22172220
if (child == null) {
22182221
outputStream.write(0xf6);
22192222
} else {
22202223
int type = child.getItemType();
22212224
if (type == CBORObjectTypeArray) {
22222225
stack = PushObject(stack, parentThisItem, child.getThisItem());
22232226
child.WriteTags(outputStream);
2224-
WriteObjectArray(child.AsList(), outputStream, stack);
2227+
WriteObjectArray(child.AsList(), outputStream, stack, options);
22252228
stack.remove(stack.size() - 1);
22262229
} else if (type == CBORObjectTypeMap) {
22272230
stack = PushObject(stack, parentThisItem, child.getThisItem());
22282231
child.WriteTags(outputStream);
2229-
WriteObjectMap(child.AsMap(), outputStream, stack);
2232+
WriteObjectMap(child.AsMap(), outputStream, stack, options);
22302233
stack.remove(stack.size() - 1);
22312234
} else {
22322235
child.WriteTo(outputStream);
@@ -2238,25 +2241,37 @@ private static List<Object> WriteChildObject(
22382241
private static void WriteObjectArray(
22392242
List<CBORObject> list,
22402243
OutputStream outputStream,
2241-
List<Object> stack) throws java.io.IOException {
2244+
List<Object> stack,
2245+
CBOREncodeOptions options) throws java.io.IOException {
22422246
Object thisObj = list;
22432247
WritePositiveInt(4, list.size(), outputStream);
22442248
for (CBORObject i : list) {
2245-
stack = WriteChildObject(thisObj, i, outputStream, stack);
2249+
stack = WriteChildObject(thisObj, i, outputStream, stack, options);
22462250
}
22472251
}
22482252

22492253
private static void WriteObjectMap(
22502254
Map<CBORObject, CBORObject> map,
22512255
OutputStream outputStream,
2252-
List<Object> stack) throws java.io.IOException {
2256+
List<Object> stack,
2257+
CBOREncodeOptions options) throws java.io.IOException {
22532258
Object thisObj = map;
22542259
WritePositiveInt(5, map.size(), outputStream);
22552260
for (Map.Entry<CBORObject, CBORObject> entry : map.entrySet()) {
22562261
CBORObject key = entry.getKey();
22572262
CBORObject value = entry.getValue();
2258-
stack = WriteChildObject(thisObj, key, outputStream, stack);
2259-
stack = WriteChildObject(thisObj, value, outputStream, stack);
2263+
stack = WriteChildObject(
2264+
thisObj,
2265+
key,
2266+
outputStream,
2267+
stack,
2268+
options);
2269+
stack = WriteChildObject(
2270+
thisObj,
2271+
value,
2272+
outputStream,
2273+
stack,
2274+
options);
22602275
}
22612276
}
22622277

@@ -2434,6 +2449,38 @@ public static void Write(String str, OutputStream stream) throws java.io.IOExcep
24342449
}
24352450
}
24362451

2452+
/**
2453+
* Writes a string in CBOR format to a data stream.
2454+
* @param str The string to write. Can be null.
2455+
* @param stream A writable data stream.
2456+
* @param options Options for encoding the data to CBOR.
2457+
* @throws NullPointerException The parameter {@code stream} is null.
2458+
* @throws java.io.IOException An I/O error occurred.
2459+
*/
2460+
public static void Write(
2461+
String str,
2462+
OutputStream stream,
2463+
CBOREncodeOptions options) throws java.io.IOException {
2464+
if (stream == null) {
2465+
throw new NullPointerException("stream");
2466+
}
2467+
if (str == null) {
2468+
stream.write(0xf6); // Write null instead of String
2469+
} else {
2470+
CBOREncodeOptions noIndef =
2471+
options.And(CBOREncodeOptions.NoIndefLengthStrings);
2472+
if (noIndef.getValue() != 0) {
2473+
// NOTE: Length of a String Object won't be higher than the maximum
2474+
// allowed for definite-length strings
2475+
long codePointLength = DataUtilities.GetUtf8Length(str, true);
2476+
WritePositiveInt64(3, codePointLength, stream);
2477+
DataUtilities.WriteUtf8(str, stream, true);
2478+
} else {
2479+
WriteStreamedString(str, stream);
2480+
}
2481+
}
2482+
}
2483+
24372484
/**
24382485
* Writes a binary floating-point number in CBOR format to a data stream as
24392486
* follows: <ul><li>If the value is null, writes the byte 0xF6.</li>
@@ -2660,6 +2707,17 @@ public static void Write(BigInteger bigint, OutputStream stream) throws java.io.
26602707
* @throws java.io.IOException An I/O error occurred.
26612708
*/
26622709
public void WriteTo(OutputStream stream) throws java.io.IOException {
2710+
this.WriteTo(stream, CBOREncodeOptions.None);
2711+
}
2712+
2713+
/**
2714+
* Writes this CBOR object to a data stream.
2715+
* @param stream A writable data stream.
2716+
* @param options Options for encoding the data to CBOR.
2717+
* @throws NullPointerException The parameter {@code stream} is null.
2718+
* @throws java.io.IOException An I/O error occurred.
2719+
*/
2720+
public void WriteTo(OutputStream stream, CBOREncodeOptions options) throws java.io.IOException {
26632721
if (stream == null) {
26642722
throw new NullPointerException("stream");
26652723
}
@@ -2677,9 +2735,9 @@ public void WriteTo(OutputStream stream) throws java.io.IOException {
26772735
stream);
26782736
stream.write(arr, 0, arr.length);
26792737
} else if (type == CBORObjectTypeTextString) {
2680-
Write((String)this.getThisItem(), stream);
2738+
Write((String)this.getThisItem(), stream, options);
26812739
} else if (type == CBORObjectTypeArray) {
2682-
WriteObjectArray(this.AsList(), stream);
2740+
WriteObjectArray(this.AsList(), stream, options);
26832741
} else if (type == CBORObjectTypeExtendedDecimal) {
26842742
ExtendedDecimal dec = (ExtendedDecimal)this.getThisItem();
26852743
Write(dec, stream);
@@ -2690,7 +2748,7 @@ public void WriteTo(OutputStream stream) throws java.io.IOException {
26902748
ExtendedRational flo = (ExtendedRational)this.getThisItem();
26912749
Write(flo, stream);
26922750
} else if (type == CBORObjectTypeMap) {
2693-
WriteObjectMap(this.AsMap(), stream);
2751+
WriteObjectMap(this.AsMap(), stream, options);
26942752
} else if (type == CBORObjectTypeSimpleValue) {
26952753
int value = ((Integer)this.getThisItem()).intValue();
26962754
if (value < 24) {
@@ -2911,6 +2969,15 @@ private static byte[] GetOptimizedBytesIfShortAscii(
29112969
* @return A byte array in CBOR format.
29122970
*/
29132971
public byte[] EncodeToBytes() {
2972+
return this.EncodeToBytes(CBOREncodeOptions.None);
2973+
}
2974+
2975+
/**
2976+
* Gets the binary representation of this data item.
2977+
* @param options Options for encoding the data to CBOR.
2978+
* @return A byte array in CBOR format.
2979+
*/
2980+
public byte[] EncodeToBytes(CBOREncodeOptions options) {
29142981
// For some types, a memory stream is a lot of
29152982
// overhead since the amount of memory the types
29162983
// use is fixed and small
@@ -3014,7 +3081,7 @@ public byte[] EncodeToBytes() {
30143081
try {
30153082
ms = new java.io.ByteArrayOutputStream(16);
30163083

3017-
this.WriteTo(ms);
3084+
this.WriteTo(ms, options);
30183085
return ms.toByteArray();
30193086
}
30203087
finally {
@@ -3042,18 +3109,31 @@ public static void Write(CBORObject value, OutputStream stream) throws java.io.I
30423109
}
30433110
}
30443111

3112+
/**
3113+
* Not documented yet.
3114+
* @param objValue An arbitrary object.
3115+
* @param stream A writable data stream.
3116+
*/
3117+
public static void Write(Object objValue, OutputStream stream) throws java.io.IOException {
3118+
Write(objValue, stream, CBOREncodeOptions.None);
3119+
}
3120+
30453121
/**
30463122
* Writes an arbitrary object to a CBOR data stream. Currently, the following
30473123
* objects are supported: <ul><li>Lists of CBORObject.</li> <li>Maps of
30483124
* CBORObject.</li> <li>Null.</li> <li>Any object accepted by the
30493125
* FromObject static methods.</li> </ul>
30503126
* @param objValue The value to write.
30513127
* @param stream A writable data stream.
3128+
* @param options Options for encoding the data to CBOR.
30523129
* @throws IllegalArgumentException The object's type is not supported.
30533130
* @throws NullPointerException The parameter {@code stream} is null.
30543131
*/
30553132
@SuppressWarnings("unchecked")
3056-
public static void Write(Object objValue, OutputStream stream) throws java.io.IOException {
3133+
public static void Write(
3134+
Object objValue,
3135+
OutputStream stream,
3136+
CBOREncodeOptions options) throws java.io.IOException {
30573137
if (stream == null) {
30583138
throw new NullPointerException("stream");
30593139
}
@@ -3068,11 +3148,17 @@ public static void Write(Object objValue, OutputStream stream) throws java.io.IO
30683148
return;
30693149
}
30703150
if (objValue instanceof List<?>) {
3071-
WriteObjectArray((List<CBORObject>)objValue, stream);
3151+
WriteObjectArray(
3152+
(List<CBORObject>)objValue,
3153+
stream,
3154+
options);
30723155
return;
30733156
}
30743157
if (objValue instanceof Map<?, ?>) {
3075-
WriteObjectMap((Map<CBORObject, CBORObject>)objValue, stream);
3158+
WriteObjectMap(
3159+
(Map<CBORObject, CBORObject>)objValue,
3160+
stream,
3161+
options);
30763162
return;
30773163
}
30783164
FromObject(objValue).WriteTo(stream);

src/test/java/com/upokecenter/test/CBORTest.java

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,13 +1968,13 @@ public void TestCBORFromArray() {
19681968
public void TestHalfPrecision() {
19691969
CBORObject o = CBORObject.DecodeFromBytes(
19701970
new byte[] { (byte)0xf9, 0x7c, 0x00 });
1971-
Assert.assertEquals(Float.POSITIVE_INFINITY, o.AsSingle());
1971+
Assert.assertEquals(Float.POSITIVE_INFINITY, o.AsSingle(), 0f);
19721972
o = CBORObject.DecodeFromBytes(
19731973
new byte[] { (byte)0xf9, 0x00, 0x00 });
19741974
Assert.assertEquals((float)0, o.AsSingle(), 0f);
19751975
o = CBORObject.DecodeFromBytes(
19761976
new byte[] { (byte)0xf9, (byte)0xfc, 0x00 });
1977-
Assert.assertEquals(Float.NEGATIVE_INFINITY, o.AsSingle());
1977+
Assert.assertEquals(Float.NEGATIVE_INFINITY, o.AsSingle(), 0f);
19781978
o = CBORObject.DecodeFromBytes(
19791979
new byte[] { (byte)0xf9, 0x7e, 0x00 });
19801980
if (!(Float.isNaN(o.AsSingle())))Assert.fail();
@@ -2496,33 +2496,31 @@ private static String Repeat(String c, int num) {
24962496
return sb.toString();
24972497
}
24982498

2499+
private void TestTextStringStreamOne(String longString) {
2500+
CBORObject cbor, cbor2;
2501+
cbor = CBORObject.FromObject(longString);
2502+
cbor2 = TestCommon.FromBytesTestAB(cbor.EncodeToBytes());
2503+
Assert.assertEquals(
2504+
longString,
2505+
CBORObject.DecodeFromBytes(cbor.EncodeToBytes()).AsString());
2506+
Assert.assertEquals(
2507+
longString,
2508+
CBORObject.DecodeFromBytes(cbor.EncodeToBytes(
2509+
CBOREncodeOptions.NoIndefLengthStrings)).AsString());
2510+
TestCommon.AssertEqualsHashCode(cbor, cbor2);
2511+
Assert.assertEquals(longString, cbor2.AsString());
2512+
}
2513+
24992514
@Test
25002515
public void TestTextStringStream() {
25012516
CBORObject cbor = TestCommon.FromBytesTestAB(
25022517
new byte[] { 0x7f, 0x61, 0x2e, 0x61, 0x2e, (byte)0xff });
25032518
Assert.assertEquals("..", cbor.AsString());
25042519
// Test streaming of long strings
2505-
String longString = Repeat('x', 200000);
2506-
CBORObject cbor2;
2507-
cbor = CBORObject.FromObject(longString);
2508-
cbor2 = TestCommon.FromBytesTestAB(cbor.EncodeToBytes());
2509-
TestCommon.AssertEqualsHashCode(cbor, cbor2);
2510-
Assert.assertEquals(longString, cbor2.AsString());
2511-
longString = Repeat('\u00e0', 200000);
2512-
cbor = CBORObject.FromObject(longString);
2513-
cbor2 = TestCommon.FromBytesTestAB(cbor.EncodeToBytes());
2514-
TestCommon.AssertEqualsHashCode(cbor, cbor2);
2515-
Assert.assertEquals(longString, cbor2.AsString());
2516-
longString = Repeat('\u3000', 200000);
2517-
cbor = CBORObject.FromObject(longString);
2518-
cbor2 = TestCommon.FromBytesTestAB(cbor.EncodeToBytes());
2519-
TestCommon.AssertEqualsHashCode(cbor, cbor2);
2520-
Assert.assertEquals(longString, cbor2.AsString());
2521-
longString = Repeat("\ud800\udc00", 200000);
2522-
cbor = CBORObject.FromObject(longString);
2523-
cbor2 = TestCommon.FromBytesTestAB(cbor.EncodeToBytes());
2524-
TestCommon.AssertEqualsHashCode(cbor, cbor2);
2525-
Assert.assertEquals(longString, cbor2.AsString());
2520+
this.TestTextStringStreamOne(Repeat('x', 200000));
2521+
this.TestTextStringStreamOne(Repeat('\u00e0', 200000));
2522+
this.TestTextStringStreamOne(Repeat('\u3000', 200000));
2523+
this.TestTextStringStreamOne(Repeat("\ud800\udc00", 200000));
25262524
}
25272525
@Test(expected = CBORException.class)
25282526
public void TestTextStringStreamNoTagsBeforeDefinite() {

0 commit comments

Comments
 (0)