Skip to content

Commit ed3eef6

Browse files
committed
Merge branch '2.x' into 3.x
2 parents ba4ef84 + f0be269 commit ed3eef6

File tree

4 files changed

+256
-0
lines changed

4 files changed

+256
-0
lines changed

cbor/src/main/java/tools/jackson/dataformat/cbor/CBORGenerator.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,21 @@ public JsonGenerator writeNull() throws JacksonException {
938938
return this;
939939
}
940940

941+
/**
942+
* Method for outputting given value as an unsigned integer.
943+
* Can be called in any context where a value is expected
944+
* (Array value, Object field value, root-level value).
945+
*
946+
* @param i Number value to write
947+
* @throws IOException if there is either an underlying I/O problem or encoding
948+
* issue at format layer
949+
* @since 2.20
950+
*/
951+
public void writeNumberUnsigned(int i) throws IOException {
952+
_verifyValueWrite("write number unsigned");
953+
_writeIntMinimal(PREFIX_TYPE_INT_POS, i);
954+
}
955+
941956
@Override
942957
public JsonGenerator writeNumber(short v) throws JacksonException {
943958
// !!! TODO 25-May-2020, tatu: Should we try to check for more optimal form?
@@ -986,6 +1001,34 @@ public JsonGenerator writeNumber(int i) throws JacksonException {
9861001
return this;
9871002
}
9881003

1004+
/**
1005+
* Method for outputting given value as an unsigned integer.
1006+
* Can be called in any context where a value is expected
1007+
* (Array value, Object field value, root-level value).
1008+
*
1009+
* @param l Number value to write
1010+
* @throws IOException if there is either an underlying I/O problem or encoding
1011+
* issue at format layer
1012+
* @since 2.20
1013+
*/
1014+
public void writeNumberUnsigned(long l) throws IOException {
1015+
if (_cfgMinimalInts && l >= 0 && l < 0x100000000L) {
1016+
writeNumberUnsigned((int) l);
1017+
return;
1018+
}
1019+
_verifyValueWrite("write number unsigned");
1020+
_ensureRoomForOutput(9);
1021+
_outputBuffer[_outputTail++] = (byte) (PREFIX_TYPE_INT_POS + SUFFIX_UINT64_ELEMENTS);
1022+
_outputBuffer[_outputTail++] = (byte) (l >> 56);
1023+
_outputBuffer[_outputTail++] = (byte) (l >> 48);
1024+
_outputBuffer[_outputTail++] = (byte) (l >> 40);
1025+
_outputBuffer[_outputTail++] = (byte) (l >> 32);
1026+
_outputBuffer[_outputTail++] = (byte) (l >> 24);
1027+
_outputBuffer[_outputTail++] = (byte) (l >> 16);
1028+
_outputBuffer[_outputTail++] = (byte) (l >> 8);
1029+
_outputBuffer[_outputTail++] = (byte) l;
1030+
}
1031+
9891032
@Override
9901033
public JsonGenerator writeNumber(long l) throws JacksonException {
9911034
_verifyValueWrite("write number");

cbor/src/test/java/tools/jackson/dataformat/cbor/gen/GeneratorSimpleTest.java

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,98 @@ public void testIntValues() throws Exception
189189
(byte) 0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF);
190190
}
191191

192+
@Test
193+
public void testUnsignedIntValues() throws Exception
194+
{
195+
// uint32 max
196+
ByteArrayOutputStream out = new ByteArrayOutputStream();
197+
CBORGenerator gen = cborGenerator(out);
198+
gen.writeNumberUnsigned(-1);
199+
gen.close();
200+
_verifyBytes(out.toByteArray(),
201+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT32_ELEMENTS),
202+
(byte) 0xFF,
203+
(byte) 0xFF,
204+
(byte) 0xFF,
205+
(byte) 0xFF);
206+
207+
// Min int
208+
out = new ByteArrayOutputStream();
209+
gen = cborGenerator(out);
210+
gen.writeNumberUnsigned(Integer.MIN_VALUE);
211+
gen.close();
212+
_verifyBytes(out.toByteArray(),
213+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT32_ELEMENTS),
214+
(byte) 0x80,
215+
(byte) 0x00,
216+
(byte) 0x00,
217+
(byte) 0x00);
218+
219+
// Truncated to 2 bytes
220+
out = new ByteArrayOutputStream();
221+
gen = cborGenerator(out);
222+
gen.writeNumberUnsigned(1000);
223+
gen.close();
224+
_verifyBytes(out.toByteArray(),
225+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT16_ELEMENTS),
226+
(byte) 0x03,
227+
(byte) 0xE8);
228+
229+
// Truncated to 1 byte
230+
out = new ByteArrayOutputStream();
231+
gen = cborGenerator(out);
232+
gen.writeNumberUnsigned(100);
233+
gen.close();
234+
_verifyBytes(out.toByteArray(),
235+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
236+
(byte) 0x64);
237+
238+
out = new ByteArrayOutputStream();
239+
gen = cborGenerator(out);
240+
gen.writeNumberUnsigned(25);
241+
gen.close();
242+
_verifyBytes(out.toByteArray(),
243+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
244+
(byte) 0x19);
245+
246+
out = new ByteArrayOutputStream();
247+
gen = cborGenerator(out);
248+
gen.writeNumberUnsigned(24);
249+
gen.close();
250+
_verifyBytes(out.toByteArray(),
251+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
252+
(byte) 0x18);
253+
254+
// Truncated to not take any extra bytes
255+
out = new ByteArrayOutputStream();
256+
gen = cborGenerator(out);
257+
gen.writeNumberUnsigned(23);
258+
gen.close();
259+
_verifyBytes(out.toByteArray(),
260+
(byte) 0x17);
261+
262+
out = new ByteArrayOutputStream();
263+
gen = cborGenerator(out);
264+
gen.writeNumberUnsigned(10);
265+
gen.close();
266+
_verifyBytes(out.toByteArray(),
267+
(byte) 0x0A);
268+
269+
out = new ByteArrayOutputStream();
270+
gen = cborGenerator(out);
271+
gen.writeNumberUnsigned(1);
272+
gen.close();
273+
_verifyBytes(out.toByteArray(),
274+
(byte) 0x01);
275+
276+
out = new ByteArrayOutputStream();
277+
gen = cborGenerator(out);
278+
gen.writeNumberUnsigned(0);
279+
gen.close();
280+
_verifyBytes(out.toByteArray(),
281+
(byte) 0x00);
282+
}
283+
192284
@Test
193285
public void testLongValues() throws Exception
194286
{
@@ -209,6 +301,119 @@ public void testLongValues() throws Exception
209301
assertEquals(0, b[3]);
210302
}
211303

304+
@Test
305+
public void testUnsignedLongValues() throws Exception
306+
{
307+
ByteArrayOutputStream out = new ByteArrayOutputStream();
308+
CBORGenerator gen = cborGenerator(out);
309+
310+
// uint64 max
311+
gen.writeNumberUnsigned(-1L);
312+
gen.close();
313+
_verifyBytes(out.toByteArray(),
314+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT64_ELEMENTS),
315+
(byte) 0xFF,
316+
(byte) 0xFF,
317+
(byte) 0xFF,
318+
(byte) 0xFF,
319+
(byte) 0xFF,
320+
(byte) 0xFF,
321+
(byte) 0xFF,
322+
(byte) 0xFF);
323+
324+
// Min long
325+
out = new ByteArrayOutputStream();
326+
gen = cborGenerator(out);
327+
gen.writeNumberUnsigned(Long.MIN_VALUE);
328+
gen.close();
329+
_verifyBytes(out.toByteArray(),
330+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT64_ELEMENTS),
331+
(byte) 0x80,
332+
(byte) 0x00,
333+
(byte) 0x00,
334+
(byte) 0x00,
335+
(byte) 0x00,
336+
(byte) 0x00,
337+
(byte) 0x00,
338+
(byte) 0x00);
339+
340+
// Truncated to 4 bytes
341+
out = new ByteArrayOutputStream();
342+
gen = cborGenerator(out);
343+
gen.writeNumberUnsigned(1000000L);
344+
gen.close();
345+
_verifyBytes(out.toByteArray(),
346+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT32_ELEMENTS),
347+
(byte) 0x00,
348+
(byte) 0x0F,
349+
(byte) 0x42,
350+
(byte) 0x40);
351+
352+
// Truncated to 2 bytes
353+
out = new ByteArrayOutputStream();
354+
gen = cborGenerator(out);
355+
gen.writeNumberUnsigned(1000L);
356+
gen.close();
357+
_verifyBytes(out.toByteArray(),
358+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT16_ELEMENTS),
359+
(byte) 0x03,
360+
(byte) 0xE8);
361+
362+
// Truncated to 1 byte
363+
out = new ByteArrayOutputStream();
364+
gen = cborGenerator(out);
365+
gen.writeNumberUnsigned(100L);
366+
gen.close();
367+
_verifyBytes(out.toByteArray(),
368+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
369+
(byte) 0x64);
370+
371+
out = new ByteArrayOutputStream();
372+
gen = cborGenerator(out);
373+
gen.writeNumberUnsigned(25L);
374+
gen.close();
375+
_verifyBytes(out.toByteArray(),
376+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
377+
(byte) 0x19);
378+
379+
out = new ByteArrayOutputStream();
380+
gen = cborGenerator(out);
381+
gen.writeNumberUnsigned(24L);
382+
gen.close();
383+
_verifyBytes(out.toByteArray(),
384+
(byte) (CBORConstants.PREFIX_TYPE_INT_POS + CBORConstants.SUFFIX_UINT8_ELEMENTS),
385+
(byte) 0x18);
386+
387+
// Truncated to not take any extra bytes
388+
out = new ByteArrayOutputStream();
389+
gen = cborGenerator(out);
390+
gen.writeNumberUnsigned(23L);
391+
gen.close();
392+
_verifyBytes(out.toByteArray(),
393+
(byte) 0x17);
394+
395+
out = new ByteArrayOutputStream();
396+
gen = cborGenerator(out);
397+
gen.writeNumberUnsigned(10L);
398+
gen.close();
399+
_verifyBytes(out.toByteArray(),
400+
(byte) 0x0A);
401+
402+
out = new ByteArrayOutputStream();
403+
gen = cborGenerator(out);
404+
gen.writeNumberUnsigned(1L);
405+
gen.close();
406+
_verifyBytes(out.toByteArray(),
407+
(byte) 0x01);
408+
409+
out = new ByteArrayOutputStream();
410+
gen = cborGenerator(out);
411+
gen.writeNumberUnsigned(0L);
412+
gen.close();
413+
_verifyBytes(out.toByteArray(),
414+
(byte) 0x00);
415+
}
416+
212417
@Test
213418
public void testFloatValues() throws Exception
214419
{

release-notes/CREDITS-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,7 @@ Fawzi Essam (@iifawzi)
408408
* Contributed implementation of #587: (cbor) Allow exposing CBOR Simple values as
409409
`JsonToken.VALUE_EMBEDDED_OBJECT` with a feature flag
410410
(2.20.0)
411+
412+
Oleg Koretsky (@Radiokot)
413+
* Contributed #603 (cbor) Add support for writing unsigned numbers to CBOR
414+
(2.20.0)

release-notes/VERSION-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ Active maintainers:
2525
#587: (cbor) Allow exposing CBOR Simple values as `JsonToken.VALUE_EMBEDDED_OBJECT`
2626
with a feature flag
2727
(implementation contributed by Fawzi E)
28+
#600: (avro) Make RecordVisitor _avroSchema and _fields properties final
29+
(contributed by Michal F)
30+
#603 (cbor) Add support for writing unsigned numbers to CBOR
31+
(contributed by Oleg K)
2832
- Fixes wrt [core#1438] (ParserBase.close() not resetting current token)
2933
- Generate SBOMs [JSTEP-14]
3034

0 commit comments

Comments
 (0)