Skip to content

Commit ae1b4f4

Browse files
committed
More testing, some refactoring wrt #201
1 parent 6cedcc4 commit ae1b4f4

File tree

2 files changed

+119
-45
lines changed

2 files changed

+119
-45
lines changed

cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java

+33-44
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,25 @@ public void writeArray(int[] array, int offset, int length) throws IOException
589589
// short-cut, do not create child array context etc
590590
_verifyValueWrite("write int array");
591591
_writeLengthMarker(PREFIX_TYPE_ARRAY, length);
592-
for (int i = offset, end = offset+length; i < end; ++i) {
593-
_writeIntNoCheck(array[i]);
592+
593+
if (_cfgMinimalInts) {
594+
for (int i = offset, end = offset+length; i < end; ++i) {
595+
final int value = array[i];
596+
if (value < 0) {
597+
_writeIntMinimal(PREFIX_TYPE_INT_NEG, -value - 1);
598+
} else {
599+
_writeIntMinimal(PREFIX_TYPE_INT_POS, value);
600+
}
601+
}
602+
} else {
603+
for (int i = offset, end = offset+length; i < end; ++i) {
604+
final int value = array[i];
605+
if (value < 0) {
606+
_writeIntFull(PREFIX_TYPE_INT_NEG, -value - 1);
607+
} else {
608+
_writeIntFull(PREFIX_TYPE_INT_POS, value);
609+
}
610+
}
594611
}
595612
}
596613

@@ -626,33 +643,24 @@ private final void _pushRemainingElements() {
626643
_elementCounts[_elementCountsPtr++] = _currentRemainingElements;
627644
}
628645

629-
private final void _writeIntNoCheck(int i) throws IOException {
630-
int marker;
631-
if (i < 0) {
632-
i = -i - 1;
633-
marker = PREFIX_TYPE_INT_NEG;
634-
} else {
635-
marker = PREFIX_TYPE_INT_POS;
636-
}
637-
638-
// if ((_outputTail + needed) >= _outputEnd) { _flushBuffer(); }
646+
private final void _writeIntMinimal(int markerBase, int i) throws IOException
647+
{
639648
_ensureRoomForOutput(5);
640-
641649
byte b0;
642-
if (_cfgMinimalInts) {
650+
if (i >= 0) {
643651
if (i < 24) {
644-
_outputBuffer[_outputTail++] = (byte) (marker + i);
652+
_outputBuffer[_outputTail++] = (byte) (markerBase + i);
645653
return;
646654
}
647655
if (i <= 0xFF) {
648-
_outputBuffer[_outputTail++] = (byte) (marker + SUFFIX_UINT8_ELEMENTS);
656+
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT8_ELEMENTS);
649657
_outputBuffer[_outputTail++] = (byte) i;
650658
return;
651659
}
652660
b0 = (byte) i;
653661
i >>= 8;
654662
if (i <= 0xFF) {
655-
_outputBuffer[_outputTail++] = (byte) (marker + SUFFIX_UINT16_ELEMENTS);
663+
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT16_ELEMENTS);
656664
_outputBuffer[_outputTail++] = (byte) i;
657665
_outputBuffer[_outputTail++] = b0;
658666
return;
@@ -661,46 +669,27 @@ private final void _writeIntNoCheck(int i) throws IOException {
661669
b0 = (byte) i;
662670
i >>= 8;
663671
}
664-
_outputBuffer[_outputTail++] = (byte) (marker + SUFFIX_UINT32_ELEMENTS);
672+
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT32_ELEMENTS);
665673
_outputBuffer[_outputTail++] = (byte) (i >> 16);
666674
_outputBuffer[_outputTail++] = (byte) (i >> 8);
667675
_outputBuffer[_outputTail++] = (byte) i;
668676
_outputBuffer[_outputTail++] = b0;
669677
}
670678

671-
private final void _writeIntMinimal(int markerBase, int i) throws IOException
679+
private final void _writeIntFull(int markerBase, int i) throws IOException
672680
{
681+
// if ((_outputTail + needed) >= _outputEnd) { _flushBuffer(); }
673682
_ensureRoomForOutput(5);
674-
byte b0;
675-
if (i >= 0) {
676-
if (i < 24) {
677-
_outputBuffer[_outputTail++] = (byte) (markerBase + i);
678-
return;
679-
}
680-
if (i <= 0xFF) {
681-
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT8_ELEMENTS);
682-
_outputBuffer[_outputTail++] = (byte) i;
683-
return;
684-
}
685-
b0 = (byte) i;
686-
i >>= 8;
687-
if (i <= 0xFF) {
688-
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT16_ELEMENTS);
689-
_outputBuffer[_outputTail++] = (byte) i;
690-
_outputBuffer[_outputTail++] = b0;
691-
return;
692-
}
693-
} else {
694-
b0 = (byte) i;
695-
i >>= 8;
696-
}
683+
697684
_outputBuffer[_outputTail++] = (byte) (markerBase + SUFFIX_UINT32_ELEMENTS);
685+
_outputBuffer[_outputTail++] = (byte) (i >> 24);
698686
_outputBuffer[_outputTail++] = (byte) (i >> 16);
699687
_outputBuffer[_outputTail++] = (byte) (i >> 8);
700688
_outputBuffer[_outputTail++] = (byte) i;
701-
_outputBuffer[_outputTail++] = b0;
702689
}
703-
690+
691+
// Helper method that works like `writeNumber(long)` but DOES NOT
692+
// check internal output state. It does, however, check need for minimization
704693
private final void _writeLongNoCheck(long l) throws IOException {
705694
if (_cfgMinimalInts) {
706695
if (l >= 0) {

cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/gen/ArrayGenerationTest.java

+86-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,69 @@ public void testDoubleArray() throws Exception
3131
_testDoubleArray();
3232
}
3333

34-
public void testMinimalIntValues2() throws Exception
34+
public void testMinimalIntValuesForInt() throws Exception
35+
{
36+
// Array with 3 values, with different sizing
37+
_testMinimalIntValuesForInt(1, -1, 3, 11); // single-byte
38+
_testMinimalIntValuesForInt(200, -200, 5, 11); // two-byte (marker, 0xFF)
39+
_testMinimalIntValuesForInt(0xC831, -50000, 7, 11); // three-byte (marker, 0xFFFF)
40+
_testMinimalIntValuesForInt(0x35690001, -(0x7FFFFFF0), 11, 11); // full
41+
}
42+
43+
private void _testMinimalIntValuesForInt(int v1, int v2,
44+
int minLen, int fullLen) throws Exception
45+
{
46+
final int[] input = new int[] { v1, v2 };
47+
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
48+
CBORGenerator gen = FACTORY.createGenerator(bytes);
49+
assertTrue(gen.isEnabled(CBORGenerator.Feature.WRITE_MINIMAL_INTS));
50+
gen.writeArray(input, 0, 2);
51+
gen.close();
52+
53+
// With default settings, should get:
54+
byte[] encoded = bytes.toByteArray();
55+
assertEquals(minLen, encoded.length);
56+
57+
// then verify contents
58+
59+
CBORParser p = FACTORY.createParser(encoded);
60+
assertToken(JsonToken.START_ARRAY, p.nextToken());
61+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
62+
assertEquals(NumberType.INT, p.getNumberType());
63+
assertEquals(input[0], p.getIntValue());
64+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
65+
assertEquals(NumberType.INT, p.getNumberType());
66+
assertEquals(input[1], p.getIntValue());
67+
assertToken(JsonToken.END_ARRAY, p.nextToken());
68+
p.close();
69+
70+
// but then also check without minimization
71+
bytes = new ByteArrayOutputStream();
72+
gen = FACTORY.createGenerator(bytes);
73+
gen.disable(CBORGenerator.Feature.WRITE_MINIMAL_INTS);
74+
75+
gen.writeArray(input, 0, 2);
76+
gen.close();
77+
78+
// With default settings, should get:
79+
encoded = bytes.toByteArray();
80+
assertEquals(fullLen, encoded.length);
81+
82+
// then verify contents
83+
84+
p = FACTORY.createParser(encoded);
85+
assertToken(JsonToken.START_ARRAY, p.nextToken());
86+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
87+
assertEquals(NumberType.INT, p.getNumberType());
88+
assertEquals(input[0], p.getIntValue());
89+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
90+
assertEquals(NumberType.INT, p.getNumberType());
91+
assertEquals(input[1], p.getIntValue());
92+
assertToken(JsonToken.END_ARRAY, p.nextToken());
93+
p.close();
94+
}
95+
96+
public void testMinimalIntValuesForLong() throws Exception
3597
{
3698
// Array with 2 values that can't be passed as `int`s but DO fit
3799
// CBOR 5-byte int (sign + 32-bits)
@@ -63,6 +125,29 @@ public void testMinimalIntValues2() throws Exception
63125
p.close();
64126

65127
// but then also check without minimization
128+
bytes = new ByteArrayOutputStream();
129+
gen = FACTORY.createGenerator(bytes);
130+
gen.disable(CBORGenerator.Feature.WRITE_MINIMAL_INTS);
131+
132+
gen.writeArray(input, 0, 2);
133+
gen.close();
134+
135+
// With default settings, should get:
136+
encoded = bytes.toByteArray();
137+
assertEquals(19, encoded.length);
138+
139+
// then verify contents
140+
141+
p = FACTORY.createParser(encoded);
142+
assertToken(JsonToken.START_ARRAY, p.nextToken());
143+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
144+
assertEquals(NumberType.LONG, p.getNumberType());
145+
assertEquals(input[0], p.getLongValue());
146+
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
147+
assertEquals(NumberType.LONG, p.getNumberType());
148+
assertEquals(input[1], p.getLongValue());
149+
assertToken(JsonToken.END_ARRAY, p.nextToken());
150+
p.close();
66151
}
67152

68153
private void _testIntArray() throws Exception {

0 commit comments

Comments
 (0)