@@ -45,9 +45,9 @@ public static <T> T decodeNullable(byte[] data, Function<byte[], T> decoder) {
4545 * @param data bytes
4646 * @return unsigned number
4747 */
48- public static CborNumber decodeUnsignedInteger (byte [] data ) {
48+ public static CborUnsignedLong decodeUnsignedInteger (byte [] data ) {
4949 CborReader reader = new CborReader (data );
50- CborNumber value = reader .readLength (CborMajorType .UNSIGNED_INTEGER );
50+ CborUnsignedLong value = reader .readLength (CborMajorType .UNSIGNED_INTEGER );
5151 reader .assertExhausted ();
5252
5353 return value ;
@@ -61,7 +61,7 @@ public static CborNumber decodeUnsignedInteger(byte[] data) {
6161 */
6262 public static byte [] decodeByteString (byte [] data ) {
6363 CborReader reader = new CborReader (data );
64- byte [] result = reader .read (reader .readLength (CborMajorType .BYTE_STRING ).asInt ());
64+ byte [] result = reader .read (reader .readLength (CborMajorType .BYTE_STRING ).asListSize ());
6565 reader .assertExhausted ();
6666
6767 return result ;
@@ -108,7 +108,7 @@ public static BigInteger decodeBigInteger(byte[] data, Integer maxByteLength) {
108108 */
109109 public static String decodeTextString (byte [] data ) {
110110 CborReader reader = new CborReader (data );
111- byte [] bytes = reader .read (reader .readLength (CborMajorType .TEXT_STRING ).asInt ());
111+ byte [] bytes = reader .read (reader .readLength (CborMajorType .TEXT_STRING ).asListSize ());
112112 reader .assertExhausted ();
113113
114114 return new String (bytes );
@@ -122,7 +122,7 @@ public static String decodeTextString(byte[] data) {
122122 */
123123 public static List <byte []> decodeArray (byte [] data ) {
124124 CborReader reader = new CborReader (data );
125- int length = reader .readLength (CborMajorType .ARRAY ).asInt ();
125+ int length = reader .readLength (CborMajorType .ARRAY ).asListSize ();
126126
127127 ArrayList <byte []> result = new ArrayList <>();
128128 for (int i = 0 ; i < length ; i ++) {
@@ -160,7 +160,7 @@ public static List<byte[]> decodeArray(byte[] data, long expectedLength) {
160160 */
161161 public static Set <CborMap .Entry > decodeMap (byte [] data ) {
162162 CborReader reader = new CborReader (data );
163- int length = reader .readLength (CborMajorType .MAP ).asInt ();
163+ int length = reader .readLength (CborMajorType .MAP ).asListSize ();
164164
165165 Set <Entry > result = new LinkedHashSet <>();
166166 Entry previous = null ;
@@ -258,7 +258,7 @@ public byte[] read(int length) {
258258 }
259259 }
260260
261- public CborNumber readLength (CborMajorType majorType ) {
261+ public CborUnsignedLong readLength (CborMajorType majorType ) {
262262 byte initialByte = this .readByte ();
263263
264264 CborMajorType parsedMajorType = CborMajorType .fromType (
@@ -271,7 +271,7 @@ public CborNumber readLength(CborMajorType majorType) {
271271 byte additionalInformation = (byte ) (initialByte
272272 & CborDeserializer .ADDITIONAL_INFORMATION_MASK );
273273 if (Byte .compareUnsigned (additionalInformation , (byte ) 24 ) < 0 ) {
274- return new CborNumber (additionalInformation );
274+ return new CborUnsignedLong (additionalInformation );
275275 }
276276
277277 switch (majorType ) {
@@ -307,7 +307,7 @@ public CborNumber readLength(CborMajorType majorType) {
307307 length , Long .toUnsignedString (t )));
308308 }
309309
310- return new CborNumber (t );
310+ return new CborUnsignedLong (t );
311311 }
312312
313313 public byte [] readRawCbor () {
@@ -323,19 +323,19 @@ public byte[] readRawCbor() {
323323
324324 CborMajorType majorType = CborMajorType .fromType (
325325 this .data [this .position ] & CborDeserializer .MAJOR_TYPE_MASK );
326- CborNumber length = this .readLength (majorType );
326+ CborUnsignedLong length = this .readLength (majorType );
327327 switch (majorType ) {
328328 case BYTE_STRING :
329329 case TEXT_STRING :
330- this .read (length .asInt ());
330+ this .read (length .asListSize ());
331331 break ;
332332 case ARRAY :
333333 // asInt bounds each count and every header consumes input, so the counter cannot
334334 // overflow; undersupplied counts fail with premature end of data as items are read.
335- remaining += length .asInt ();
335+ remaining += length .asListSize ();
336336 break ;
337337 case MAP :
338- remaining += length .asInt () * 2L ;
338+ remaining += length .asListSize () * 2L ;
339339 break ;
340340 case TAG :
341341 remaining += 1 ;
@@ -384,59 +384,82 @@ public byte[] getData() {
384384 /**
385385 * CBOR number implementation.
386386 */
387- public static class CborNumber {
387+ public static class CborUnsignedLong {
388388
389389 private final long value ;
390390
391- private CborNumber (long value ) {
391+ private CborUnsignedLong (long value ) {
392392 this .value = value ;
393393 }
394394
395395 /**
396- * Get number as long.
396+ * Get the raw unsigned value as a {@code long}. Values at or above {@code 2^63} are returned
397+ * as a negative long with the same bit pattern; use {@link Long#compareUnsigned} to compare
398+ * them.
397399 *
398- * @return number
400+ * @return value
399401 */
400402 public long asLong () {
401403 return this .value ;
402404 }
403405
404406 /**
405- * Get number as int, throw error if does not fit.
407+ * Get the value as an unsigned 32-bit integer, throwing if it exceeds {@code 0xFFFFFFFF}.
408+ * Values above {@link Integer#MAX_VALUE} are returned with the same bit pattern (a negative
409+ * {@code int}); mask with {@code & 0xFFFFFFFFL} to recover the unsigned value.
406410 *
407- * @return number
411+ * @return value
408412 */
409413 public int asInt () {
410- if (Long .compareUnsigned (this .value , Integer . MAX_VALUE ) > 0 ) {
414+ if (Long .compareUnsigned (this .value , 0xFFFFFFFFL ) > 0 ) {
411415 throw new CborSerializationException ("Value too large" );
412416 }
413417 return (int ) this .value ;
414418 }
415419
416420 /**
417- * Get number as byte, throw error if does not fit.
421+ * Get the value as an unsigned 16-bit integer, throwing if it exceeds {@code 0xFFFF}. Values
422+ * above {@link Short#MAX_VALUE} are returned with the same bit pattern (a negative
423+ * {@code short}); mask with {@code & 0xFFFF} to recover the unsigned value.
418424 *
419- * @return number
425+ * @return value
426+ */
427+ public short asShort () {
428+ if (Long .compareUnsigned (this .value , 0xFFFFL ) > 0 ) {
429+ throw new CborSerializationException ("Value too large" );
430+ }
431+
432+ return (short ) this .value ;
433+ }
434+
435+ /**
436+ * Get the value as an unsigned 8-bit integer, throwing if it exceeds {@code 0xFF}. Values
437+ * above {@link Byte#MAX_VALUE} are returned with the same bit pattern (a negative
438+ * {@code byte}); mask with {@code & 0xFF} to recover the unsigned value.
439+ *
440+ * @return value
420441 */
421442 public byte asByte () {
422- if (Long .compareUnsigned (this .value , Byte . MAX_VALUE ) > 0 ) {
443+ if (Long .compareUnsigned (this .value , 0xFFL ) > 0 ) {
423444 throw new CborSerializationException ("Value too large" );
424445 }
425446
426447 return (byte ) this .value ;
427448 }
428449
429450 /**
430- * Get number as short, throw error if does not fit.
451+ * Get the value as a non-negative {@code int} bounded to {@link Integer#MAX_VALUE}, suitable
452+ * for a collection size, byte-string length or index. Throws if the value would not fit in a
453+ * valid Java array size.
431454 *
432- * @return number
455+ * @return value
433456 */
434- public short asShort () {
435- if (Long .compareUnsigned (this .value , Short .MAX_VALUE ) > 0 ) {
457+ public int asListSize () {
458+ if (Long .compareUnsigned (this .value , Integer .MAX_VALUE ) > 0 ) {
436459 throw new CborSerializationException ("Value too large" );
437460 }
438461
439- return (short ) this .value ;
462+ return (int ) this .value ;
440463 }
441464 }
442465}
0 commit comments